Я использую следующий код, чтобы добавить изображение в JPanel внутри JScrollPane. Я хочу, чтобы панель прокрутки прокручивалась донизу, но, похоже, она не распознает, что изображение было добавлено до некоторого времени позже, хотя я вызываю это внутри оболочки SwingUtilities.JPanel высота не обновляется сразу
private void addImage(final String image){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
imagePanel.addImage(image);
final JScrollBar vScroll = imageScrollPane.getVerticalScrollBar();
vScroll.setValue(vScroll.getMaximum());
}
});
}
Код addImage из imagePanel выглядит следующим образом:
public void addImage(String image){
System.out.println("Pre-height: " + getHeight());
add(createImageLabel(image));
System.out.println("After-height: " + getHeight());
revalidate();
System.out.println("Revalidate-height: " + getHeight());
}
Похоже, что это приводит к следующему, например:
Pre-height: 690
After-height: 690
Revalidate-height: 690
Если я сплю в цикле после того, как звоните, для высоты, по-видимому, требуется около 200 мс.
Код, который у меня здесь, всегда имеет 1 изображение сзади при прокрутке. Каков наилучший способ прокрутки на дно таким образом, что я действительно знаю, где находится дно? Я немного знаком с соглашениями Swing, но я думал, что, поскольку все происходит в вызове SwingUtilities, он будет знать, что он делает.
Полный Исполняемые Пример кода, который демонстрирует проблему:
package com.foo.bar
import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class ScrollImageExampleFrame extends JFrame{
private ScrollImageExamplePanel siePanel;
public ScrollImageExampleFrame(){
setSize(1024, 768);
siePanel = new ScrollImageExamplePanel();
getContentPane().add(siePanel);
}
class ScrollImageExamplePanel extends JPanel {
ImageViewExamplePanel imagePanel = new ImageViewExamplePanel();
JScrollPane imageScrollPane = new JScrollPane(imagePanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public ScrollImageExamplePanel(){
setLayout(new MigLayout("nogrid"));
imageScrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(30, 0));
add(imageScrollPane, "east, width 300!, height 100%");
}
private void addImageOuter(final String image){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
imagePanel.addImageInner(image);
imagePanel.revalidate();
final JScrollBar vScroll = imageScrollPane.getVerticalScrollBar();
vScroll.setValue(vScroll.getMaximum());
}
});
}
}
class ImageViewExamplePanel extends JPanel {
public ImageViewExamplePanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
}
public void addImageInner(String image){
URL imageUrl = ImageViewExamplePanel.class.getResource("/com/foo/bar/" + image);
ImageIcon ii = resizeImage(imageUrl, 360, 270);
JLabel label = new JLabel();
label.setIcon(ii);
add(label);
revalidate();
}
private ImageIcon resizeImage(URL url, int x, int y){
Image image = null;
try{
image = ImageIO.read(url);
Image newImage = image.getScaledInstance(x, y, Image.SCALE_SMOOTH);
return new ImageIcon(newImage);
} catch (IOException ioe){
ioe.printStackTrace();
return null;
}
}
}
public static void main(String[] args) throws InterruptedException {
ScrollImageExampleFrame frame = new ScrollImageExampleFrame();
frame.setVisible(true);
frame.siePanel.addImageOuter("foo.png");
Thread.sleep(1000);
frame.siePanel.addImageOuter("foo.png");
Thread.sleep(1000);
frame.siePanel.addImageOuter("foo.png");
Thread.sleep(1000);
frame.siePanel.addImageOuter("foo.png");
}
}
для лучшей помощи скорее опубликовать SSCCE, как демонстрация вы можете поставить там пустые JPanel – mKorbel
тьфу. МОЙ SSCCE работает так, как я ожидал. Я не хочу вставлять весь проект здесь, но я не могу определить, почему мой проект видит задержку между добавлением изображения и обновлением высоты. Все еще пытается создать SSCCE. –
Почему вы создаете новый JLabel. Просто используйте 'label.setIcon (новый ImageIcon());'. Избегайте добавления/удаления компонентов в видимом графическом интерфейсе, когда существует более простая альтернатива. – camickr