我有一个JPanel,在其上执行自定义绘画,可能需要15秒。
问题是当我在绘制JPanel的同时点击菜单时,绘画正在菜单上完成,并且选项不可见。 (见图中扭曲的文字)
如果我在绘画完成后单击菜单,则没有不需要的行为,但是当我将鼠标指针移动到不同的菜单上时,同样的事情再次发生。 例如,在完成绘画后,如果单击“应用程序”,则不会出现副作用,但是当我将鼠标指针移动到“帮助”时,会显示前面描述的行为。 如何避免这种情况?
我在paintComponent()方法之外的一个单独的线程中执行绘画:
public class RandomIFSPanel extends JPanel {
RandomIFSPanelRenderer randomIFSPanelRenderer;
@Override
public void paintComponent(Graphics graphics) {
try {
randomIFSPanelRenderer.stop();
} catch (Exception e) {
}
randomIFSPanelRenderer = new RandomIFSPanelRenderer();
randomIFSPanelRenderer.start();
}
class RandomIFSPanelRenderer extends Thread {
@Override
public void run() {
for (int i = 0; i < numberOfPoints; i++) {
Graphics g=getGraphics();
g.setColor(Color.WHITE);
g.drawLine........
}
}
}
}
答案 0 :(得分:2)
除了有关Event Dispatch Thread的内容之外:
答案 1 :(得分:2)
首先,您不应该在paintComponent()
方法中启动一个帖子,因为paintComponent()
可以多次调用repaint()
。可能会发生新线程启动而前一个线程没有被终止。
其次,如果您希望正常绘制菜单,请尝试在super.paintComponent(g)
的开头添加paintComponent()
。
第三,Graphics g = getGraphics();
为什么不只使用graphics
?由于Graphics对象正在改变,你不能假设下一个绘画在同一个旧的Graphics对象中进行。
答案 2 :(得分:1)
不要使用Thread会阻止EDT,而不是所有事件都可以在屏幕上看到,在某些情况下只有第1个。最后,使用Swing Timer代替
不要在paintComponent中创建任何Object,FileIO,Thread等,也不要在不安全的内部尝试 - catch - finally块
之前创建任何对象,将其放入数组并在paintComponent内部循环到最终对象的数组
发布SSCCE,简短,可运行,可编辑,只是绘画,所有对象都应该存储为局部变量(对于实际,任何关于二次衰落和缩小的问题的答案)
答案 3 :(得分:0)
我不会在paintComponent方法中运行一个线程。我会在paint方法之外使用该线程。