我在鼠标位置绘制矩形时遇到了一些麻烦。移动鼠标时,绘制的矩形滞后于鼠标光标。有没有办法确保矩形在鼠标上完全移动并且不会落后?
这是一个小例子,虽然因为这只是一个矩形,滞后很小,但它就在那里。在较大的程序中,我一次只绘制了一大堆它们,但只移动了它。
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();
}
}
}
答案 0 :(得分:2)
首先要做的是将所有Swing / AWT代码移入EDT。在您的应用程序中,可能无关紧要,但这是一个很好的习惯。
然而,我无法用这两种方法重现你的滞后。
public static void main (String[] args)
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
MouseTest test = new MouseTest();
}
});
}
有关Swing Threading的更多信息,请参阅this article。
答案 1 :(得分:1)
也许就此而言,当你说“滞后”时,你的意思是光标不在矩形的中心吗?您的代码的光标指向矩形的左上角,您需要将其偏移以使其居中。
答案 2 :(得分:0)
即使这是更多的工作,我建议任何此类任务,您只能使已更改的区域无效并重新绘制。这将节省许多周期(想象一直在绘制完整的背景......)。
你会看到很大的改进。
修改
我自己用这个例子测试了它
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)为用户提供更好的反馈。
答案 3 :(得分:0)
矩形滞后,因为您的类处理每个动作事件。如果它只处理最近的事件,那么矩形将是最新的(尽管它可能在位置上有大的跳跃)。一种方法是运行一个单独的线程,该线程根据当前鼠标位置绘制矩形,该位置由mouseMoved()方法更新。您必须同步访问鼠标位置变量。