2013-01-16 27 views
4

我有一个JTable,我想在双击单元格时调用函数,并在单击三次单元格时调用另一个函数。Java:检测三击而不触发双击

当单元格被三击时,我不想调用双击函数。

我现在所拥有的是(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()。

[编辑]

所有回复建议的解决方案似乎是耽误双击动作,等待一定的时间三击。

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

如果我的双击动作是在我的三连击动作之前执行的,但它确实会产生一些额外的开销,特别是一些额外的数据流量,我不希望发生这种情况。

作为迄今为止唯一的解决方案可能会导致其他问题,这可能实际上比原始问题更糟糕,我将保留现在的状态。

+0

嗯...延缓执行? –

+2

一个相当有趣的话题,但没有(如此)很容易解决。您可能想要开始阅读http://stackoverflow.com/questions/1067464/need-to-cancel-click-mouseup-events-when-double-click-event-detected。单击和双击提供相同的问题。 您需要在代码中实施一些时间跟踪。 – devnomore

+0

如何实现自定义EventQueue并检测一个,两个或三个点击这里? – 1ac0

回答

2

以前的答案是正确的:您必须考虑时间和延迟,将其视为双击,直到经过一段时间。正如你所注意到的,挑战是用户可能会有很长或很短的双击阈值。所以你需要知道用户的设置是什么。这另一个堆栈溢出线程(Distinguish between a single click and a double click in Java)提到了awt.multiClickInterval桌面属性。尝试使用你的门槛。

+0

谢谢,我没有看到之前的线程。将研究它 – Hrqls

0

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

提示。

if if getClickCount()==2 then then put it to .. for like like 200ms

+0

感谢您的回答。这似乎是要走的路,但在阅读另一个主题后,我认为这可能会导致额外的问题。看我的编辑到我的文章。 – Hrqls

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); 
} 
} 
+0

感谢您的回答。这似乎是要走的路,但在阅读另一个主题后,我认为这可能会导致额外的问题。看我的编辑到我的文章。 – Hrqls

0

这是完全一样的问题,因为检测双击。您必须延迟发起活动,直到您确定没有下一次点击。

+0

我有同样的问题[这里](http://stackoverflow.com/questions/15513139/cant-filter-mouseevent-mouse-clicked-in-awt-eventqueue) – 1ac0

+0

@EJP谢谢你的回答。这似乎是要走的路,但在阅读另一个主题后,我认为这可能会导致额外的问题。看我的编辑到我的文章。 – Hrqls

1

有此 here

编辑教程:它触发点击事件独立的,所以你会得到: 单则点击 双击即可 三击。所以你仍然需要做一些时间欺骗。

的代码是:

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"); 
    } 
    } 
} 
+0

感谢您的答案...检测点击并非那么困难,检测只是一个双击或三击(没有触发小点击事件)是问题...时间欺骗可能工作,但是欺骗..目前,我做了这样的事情,使轻点击事件发生,但没有剧烈的负面影响(除了一些额外的数据流量) – Hrqls

+0

是的。最主流的三重点击事件之一是在文本编辑器中选择一行。在执行三重点击代码之前,它们会触发单一事件和双击事件。 – alistair

+0

多数民众赞成多数民众赞成多数民众赞成多数民众赞成在真正的...我的双击虽然触发事件发送一些数据可能已经沉重的装置已经..所以我想发送尽可能少(三击点击发送其他数据)..但如此远在其工作,并没有崩溃(但:)) – Hrqls

0

这里是我做了什么来实现这一点,这其实对我来说工作得很好。检测点击类型需要延迟。你可以选择它。如果在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){} 
        } 
} 
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()); 
      } 
    } 
+0

感谢您的答案。这似乎与其他答案一样吗?其中有同样的问题,因为我不知道用户配置的双击时间。 – Hrqls