Java检测鼠标长按

Java检测鼠标长按,java,swing,events,Java,Swing,Events,如果用户按下JList组件超过3秒,是否有任何方法捕获事件 我发现最困难的部分是,即使在用户松开鼠标左键之前,也需要触发事件。(这可以很容易地由一对按住鼠标和松开鼠标的夫妇来完成)我有个主意。它不完全是一个监听器,但你可以做的是在鼠标按下上启动计时器。当计时器达到3秒时,您的事件开始,或者如果它们停止,则在鼠标上释放计时器。我有一个主意。它不完全是一个监听器,但你可以做的是在鼠标按下上启动计时器。当计时器达到3秒时,您的事件开始,或者如果它们停止,则在mousererelease上,计时器停止。

如果用户按下JList组件超过3秒,是否有任何方法捕获事件


我发现最困难的部分是,即使在用户松开鼠标左键之前,也需要触发事件。(这可以很容易地由一对按住鼠标和松开鼠标的夫妇来完成)

我有个主意。它不完全是一个监听器,但你可以做的是在
鼠标按下
上启动计时器。当计时器达到3秒时,您的事件开始,或者如果它们停止,则在
鼠标上释放计时器。

我有一个主意。它不完全是一个监听器,但你可以做的是在
鼠标按下
上启动计时器。当计时器达到3秒时,您的事件开始,或者如果它们停止,则在
mousererelease
上,计时器停止。

以下是我在类似情况下使用的方法:

public class Player implements Runnable, MouseListener
{
    public void mousePressed(MouseEvent e)
    {
        holding = true;
        thread = new Thread(this);
        thread.start();
    }

    public void mouseReleased(MouseEvent e)
    {
        holding = false;
        System.out.println("Held for: "+seconds);
    }
    public void mouseClicked(MouseEvent e){}

    public void run()
    {
        try
        {
            while(holding)
            {
                seconds++;
                // put some code here
                if(seconds==3)
                {
                    holding = false;
                    System.out.println("Held for maximum time!");
                }
            }
        }catch(Exception e){e.printStackTrace();}

    private boolean holding;
    private int seconds;
    private Thread thread;
}

通过调用label.addMouseListener(new Player())将其添加到JLabel中

以下是我在类似情况下使用的方法:

public class Player implements Runnable, MouseListener
{
    public void mousePressed(MouseEvent e)
    {
        holding = true;
        thread = new Thread(this);
        thread.start();
    }

    public void mouseReleased(MouseEvent e)
    {
        holding = false;
        System.out.println("Held for: "+seconds);
    }
    public void mouseClicked(MouseEvent e){}

    public void run()
    {
        try
        {
            while(holding)
            {
                seconds++;
                // put some code here
                if(seconds==3)
                {
                    holding = false;
                    System.out.println("Held for maximum time!");
                }
            }
        }catch(Exception e){e.printStackTrace();}

    private boolean holding;
    private int seconds;
    private Thread thread;
}

通过调用label.addMouseListener(new Player())将其添加到JLabel中

您可以在mouseDown事件侦听器中设置计时器,并在初始延迟3000毫秒后每隔500毫秒执行一次。在mouseDown事件侦听器中,您可以取消该计时器。在与您的
计时器关联的
TimerTask
对象的run方法上,您可以执行所需任务的计算。以下是我的解决方案:

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

public class Test
{
    public static void main(String[] args)
    {
        final JFrame f = new JFrame();
        String[] data = {"one", "two", "three", "four"};
        JList myList = new JList(data);
        f.add(myList);
        myList.addMouseListener(
            new MouseAdapter()
            {
                private java.util.Timer t;
                public void mousePressed(MouseEvent e)
                {
                    if(t == null)
                    {
                        t = new java.util.Timer();
                    }
                    t.schedule(new TimerTask()
                    {
                        public void run()
                        {
                            System.out.println("My importan task goes here");
                        }
                    },3000,500);
                }

                public void mouseReleased(MouseEvent e)
                {
                    if(t != null)
                    {
                        t.cancel();
                        t = null;
                    }
                }
            }
            );
            f.pack();
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    f.setVisible(true);
                }
            }
        );
    }
}

您可以在mouseDown事件侦听器中设置计时器,并在初始延迟3000毫秒后每500毫秒执行一次。在MouseRelease中,您可以取消该计时器。在与您的
计时器关联的
TimerTask
对象的run方法上,您可以执行所需任务的计算。以下是我的解决方案:

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

public class Test
{
    public static void main(String[] args)
    {
        final JFrame f = new JFrame();
        String[] data = {"one", "two", "three", "four"};
        JList myList = new JList(data);
        f.add(myList);
        myList.addMouseListener(
            new MouseAdapter()
            {
                private java.util.Timer t;
                public void mousePressed(MouseEvent e)
                {
                    if(t == null)
                    {
                        t = new java.util.Timer();
                    }
                    t.schedule(new TimerTask()
                    {
                        public void run()
                        {
                            System.out.println("My importan task goes here");
                        }
                    },3000,500);
                }

                public void mouseReleased(MouseEvent e)
                {
                    if(t != null)
                    {
                        t.cancel();
                        t = null;
                    }
                }
            }
            );
            f.pack();
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    f.setVisible(true);
                }
            }
        );
    }
}
两种不同的解决方案(与之前的解决方案几乎相同):

