java - 如何刷新包含 BufferedImage 的 JFrame?

标签 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

最佳答案

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

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

此版本与先前版本之间解决的问题的简要摘要:

  1. 您不希望 contentPane 成为 JLabel,因为它会使以后添加其他控件变得更加困难,并且没有布局管理器。我在两者之间添加了一个 JPanel ,并给它 BorderLayout .
  2. 调用者应对线程安全负责。我本来没有这样做,因为你没有提供任何调用代码,但在这里,我做了事件调度线程委托(delegate)。确保使用 EventQueue.invokeLater 切换到事件调度线程,就像我在调用 setBackgroundImage() 之前在 main 中所做的那样。
  3. 我在 JLabel 上使用 setSizesetPreferredSize ,以便布局管理器可以正确地为控件选择合适的尺寸,从而 frame.pack按预期工作。
  4. 我在构造函数外部的 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);
      }
    });
  }
}

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

Nonogram in a JFrame

关于java - 如何刷新包含 BufferedImage 的 JFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32259923/

相关文章:

java - DataOutputStream 卡住

java - 空白的最终字段可能尚未初始化

java - 褪色 sample

java - 创建独立的 Java 应用程序

java - 为什么要使用 App Engine 来完成如此简单的任务?

Java多线程数据库访问

Java,结束 JFrame

swing - 在java swing中创建一个透明的JFrame

java - 更改 ContentPane 的背景颜色

Java JFrame - 按键似乎没有注册