Java MouseEvent,检查是否按下了

时间:2011-07-26 10:31:44

标签: java swing mouseevent mouselistener

我有一个实现MouseListener(JPanel)的类。当我点击面板时会发生一些事情。我想要的是某种while循环,只要按下鼠标按钮就会循环。

@Override
public void mousePressed(MouseEvent e) {
    while(e.isPressedDownD) {      // <--
        //DO SOMETHING
    }
}

这显然不起作用,但我希望你明白我想要实现的目标。 全班有兴趣的人:

package control;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import model.GridModel;
import view.GUIView;

public class MapListener implements MouseListener{
    private GridModel model;
    private GUIView view;
    private int posX;
    private int posY;

    public MapListener(GridModel model, GUIView view) {
        this.model = model;
        this.view = view;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        posX = e.getX();
        posY = e.getY();
        model.setMouseAtX(posX);
        model.setMouseAtY(posY);
        view.paintTile();
        System.out.println("X: " + posX + " Y: " + posY);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        while(e.getModifiers() == MouseEvent.MOUSE_PRESSED) { //Obviously doesn't work
            //DO SOMETHING
        }
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
    }
}

5 个答案:

答案 0 :(得分:15)

正如其他答案所指出的,在鼠标事件监听器方法中,你的工作地点是不是

MouseEvent中也没有明确的“鼠标按下”概念,因此您必须自己跟踪。我提供了一个如何执行此操作的示例。另请注意MouseEvent.BUTTON1引用,因为这只是为了跟踪鼠标左键的状态。

这是您必须开始了解并发性的地方。出于这个原因,我已经添加了一个synchronized方法,因为你需要知道当多个线程同时访问属性时会发生有趣的事情,synchronized是一种保持理智的机制。考虑进一步阅读超出本例范围的内容。

未经测试,但这应该有效:

volatile private boolean mouseDown = false;

public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        mouseDown = true;
        initThread();
    }
}

public void mouseReleased(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        mouseDown = false;
    }
}

volatile private boolean isRunning = false;
private synchronized boolean checkAndMark() {
    if (isRunning) return false;
    isRunning = true;
    return true;
}
private void initThread() {
    if (checkAndMark()) {
        new Thread() {
            public void run() {
                do {
                    //do something
                } while (mouseDown);
                isRunning = false;
            }
        }.start();
    }
}

答案 1 :(得分:10)

为什么这么多答案错误地断言MouseEvent中没有明确的“鼠标按下”概念?

虽然其他评论者认为OP不应该在事件处理程序中执行所有操作,但在其他情况下,查询鼠标侦听器中的按钮状态很有用。在这些情况下,您实际上可以确定按钮关闭状态。例如:

@Override
public void mouseExited(MouseEvent event) // Or any other mouse event handler...
{
    int buttonsDownMask = MouseEvent.BUTTON1_DOWN_MASK 
            | MouseEvent.BUTTON2_DOWN_MASK 
            | MouseEvent.BUTTON3_DOWN_MASK; // Or whichever buttons you care about...
    if ( (event.getModifiersEx() & buttonsDownMask) != 0 )
        System.out.println("Hey! Some button is pressed!");
}

请特别注意使用MouseEvent.getModifiersEx()方法以及MouseEvent.BUTTON1_DOWN_MASK和朋友。

答案 2 :(得分:4)

你可以创建一个包含你的while循环的新线程。 按下鼠标按钮时启动该线程。释放鼠标按钮时停止它。

答案 3 :(得分:3)

您不应该在事件处理程序中执行此操作,因为在事件处理程序退出之前不会再处理任何事件。

您想要实现的目标可以通过单独的工作线程完成。从mousePressed侦听器创建线程,在线程中执行任何操作(这应包含while循环)并在释放鼠标时使线程退出(您的mouseReleased侦听器应通知线程)。

答案 4 :(得分:2)

例如

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

public class ClickListener extends MouseAdapter implements ActionListener {

    private final static int clickInterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
    private MouseEvent lastEvent;
    private Timer timer;

    public ClickListener() {
        this(clickInterval);
    }

    public ClickListener(int delay) {
        timer = new Timer(delay, this);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        /*if (e.getClickCount() > 2) {
            return;
        }
        lastEvent = e;
        if (timer.isRunning()) {
            timer.stop();
            doubleClick(lastEvent);
        } else {
            timer.restart();
        }*/

        if (timer.isRunning() && !e.isConsumed() && e.getClickCount() > 1) {
            System.out.println("double");
            timer.stop();
        } else {
            timer.restart();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        timer.stop();
        singleClick(lastEvent);
    }

    public void singleClick(MouseEvent e) {
    }

    public void doubleClick(MouseEvent e) {
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Double Click Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addMouseListener(new ClickListener() {

            @Override
            public void singleClick(MouseEvent e) {
                System.out.println("single");
            }

            @Override
            public void doubleClick(MouseEvent e) {
                System.out.println("double");
            }
        });
        frame.setPreferredSize(new Dimension(200, 200));
        frame.pack();
        frame.setVisible(true);
    }
}