newmouseadapter(){
按日期和时间;
长时间点击;
@凌驾
公共无效鼠标按下(MouseEvent e){
按时间=新日期();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
timeClicked=newdate().getTime()-按edtime.getTime();
如果(单击的时间>=3000){
//你在这里做什么
}
}
};

newmouseadapter(){
布尔mousePressed=false;
@凌驾
公共无效鼠标按下(MouseEvent e){
新线程(newrunnable()){
@凌驾
公开募捐{
鼠标按下=真;
while(鼠标按下){
试一试{
睡眠(3000);
}捕捉(中断异常e){
e、 printStackTrace();
}
如果(鼠标按下){
//你在这里做什么
}
}
}
}).start();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
鼠标按下=错误;
}
}
两种不同的解决方案(与之前的解决方案几乎相同):

newmouseadapter(){
按日期和时间;
长时间点击;
@凌驾
公共无效鼠标按下(MouseEvent e){
按时间=新日期();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
timeClicked=newdate().getTime()-按edtime.getTime();
如果(单击的时间>=3000){
//你在这里做什么
}
}
};

newmouseadapter(){
布尔mousePressed=false;
@凌驾
公共无效鼠标按下(MouseEvent e){
新线程(newrunnable()){
@凌驾
公开募捐{
鼠标按下=真;
while(鼠标按下){
试一试{
睡眠(3000);
}捕捉(中断异常e){
e、 printStackTrace();
}
如果(鼠标按下){
//你在这里做什么
}
}
}
}).start();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
鼠标按下=错误;
}
}

使用此代码,您可以检测和管理长按或短按(如单击),一个事件排除另一个事件

private int pressStatus = 0; // TO DETECT IF LONG IS REAL LONG OR SHORT PRESSED
private Timer t;

...

@Override
public void mousePressed(final MouseEvent arg0) {
    pressStatus = 0; // to manage simple click or long

    if (t == null) {
        t = new Timer();
    }
    t.schedule(new TimerTask() {
        public void run() {
            pressStatus = 1;

            if (t != null) {
                t.cancel();
                t = null;
            }

            // PRESSED LONG
            int modifiers = arg0.getModifiers();
            if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
                ...
            } else if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
                ....
            }
        }
    }, 700, 1);
}

@Override
public void mouseReleased(MouseEvent arg0) {
    if (t != null) {
        t.cancel();
        t = null;
    }

    // PRESSED SHORT LIKE CLICK
    if (pressStatus == 0) {
        int modifiers = arg0.getModifiers();
        if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
            ...
        } else if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
            ...
        }
    }

    pressStatus = 0;
}

使用此代码,您可以检测和管理按下的长或短(如单击),一个事件排除另一个事件

private int pressStatus = 0; // TO DETECT IF LONG IS REAL LONG OR SHORT PRESSED
private Timer t;

...

@Override
public void mousePressed(final MouseEvent arg0) {
    pressStatus = 0; // to manage simple click or long

    if (t == null) {
        t = new Timer();
    }
    t.schedule(new TimerTask() {
        public void run() {
            pressStatus = 1;

            if (t != null) {
                t.cancel();
                t = null;
            }

            // PRESSED LONG
            int modifiers = arg0.getModifiers();
            if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
                ...
            } else if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
                ....
            }
        }
    }, 700, 1);
}

@Override
public void mouseReleased(MouseEvent arg0) {
    if (t != null) {
        t.cancel();
        t = null;
    }

    // PRESSED SHORT LIKE CLICK
    if (pressStatus == 0) {
        int modifiers = arg0.getModifiers();
        if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
            ...
        } else if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
            ...
        }
    }

    pressStatus = 0;
}

你的代码有效!只是好奇。。。为什么我们需要将f.setvisible(true)设置为可见;在SwingUtilities.invokeLater()中?这很好,另外一个很好的补充是,第一次单击应该执行任务,然后如果用户在3秒钟后仍然按住鼠标,则每500毫秒启动一次计划任务您的代码工作!只是好奇。。。为什么我们需要将f.setvisible(true)设置为可见;在SwingUtilities.invokeLater()中?这很好,另外一个很好的补充是,第一次单击应该执行任务,然后如果用户在3秒钟后仍然按住鼠标,那么每500分钟启动一次计划任务。现在,您在多个线程上访问了一个保持变量,如果您想在UI中执行任何操作(这很可能是因为用户执行了一些此代码应该响应的操作),那么您需要从该线程返回到UI线程。与简单的Swing
计时器相比,所有这些的好处是什么?因此,现在您有了一个在多个线程上访问的保持变量,如果您想在UI中执行任何操作(这很可能是因为用户执行了一些此代码应该响应的操作),您需要从该线程返回UI线程。与简单的Swing
计时器相比,所有答案(截至2016年)都包含欺骗性的细微错误,不应按原样使用。所有答案(截至2016年)都包含欺骗性的su