无法在Jframe /标签内重新绘制

时间:2013-02-12 03:10:58

标签: java swing jframe jlabel event-dispatch-thread

基本上,有两种不同的BufferedImage叫做img_w和img_b1 ...... 一旦我将Jframe / label设置为其中一个,它就永远不会改变或永远不会将()重新设置为新的Imagebuffered值......

提前致谢..

BufferedImage img_w = new BufferedImage(old_width_i, old_height_i, BufferedImage.TYPE_INT_RGB);
BufferedImage img_b1 = new BufferedImage(old_width_i, old_height_i, BufferedImage.TYPE_INT_RGB);

// add data into the img_w and img_b1

JFrame frame=new JFrame();
JLabel label = new JLabel(new ImageIcon(img_w));
frame.getContentPane().add(label, BorderLayout.WEST);
frame.pack();
frame.setVisible(true); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

//I am trying to sleep only cause I want to make out if the image is changing or not or basically , to have a rotating illusion...

System.out.println("Hello");
frame.getContentPane().add(new JLabel(new ImageIcon(img_w)), BorderLayout.WEST);
frame.repaint();


label = new JLabel(new ImageIcon(img_b1));
frame.getContentPane().add(label,BorderLayout.WEST); //display the image (works)
label.repaint(); //update the display??
frame.repaint();
frame.getContentPane().repaint();

2 个答案:

答案 0 :(得分:3)

此...

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

将阻止UI处理绘制请求,直到结束。你永远不应该阻止EDT。

以下示例(很简单)并演示了一种手动在图片之间移动的简单方法。

public class FlipPictures {

    public static void main(String[] args) {
        new FlipPictures();
    }

    public FlipPictures() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PicturePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });
    }

    public class PicturePane extends JPanel {

        private JLabel picture;
        private File[] pictures;
        private int currentPicture = -1;

        public PicturePane() {

            pictures = new File("/point/me/to/a/directory/of/images").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    String name = pathname.getName().toLowerCase();
                    return name.endsWith(".png") 
                            || name.endsWith(".gif") 
                            || name.endsWith(".jpg")
                            || name.endsWith(".jpeg")
                            || name.endsWith(".bmp");
                }
            });

            setLayout(new BorderLayout());
            picture = new JLabel();
            picture.setHorizontalAlignment(JLabel.CENTER);
            picture.setVerticalAlignment(JLabel.CENTER);
            add(picture);

            JButton change = new JButton("Change");
            add(change, BorderLayout.SOUTH);

            change.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    changePicture();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        protected void changePicture() {

            if (pictures != null && pictures.length > 0) {

                currentPicture++;
                if (currentPicture >= pictures.length) {
                    currentPicture = 0;
                }

                try {
                    // This is a potentionally blocking process and really should be threaded...
                    picture.setIcon(new ImageIcon(ImageIO.read(pictures[currentPicture])));
                    picture.setText(null);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    picture.setText(ex.getMessage());
                }

            } else {

                picture.setText("No Pictures :(");

            }

        }

    }

}

<强>更新

或者如果您更喜欢在图像之间自动切换

public class FlipPictures {

    public static void main(String[] args) {
        new FlipPictures();
    }

    public FlipPictures() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PicturePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });
    }

    public class PicturePane extends JPanel {

        private JLabel picture;

        public PicturePane() {
            setLayout(new BorderLayout());
            picture = new JLabel();
            picture.setHorizontalAlignment(JLabel.CENTER);
            picture.setVerticalAlignment(JLabel.CENTER);
            add(picture);

            BackgroundSwitcher switcher = new BackgroundSwitcher(this);
            switcher.execute();

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        public void setPicture(BufferedImage image) {

            picture.setIcon(new ImageIcon(image));

        }

    }

    public class BackgroundSwitcher extends SwingWorker<Void, BufferedImage> {

        private File[] pictures;
        private int currentPicture = -1;
        private PicturePane picturePane;

        public BackgroundSwitcher(PicturePane picturePane) {
            pictures = new File("/point/me/to/a/directory/of/images").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    String name = pathname.getName().toLowerCase();
                    return name.endsWith(".png")
                            || name.endsWith(".gif")
                            || name.endsWith(".jpg")
                            || name.endsWith(".jpeg")
                            || name.endsWith(".bmp");
                }
            });
            this.picturePane = picturePane;
        }

        @Override
        protected void process(List<BufferedImage> chunks) {
            picturePane.setPicture(chunks.get(chunks.size() - 1));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (pictures != null && pictures.length > 0) {
                while (true) {

                    currentPicture++;
                    if (currentPicture >= pictures.length) {
                        currentPicture = 0;
                    }

                    try {
                        publish(ImageIO.read(pictures[currentPicture]));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    Thread.sleep(1000);
                }
            }
            return null;
        }
    }
}

您可能想看一下Concurrency in Swing

答案 1 :(得分:2)

您的代码不完整所以我们所能做的就是猜测。下次发布SSCCE

我猜测问题是您正在向可见帧添加组件。您没有在面板上调用revalidate(),因此标签的大小保持为(0,0)。

但是,没有必要创建新的JLabel。只需通过调用现有标签的setIcon()方法来更改图像,标签将自行重新绘制。无需在框架或任何其他组件上调用repaint()。