繁体   English   中英

Java:检测三击而不触发双击

[英]Java : detect triple-click without firing double-click

我有一个JTable,我想在双击单元格时调用一个函数,并在单击三次单元格时调用另一个函数。

当单击三次单元格时,我不想调用双击功能。

我现在拥有的是(mgrdAlarm是JTable):

mgrdAlarm.addMouseListener(new MouseAdapter()
{
  public void mouseClicked(MouseEvent e)
  {
    System.out.println("getClickCount() = " + e.getClickCount());
    if (e.getClickCount()==2)
    {
      doubleClick();
      System.out.println("Completed : doubleClick()");
    }
    if (e.getClickCount()==3)
    {
      tripleClick();
      System.out.println("Completed : tripleClick()");
    }
  }
});

双击控制台时显示:

getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()

三击时,控制台显示:

getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()
getClickCount() = 3
Completed : tripleClick()

三击时,我希望控制台显示:

getClickCount() = 1
getClickCount() = 2
getClickCount() = 3
Completed : tripleClick()

因此,当单击三次单元格时,我不想调用函数doubleClick(),但我想在双击单元格时调用函数doubleClick()。

[编辑]

正如所有回复都表明解决方案似乎是延迟双击操作并等待一段时间进行三次点击。

但正如这里所讨论的那样,可能会导致不同类型的问题:用户可能将其双击时间设置得相当长,这可能与我的三次点击超时重叠。

如果我的双击操作在我的三击操作之前执行,那不是真正的灾难,但它确实会产生一些额外的开销,特别是一些我希望阻止的额外数据流量。

到目前为止唯一的解决办法可能会导致其他问题,这可能实际上比原来的问题更糟糕,我现在就把它留下来。

  public class TestMouseListener implements MouseListener {    
  private boolean leftClick;
  private int clickCount;
  private boolean doubleClick;
  private boolean tripleClick;
  public void mouseClicked(MouseEvent evt) {
    if (evt.getButton()==MouseEvent.BUTTON1){
                leftClick = true; clickCount = 0;
                if(evt.getClickCount() == 2) doubleClick=true;
                if(evt.getClickCount() == 3){
                    doubleClick = false;
                    tripleClick = true;
                }
                Integer timerinterval = (Integer)Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");

                         Timer  timer = new Timer(timerinterval, new ActionListener() {
                            public void actionPerformed(ActionEvent evt) { 

                                if(doubleClick){
                                    System.out.println("double click.");                                    
                                    clickCount++;
                                    if(clickCount == 2){
                                        doubleClick();   //your doubleClick method
                                        clickCount=0;
                                        doubleClick = false;
                                        leftClick = false;
                                    }

                                }else if (tripleClick) { 

                                    System.out.println("Triple Click.");
                                    clickCount++;
                                    if(clickCount == 3) {
                                       tripleClick();  //your tripleClick method
                                        clickCount=0;
                                        tripleClick = false;
                                        leftClick = false;
                                    }

                                } else if(leftClick) {                                      
                                    System.out.println("single click.");
                                    leftClick = false;
                                }
                            }               
                        });
                        timer.setRepeats(false);
                        timer.start();
                        if(evt.getID()==MouseEvent.MOUSE_RELEASED) timer.stop();
            }           
      }


          public static void main(String[] argv) throws Exception {

            JTextField component = new JTextField();
            component.addMouseListener(new TestMouseListener());
            JFrame f = new JFrame();

            f.add(component);
            f.setSize(300, 300);
            f.setVisible(true);

            component.addMouseListener(new TestMouseListener());
          }
   }

之前的答案是正确的:你必须考虑时间和延迟,将其识别为双击,直到经过一定的时间。 挑战在于,正如您所注意到的,用户可能具有非常长或非常短的双击阈值。 所以你需要知道用户的设置是什么。 这个其他Stack Overflow线程( 区分单击和Java中的双击 )提到了awt.multiClickInterval桌面属性。 尝试使用它作为您的阈值。

你可以做类似的事情,不同的延迟时间:

public class ClickForm extends JFrame {

final static long CLICK_FREQUENTY = 300;

static class ClickProcessor implements Runnable {

    Callable<Void> eventProcessor;

    ClickProcessor(Callable<Void> eventProcessor) {
        this.eventProcessor = eventProcessor;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(CLICK_FREQUENTY);
            eventProcessor.call();
        } catch (InterruptedException e) {
            // do nothing
        } catch (Exception e) {
            // do logging
        }
    }
}

public static void main(String[] args) {
    ClickForm f = new ClickForm();
    f.setSize(400, 300);
    f.addMouseListener(new MouseAdapter() {
        Thread cp = null;
        public void mouseClicked(MouseEvent e) {
            System.out.println("getClickCount() = " + e.getClickCount() + ", e: " + e.toString());

            if (cp != null && cp.isAlive()) cp.interrupt();

            if (e.getClickCount() == 2) {
                cp = new Thread(new ClickProcessor(new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        System.out.println("Double click processed");
                        return null;
                    }
                }));
                cp.start();
            }
            if (e.getClickCount() == 3) {
                cp =  new Thread(new ClickProcessor(new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        System.out.println("Triple click processed");
                        return null;
                    }
                }));
                cp.start();
            }
        }
    });
    f.setVisible(true);
}
}

有一个教程这个位置

编辑:它会单独触发单击事件,因此您可以获得:单击然后双击然后三击。 所以你仍然需要做一些计时技巧。

代码是:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JTextField;

public class Main {
  public static void main(String[] argv) throws Exception {

    JTextField component = new JTextField();
    component.addMouseListener(new MyMouseListener());
    JFrame f = new JFrame();

    f.add(component);
    f.setSize(300, 300);
    f.setVisible(true);

    component.addMouseListener(new MyMouseListener());
  }
}

class MyMouseListener extends MouseAdapter {
  public void mouseClicked(MouseEvent evt) {
    if (evt.getClickCount() == 3) {
      System.out.println("triple-click");
    } else if (evt.getClickCount() == 2) {
      System.out.println("double-click");
    }
  }
}

您需要延迟执行double click以检查它是否为tripple click

暗示。

如果getClickCount()==2然后把它等待...比如200ms

这与检测双击而不触发单击完全相同。 你必须延迟发射一个事件,直到你确定没有下一个点击。

以下是我为实现这一目标所做的工作,这对我来说确实很好。 检测点击类型需要延迟。 你可以选择它。 如果在400ms内发生三次点击,则会出现以下延迟。 您可以将其减小到可以连续单击的程度。 如果你只是担心延迟,那么这是一个非常微不足道的延迟,这对于实现这一点必不可少。

这里flagt1是全局变量。

public void mouseClicked(MouseEvent e)
{
int count=e.getClickCount();
                    if(count==3)
                    {
                        flag=true;
                        System.out.println("Triple click");
                    }
                    else if(count==2)
                    {
                        try
                        {
                        t1=new Timer(1,new ActionListener(){
                            public void actionPerformed(ActionEvent ae)
                            {
                                if(!flag)
                                System.out.println("Double click");
                                flag=false;
                                t1.stop();
                            }
                        });
                        t1.setInitialDelay(400);
                        t1.start();
                        }catch(Exception ex){}
                    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM