nau*_*svn 17 java user-interface swing paintcomponent
我将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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想"刷新"JPanel,那么你应该调用repaint(),它将调用你的paintComponent().这应该可以解决您的问题:
public void setImage(BufferedImage bi)
{
image = bi;
EventQueue.invokeLater(new Runnable()
{
public void run()
{
repaint();
}
});
}
Run Code Online (Sandbox Code Playgroud)
使用EDT更新和更改GUI的良好做法.如果您有兴趣,请提供有关EDT的更多信息:
repaint
不需要从EDT调用.如果您正在更改GUI,例如将文本设置为JLabel,则它应该位于EDT内部.关于在EDT之外可以称之为什么的更多信息(由nIcE cOw提供):
在EDT之外安全使用Component.repaint()?
看看该文档的JPanel.add()
,它继承自java.awt.Container
:
将指定的组件追加到此容器的末尾.这是addImpl(java.awt.Component,java.lang.Object,int)的便捷方法.此方法更改与布局相关的信息,因此使组件层次结构无效.如果已显示容器,则必须在此后验证层次结构以显示添加的组件.
强调补充说.
因此,如果在已经显示Container 之后修改它,则必须调用validate()
它才能显示它.只是调用repaint()
是不够的.您可能已经注意到呼叫setVisible(true)
也有效; 这是因为它在validate()
内部调用.