Java 如何刷新包含BuffereImage的JFrame?
除了我的问题之外,我还上了以下课程来制作一个Java 如何刷新包含BuffereImage的JFrame?,java,swing,jframe,bufferedimage,Java,Swing,Jframe,Bufferedimage,除了我的问题之外,我还上了以下课程来制作一个JFrame: package myprojects; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; class BackgroundImageJFrame extends JFrame { public BackgroundImageJFrame(BufferedImage img) { setTitle("Bac
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);
}
}
我用newbackgroundimagejframe(img)调用它代码>。因为我想刷新这个JFrame
的内容,所以这并不能达到最佳效果,因为每次都会创建一个新的JFrame
我怎样才能改变它,让JFrame
刷新?您只需存储JLabel
控件,然后用一种方法设置图像,就可以完成这项工作。请确保您将图像设置在屏幕上
基于@MadProgrammer的优秀评论,我修改了代码,以更稳定的方式完成这项工作
本版本与上一版本之间解决问题的简要总结:
您不希望contentPane
成为JLabel
,因为它使以后添加其他控件更加困难,并且没有布局管理器。我在中间添加了一个JPanel
,并给出了它
调用方应负责线程安全。我最初没有这样做,因为您没有提供任何调用代码,但在这里,我执行事件分派线程委派。在调用setBackgroundImage()
之前,请确保使用EventQueue.invokeLater
切换到事件调度线程,就像我在main中所做的那样
我正在JLabel上使用setSize
和setPreferredSize
,这样布局管理器就可以正确地为控件选择合适的大小,并按预期工作
我在构造函数之外的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上):
请注意,使用JLabel
作为“背景”图像有两个主要问题,1-默认情况下没有布局管理器,因此您需要进行设置;2-在确定标签的首选大小时,JLabel
不会考虑其内容,这可能会导致问题。IMHO-确保线程安全不是BackgroundImageJFrame
的责任,而是调用者的责任,否则您只是在向系统中添加可能的低效率(以及可能的竞争条件),可能会看到一个更新以您不设计的顺序发生-但这就是我;)我不反对你不修改OPs代码,但应该让他们知道他们的方法可能存在的任何缺陷,这样他们就不会陷入更深的问题,只是说;)嘿,我编辑了答案,我想让你看到它。程序员在评论中提出了一些好的观点。