【问题标题】:Lag when drawing something to move with mouse用鼠标绘制要移动的东西时出现延迟
【发布时间】:2010-12-30 17:12:13
【问题描述】:

我在鼠标位置绘制矩形时遇到了一些问题。移动鼠标时,绘制的矩形滞后于鼠标光标。有没有办法确保矩形在鼠标上准确移动并且不落后?

这是一个小例子,虽然因为这只是一个矩形,所以滞后非常轻微,但它就在那里。在较大的程序中,我一次绘制大量它们,但只移动一个。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.*;

public class MouseTest {
    JFrame window;
    DrawPanel content;

    public MouseTest(){
        window = new JFrame("Test");
        content = new DrawPanel();
        window.setContentPane(content);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        window.pack();
    }

    public static void main (String[] args){
        MouseTest test = new MouseTest();
    }

    private class DrawPanel extends JPanel implements MouseMotionListener {
        int mouseX;
        int mouseY;

        private DrawPanel(){
            setBackground(Color.BLUE);
            setPreferredSize(new Dimension(400,400));
            addMouseMotionListener(this);
        }

        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(mouseX, mouseY, 20, 20);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseMoved(MouseEvent e) {
            mouseX = e.getX();
            mouseY = e.getY();
            repaint();

        }
    }

}

【问题讨论】:

  • 是“双缓冲”选项的默认值吗? ...立即证明这一点

标签: java swing


【解决方案1】:

要做的第一件事是将所有 Swing/AWT 代码移入 EDT。在您的应用程序中,这可能无关紧要,但这是一个养成的好习惯。

但是,我无法用任何一种方法重现您的滞后。

public static void main (String[] args)
{
    SwingUtilities.invokeLater(
        new Runnable()
        {
            public void run()
            {
                MouseTest test = new MouseTest();
            }
        });
}

有关 Swing 线程的更多信息,请参阅 this article

【讨论】:

    【解决方案2】:

    也许在这个问题上很遥远,但是当你说“落后”时,你的意思是光标不在矩形的中心吗?您的代码将光标指向矩形的左上角,您需要将其偏移以使其居中。

    【讨论】:

    • 不,我的意思是我希望光标始终位于顶部,并且矩形的左上角有时不会落在光标后面。
    【解决方案3】:

    即使这是更多的工作,我也建议您只使已更改的区域无效并重新绘制任何此类任务。这将节省许多周期(想象一下一直绘制完整的背景......)。

    您会看到很大的改进。

    编辑

    我用这个例子自己测试过

        public void mouseMoved(MouseEvent e) {
            repaint(mouseX, mouseY, 20, 20);
            mouseX = e.getX();
            mouseY = e.getY();
            repaint(mouseX, mouseY, 20, 20);
        }
    

    并且必须承认这些改进有点学术性(至少对我的计算机而言)。无论如何,这种技术应该用于更复杂的绘制方法..(你最终会看到改进)

    编辑

    还有更多作弊:如果您仍然不喜欢您认为光标所在位置与系统认为的位置之间的不匹配,请尝试关闭光标(http://www.java2s.com/Code/Java/2D-Graphics- GUI/HidethemousecursoruseatransparentGIFasthecursor.htm) 为用户提供更好的反馈。

    【讨论】:

      【解决方案4】:

      矩形滞后,因为您的班级处理每个运动事件。如果它只处理最近的事件,那么矩形将是最新的(尽管它的位置可能有很大的跳跃)。一种方法是运行一个单独的线程,该线程根据当前鼠标位置绘制矩形,该位置由 mouseMoved() 方法更新。您必须同步对鼠标位置变量的访问。

      【讨论】:

        猜你喜欢
        • 2012-12-06
        • 2018-07-06
        • 1970-01-01
        • 2013-02-14
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        • 2015-08-23
        相关资源
        最近更新 更多