3

我有一个 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........
            }
        }
    }

}
4

4 回答 4

2

首先,您不应该在方法中启动线程,paintComponent()因为. 可能会发生新线程启动而以前的线程没有终止的情况。paintComponent()repaint()

其次,如果要正常绘制菜单,请尝试super.paintComponent(g)在开头添加paintComponent().

第三,Graphics g = getGraphics();为什么不直接使用graphics?由于 Graphics 对象正在发生变化,因此您不能假设下一次绘画是在同一个旧 Graphics 对象中进行的。

于 2013-03-07T17:43:02.967 回答
2

除了关于事件调度线程的内容之外:

  • 你是直接调用paintComponent() 方法吗?调用 repaint() 更“安全”。
  • 是否可以在调用 paintComponent() 时缓冲图像、绘制图像然后在面板上进行设置?
于 2013-03-07T17:33:37.963 回答
1
  • 不要使用线程会阻​​塞 EDT,不是所有的事件都可以在屏幕上看到,在某些情况下只有第一个。最后,使用 Swing Timer 代替

  • 不要在 paintComponent 中创建任何 Object、FileIO、Thread 等,也不要在 try-catch-finally 块中创建 unsafe

  • 之前创建任何对象,将其放入数组和内部paintComponent以在最终对象数组中循环

  • 发布一个SSCCE,简短,可运行,可编译,只是关于绘画,所有对象都应该存储为局部变量(实际上,任何关于二次淡入和缩小问题的答案)

于 2013-03-08T11:17:15.003 回答
0

我不会在paintComponent 方法中运行线程。我会在paint方法之外使用线程。

于 2013-03-07T17:25:33.937 回答