您好,我已经用谷歌搜索了,但无法弄清楚为什么我的 paintComp 方法没有被调用
我有以下代码 包 com.vf.zepto.view;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.vf.zepto.view.interfaces.ProcessorPanel;
public class CountryDetailsPanel extends JPanel implements ProcessorPanel, Runnable {
private GridBagConstraints c = new GridBagConstraints();
private String countryName;
private Properties prop = new Properties();
private BufferedImage image;
public CountryDetailsPanel() {
try {
prop.load(new FileInputStream("country.props"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//this.setLayout(new GridBagLayout());
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(5, 5, 5, 5);
this.setPreferredSize(new Dimension(200, 200));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
try {
if(countryName != null) {
String asset = prop.getProperty(countryName+".flag");
if(!asset.equals(null)) {
image = ImageIO.read(new File(asset));
g.drawImage(image, 0, 0, null);
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void updateDetails(Object o) {
countryName = (String)o;
SwingUtilities.invokeLater(this);
}
@Override
public void run() {
this.repaint();
}
}
并且在调用 this.repaint()
时期望调用 paintComponent
方法,但是为了爱情和金钱,它不是。
曾试图强制它使用 EDT,以防这是问题所在,但事实并非如此。
有什么想法吗?
最佳答案
永远不要调用
/li>paintComponent()
repaint()
方法合并所有更改组件的请求(屏幕刷新之间可能有多个重绘请求) .它将更新请求添加到 GUI 事件队列,以便更新将与其他 GUI 操作正确协调(Swing 和 AWT 不是线程安全的)。此更新请求在处理后调用update()
,后者调用paint()
,后者调用您的paintComponent()
为什么会有这个:
@Override public void run() { this.repaint(); }
它似乎没有任何用处(创建一个新线程来重绘一次?更不用说线程不在 EDT 而是在 JPanel
上调用 repaint()
实例(如果在外部进行了修改,您甚至不必担心)。但是,要启动修改 UI 组件的线程,请使用 SwingTimer
/SwingWorker
或 SwingUtilities#invokeXXX( )
这可能不相关,但在您的代码中我看到了这一点:
if(!asset.equals(null)) { image = ImageIO.read(new File(asset)); g.drawImage(image, 0, 0, null); }
不要使用 equals()
与 null
值进行比较,因为这可能会抛出 NullPointerException
,因为您正试图
引用一个空指针,例如这段代码抛出一个 NPE
:
String s=null;
if(!s.equals(null)) {//throws NPE
System.out.println("Here");//is never printed
}
- 另外,正如 mKorbel 所说(给他+1)不要在
paintComponent()
中执行长时间运行的任务 全局声明您的Image
,在构造函数中分配它,然后使用它在paintComponent()
中。 F.i
宁愿做:
public class TestPanel extends JPanel {
private Image image;
public TestPanel() {
image = ImageIO.read(new File(asset));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(asset!=null) {
g.drawImage(image, 0, 0, null);
}
}
}
关于java - 重绘未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12692171/