如何在其中刷新带有BufferedImage的JFrame?

时间:2015-08-27 21:41:14

标签: java swing jframe bufferedimage

除了我的问题How can I more quickly render my array?之外,我还创建了以下课程来制作JFrame

package myprojects;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

class BackgroundImageJFrame extends JFrame {
    public BackgroundImageJFrame(BufferedImage img) {
        setTitle("Background Color for JFrame");
        int h = img.getHeight();
        int w = img.getWidth();
        setSize(w, h);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

        setLayout(new BorderLayout());
        setContentPane(new JLabel(new ImageIcon(img)));
        setLayout(new FlowLayout());
        // Just for refresh :) Not optional!
        setSize(w-1, h-1);
        setSize(w, h);
    }
}

我用new BackgroundImageJFrame(img);打电话。由于我想要刷新此JFrame的内容,因此这不会最佳地发挥作用,因为每次都会创建一个新的JFrame

我怎样才能改变这一点,让JFrame刷新?

1 个答案:

答案 0 :(得分:2)

您可以通过存储JLabel控件,然后使用方法设置图像来完成此操作。确保在Event Dispatch Thread上设置图像!

我已根据@ MadProgrammer的优秀评论修改了代码以更稳定的方式执行此操作。

此版本与之前版本之间解决的问题的简要概述:

  1. 您不希望contentPane成为JLabel,因为这会使以后添加其他控件变得更加困难,并且没有布局管理器。我在其间添加了JPanel,并给它BorderLayout
  2. 来电者应负责线程安全。我最初没有这样做,因为你没有提供任何调用代码,但在这里,我做了事件调度线程委托。确保在调用EventQueue.invokeLater之前使用setBackgroundImage()切换到事件调度线程,就像我在此处所做的那样。
  3. 我在JLabel上使用setSizesetPreferredSize,以便布局管理员可以为控件正确选择合适的大小,以便frame.pack按预期工作。
  4. 我在构造函数之外的initComponents方法中创建控件,以使代码更容易理解,并在必要时更容易添加更多构造函数。
  5. 以下是代码:

    public class NonogramSolutionJFrame extends JFrame {
      private final JLabel label;
      private final JPanel panel;
    
      public NonogramSolutionJFrame(BufferedImage img) {
        panel = new JPanel();
        label = new JLabel();
        initComponents(img);
      }
    
      private final void initComponents(BufferedImage img) {
        setTitle("Background Color for JFrame");
        setBackgroundImage(img);
        setContentPane(panel);
        panel.setLayout(new BorderLayout());
        panel.add(label, BorderLayout.CENTER);
        setLocationRelativeTo(null);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
      }
    
      public void setBackgroundImage(final BufferedImage img) {
        label.setIcon(new ImageIcon(img));
        label.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
      }
    
      public static void main(String... args) throws Exception {
        BufferedImage img = ImageIO.read(NonogramSolutionJFrame.class.getResource("/nonogram.png"));
        NonogramSolutionJFrame frame = new NonogramSolutionJFrame(img);
        EventQueue.invokeLater(new Runnable() {
          @Override
          public void run() {
            frame.setVisible(true);
          }
        });
      }
    }
    

    使用other answer中的图像,此代码生成以下内容(在Linux上):

    Nonogram in a JFrame