如何刷新其中包含 BufferedImage 的 JFrame?

How can I refresh a JFrame with BufferedImage in it?

除了我的问题,我做了以下class做一个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

您可以非常简单地通过存储 JLabel 控件,然后使用方法设置图像来完成此操作。确保将图像设置为 Event Dispatch Thread!

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

此版本与上一版本之间解决的问题的简要总结:

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

代码如下:

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);
      }
    });
  }
}

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