除了我的问题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 的优秀评论修改了代码,以更稳定的方式执行此操作。
此版本与先前版本之间解决的问题的简要摘要:
- 您不希望
contentPane
成为JLabel
,因为它会使以后添加其他控件变得更加困难,并且没有布局管理器。我在两者之间添加了一个JPanel
,并给它BorderLayout
. - 调用者应对线程安全负责。我本来没有这样做,因为你没有提供任何调用代码,但在这里,我做了事件调度线程委托(delegate)。确保使用
EventQueue.invokeLater
切换到事件调度线程,就像我在调用setBackgroundImage()
之前在 main 中所做的那样。 - 我在 JLabel 上使用
setSize
和setPreferredSize
,以便布局管理器可以正确地为控件选择合适的尺寸,从而frame.pack
按预期工作。 - 我在构造函数外部的
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 上):
关于java - 如何刷新包含 BufferedImage 的 JFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32259923/