Java Swing重绘延迟

时间:2019-07-19 01:34:59

标签: java swing repaint

我有一个简单的绘画程序:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class CanvasPanel extends JFrame implements MouseMotionListener
{
    private int x1, y1, x2, y2;
    public CanvasPanel()
    {
        addMouseMotionListener(this);
        setBounds(50,50,400,250);
        setVisible(true);
    }

    public static void main(String[] argv)
    {
        new CanvasPanel();
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public void paint(Graphics g)
    {
        g.setColor(Color.black);
        g.drawLine(x1, y1, x2, y2);
    }

    public void mouseDragged(MouseEvent mouseEvent)
    {
        mouseEvent.consume();
        int x = mouseEvent.getX();
        int y = mouseEvent.getY();

        if ( x1 == 0 )
        {
            x1 = x;
        }

        if ( y1 == 0 )
        {
            y1 = y;
        }

        x2 = x;
        y2 = y;
        repaint();
        x1 = x2;
        y1 = y2;
    }

    public void mouseMoved(MouseEvent me)
    {

    }
}

如果运行它,您将看到用鼠标绘画时有一个滞后,并且绘制得越快,分解成的点就越少。我该如何解决?我在想,如果重新绘制速度非常快,那么点应该形成直线和曲线。

1 个答案:

答案 0 :(得分:2)

绘画时需要学习很多东西。我已经做了大量的图形工作,所以我修改了程序以进行说明。

  1. 除非您打算覆盖某些内容,否则请勿扩展JFrame。几乎没有必要。
  2. 在覆盖JPanel的{​​{1}}中进行绘画。
  3. paintComponent()array中收集您的点,以便每次都遍历它们。这是因为调用list会清除屏幕(但有必要这样做)。
  4. 不是必需的,但我发现在私有类中使用super.paintComponent()(或任何* -Adapter)可以方便地处理事件。
  5. 由于Swing不是线程安全的,因此最好在EDT中启动它。只需确保在MouseAdapter中不做任何长时间的处理,否则您的程序将锁定并失去响应。
EDT

此示例仍然有问题。例如,如果释放鼠标按钮并将其定位到新位置,然后单击,它将从最后一点继续。可能有很多方法可以解决此问题,但是最简单的方法是拥有一个列表列表,其中每个列表都是一组单独的具有分离原点的点。