[英]JPanel doesn't update until resize Jframe
我子类化JPanel以覆盖paintComponent(Graphics),我想在jframe中将图像绘制到jpanel上。
但是直到我更改了jframe的大小,我的图像才出现。 这是我的代码:
public class ImagePanel extends JPanel{
public void setImage(BufferedImage bi)
{
image = bi;
revalidate();
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(image != null)
{
g.drawImage(image, 0, 0, this);
}
}
}
如果要“刷新” JPanel,则应调用repaint(),后者将调用paintComponent()。 这应该可以解决您的问题:
public void setImage(BufferedImage bi)
{
image = bi;
EventQueue.invokeLater(new Runnable()
{
public void run()
{
repaint();
}
});
}
使用EDT更新和更改GUI的良好做法。 如果您有兴趣,这里是EDT的更多信息:
不需要从EDT调用repaint
。 如果要更改GUI,例如将文本设置为JLabel,则它应位于EDT内。 以下是有关在EDT之外可以调用的内容的更多信息(由nIcE cOw提供):
看一下JPanel.add()
的文档 ,它是从java.awt.Container
继承的:
将指定的组件追加到此容器的末尾。 这是addImpl(java.awt.Component,java.lang.Object,int)的便捷方法。 此方法更改与布局有关的信息,因此使组件层次结构无效。 如果已经显示了容器,则此后必须验证层次结构才能显示添加的组件。
重点已添加。
因此,如果在显示容器后对其进行修改,则必须调用validate()
使其显示。 仅调用repaint()
是不够的。 您可能已经注意到,调用setVisible(true)
也可以; 这是因为它在内部调用validate()
。
我有同样的问题,可以通过调用setVisible(true)来解决。 我正在使用的JFrame。
示例:如果您的JFrame在使用后没有更新:
jframe.setContentPane(new MyContentPane());
修复:
jframe.setContentPane(new MyContentPane());
jframe.setVisible(true);
我知道即使您的JFrame已经可见,执行此操作听起来也很愚蠢,但这是我到目前为止找到的解决此问题的唯一方法(上面提出的解决方案对我不起作用)。
这是一个完整的例子。 运行它,然后取消注释“ f.setVisible(true);” 类Panel1和Panel2中的说明,您将看到区别。 不要忘记导入(对于自动导入,请按Ctrl + Shift + O)。
主类:
public class Main {
private static JFrame f;
public static void main(String[] args) {
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new Panel1(f));
f.pack();
f.setVisible(true);
}
}
Panel1类:
public class Panel1 extends JPanel{
private JFrame f;
public Panel1(JFrame frame) {
f = frame;
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
JButton b = new JButton("Panel 1");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.setContentPane(new Panel2(f));
// Uncomment the instruction below to fix GUI "update-on-resize-only" problem
//f.setVisible(true);
}
});
add(b);
}
}
Panel2类:
public class Panel2 extends JPanel{
private JFrame f;
public Panel2(JFrame frame) {
f = frame;
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
JButton b = new JButton("Panel 2");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.setContentPane(new Panel1(f));
// Uncomment the instruction below to fix GUI "update-on-resize-only" problem
//f.setVisible(true);
}
});
add(b);
}
}
希望能有所帮助。
问候。
我也有同样的问题,但我找到了解决方案。 只需在顶部创建一个jframe
对象,然后在底部调用jframe
方法,例如jf.pack()
, jf.setVisible()
, jf.setSize()
, jf.setDefaultCloseOpetion()
应该位于添加的所有UI的底部框架,您会发现它很棒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.