2013-01-16 26 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