4

我有一个 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()。

[编辑]

正如所有回复所暗示的那样,解决方案似乎是延迟双击动作并等待一定时间进行三次单击。

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

如果我的双击操作在我的三次单击操作之前执行,这并不是真正的灾难,但它确实会产生一些额外的开销,尤其是一些我想阻止的额外数据流量。

由于到目前为止唯一的解决方案可能会导致其他问题,这实际上可能比原来的问题更糟糕,所以我将保持原样。

4

7 回答 7

4
  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());
          }
   }
于 2013-11-18T11:30:36.730 回答
2

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

于 2013-04-22T03:39:22.527 回答
1

你可以做类似的事情,改变延迟时间:

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);
}
}
于 2013-01-16T08:22:21.640 回答
0

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

暗示。

如果getClickCount()==2然后让它等待..说喜欢200ms

于 2013-01-16T08:11:26.733 回答
0

这与检测双击而不触发单击完全相同的问题。您必须延迟触发事件,直到您确定没有后续点击。

于 2013-01-16T08:53:44.150 回答
0

这里有一个教程

编辑:它会单独触发点击事件,所以你会得到:单击然后双击然后三次单击。所以你仍然需要做一些时间技巧。

代码是:

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");
    }
  }
}
于 2013-06-03T13:15:07.547 回答
0

这是我为实现这一目标所做的工作,这对我来说实际上效果很好。检测点击类型需要延迟。你可以选择它。如果可以在 400 毫秒内发生三次单击,则会出现以下延迟。您可以将其减小到无法连续单击的程度。如果您只是担心延迟,那么这是一个可以忽略不计的延迟,这对于执行此操作至关重要。

这里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){}
                    }
}
于 2013-07-16T09:37:00.870 回答