JLabel 跟不上鼠标

JLabel can't keep up with mouse

我有一个小程序,它创建了一个可以被视为操纵杆的东西。一切正常,但有一个小故障,我不知道如何修复。如果鼠标移动得太快,我拖动的 JLabel 会粘住,因为鼠标已移出绘制框。我可以增加 Jlabel 的大小,但 "O" 与鼠标的偏移量太大。 (我什至宁愿减小尺寸,但是对于这种实现,最大鼠标速度太低了)。 任何想法如何解决这一问题?

这是完整的代码,顺便说一句,任何人都可以继续编译,看看鼠标移动太快时到底出了什么问题。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainClass implements ActionListener, MouseListener, MouseMotionListener
{
int labelSize = 20;
int screenOffsetX = 58;
int screenOffsetY = 130;
JFrame frame;
JLabel xAxis;
JLabel move;
JLabel drag;
JLabel yAxis;
JLabel xAxisDrag;
JLabel yAxisDrag;
JLabel radio;
JLayeredPane panel;
Robot rob;
public static void main(String[] args)
{
    new MainClass();
}
public MainClass()
{   
    frame = new JFrame("app");
    frame.setLayout(null);
    frame.setBounds(20, 20, 400, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    move = new JLabel("Movement");
    move.setBounds(150, 0, 100, 15);
    frame.add(move);

    xAxis = new JLabel("X");
    xAxis.setBounds(100, 20, 50, 15);
    frame.add(xAxis);

    yAxis = new JLabel("Y");
    yAxis.setBounds(200, 20, 50, 15);
    frame.add(yAxis);

    drag = new JLabel("Dragging");
    drag.setBounds(150, 40, 100, 15);
    frame.add(drag);

    xAxisDrag = new JLabel("X");
    xAxisDrag.setBounds(100, 60, 50, 15);
    frame.add(xAxisDrag);

    yAxisDrag = new JLabel("Y");
    yAxisDrag.setBounds(200, 60, 50, 15);
    frame.add(yAxisDrag);

    radio = new JLabel("O");
    radio.setBounds(0, 0, labelSize, labelSize);
    radio.setOpaque(false);
    radio.setEnabled(false);
    panel = new JLayeredPane();
    panel.setBounds(50, 100, 257, 257);
    panel.setLayout(null);
    panel.setBackground(new Color((float)1.0,(float)1.0,(float)1.0));
    panel.setOpaque(true);
    panel.add(radio);
    radio.setLocation(128, 128);
    frame.add(panel);
    panel.addMouseMotionListener(this);
    panel.addMouseListener(this);
    frame.revalidate();
    frame.repaint();
}
@Override
public void actionPerformed(ActionEvent e) {}
@Override
public void mouseDragged(MouseEvent e)
{
    if(!(e.getPoint().x<0 || e.getPoint().y<0 || e.getPoint().x>257 || e.getPoint().y>257))
    {   
        xAxis.setText("X: "+((e.getPoint().x/4)-32));
        yAxis.setText("Y: "+((e.getPoint().y/4)-32));
    }
    if(e.getPoint().x<0 || e.getPoint().y<0 || e.getPoint().x>257 || e.getPoint().y>257)
    {   //Neļauj iziet ārpus paneļa;
        try
        {
            rob = new Robot();
            if(e.getPoint().x<0)
                rob.mouseMove((screenOffsetX+frame.getX()), (e.getPoint().y+screenOffsetY+frame.getY()));
            if(e.getPoint().y<0)
                rob.mouseMove((e.getPoint().x+screenOffsetX+frame.getX()), (screenOffsetY+frame.getY()));
            if(e.getPoint().x>257)
                rob.mouseMove((257+screenOffsetX+frame.getX()), (e.getPoint().y+screenOffsetY+frame.getY()));
            if(e.getPoint().y>257)
                rob.mouseMove((e.getPoint().x+screenOffsetX+frame.getX()), (257+screenOffsetY+frame.getY()));
        }
        catch (AWTException e1)
        {
            e1.printStackTrace();
        }
    }
    if(     (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) && 
            (e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
            )
    {   //Ja kursors ir uz JLabel, tad pārvieto;
        xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
        yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
        radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);
    }
}
@Override
public void mouseMoved(MouseEvent e)
{
    xAxis.setText("X: "+((e.getPoint().x/4)-32));
    yAxis.setText("Y: "+((e.getPoint().y/4)-32));
}
@Override
public void mouseClicked(MouseEvent arg0) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e)
{
    radio.setLocation(124, 124);
    xAxisDrag.setText("X: "+0);
    yAxisDrag.setText("Y: "+0);
}

}

替换

     if(     (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) && 
        (e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
        )
{   //Ja kursors ir uz JLabel, tad pārvieto;
    xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
    yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
    radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);
}

作者:

  if(      (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) && 
        (e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
        )
{
    //Has the mouse been clicked inside the radio before grabbing started ?
    if(grab==0)  //if it is the first iteration of the function mousedragged
        grab=2;  //proceed to "grab"
}

if(grab==2 &&   (e.getPoint().x>=0 && e.getPoint().x<panel.getWidth()) && 
        (e.getPoint().y>=0 && e.getPoint().y<panel.getHeight())
        )
{   //Ja kursors ir uz JLabel, tad pārvieto;
    System.out.println(radio.getX()+" "+radio.getY());
    xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
    yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
    radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);

}
if(grab!=2)  // if grabbing is not started
   grab=1; // first iteration is over

将 MouseReleased 函数更新为:

        @Override
    public void mouseReleased(MouseEvent e)
    {
        //this a new line
        //grabbing is over
        grab=0;  // go back to idle state
        radio.setLocation(124, 124);
        xAxisDrag.setText("X: "+0);
        yAxisDrag.setText("Y: "+0);
    }

最后,向您的 class MainClass 添加一个名为 grab 的新字段:

  private int grab=0;  //idle state

抢的意思:
1. grab=0 => 第一次执行MouseDragged函数,"grabbing"还没有启动。事实上,当您拖动鼠标时,此函数会像无限循环一样迭代,直到您释放鼠标。所以知道它什么时候开始很重要。
2. grab=1 => 迭代已经开始但是没有"grabbing"
3. grab=2 => "grabbing" 已经开始。你可以注意到在做作之前的条件 grab==0 。事实上,我试图避免鼠标从其他地方拖动并经过 "radio" 然后收音机是 "grabbed" 的情况。这就是为什么我检查它是第一次迭代。在这种情况下,我们有 grab=1 => 收音机没有被抓取