2012-06-08 131 views
41

我想知道是否有可能檢測到JavaFX 2中的雙擊?如何 ?Javafx 2單擊並雙擊

我想在點擊和雙擊之間做出不同的事件。

感謝

回答

72

是的,你可以檢測單,雙甚至多次點擊:

myNode.setOnMouseClicked(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent mouseEvent) { 
     if(mouseEvent.getButton().equals(MouseButton.PRIMARY)){ 
      if(mouseEvent.getClickCount() == 2){ 
       System.out.println("Double clicked"); 
      } 
     } 
    } 
}); 

MouseButton.PRIMARY用於確定左(通常)鼠標左鍵觸發事件。閱讀getClickCount()的api得出的結論是,除了單倍或雙倍外,可能還有多次點擊計數。不過,我發現很難區分單擊事件和雙擊事件。因爲雙擊的第一次點擊計數也會引發單個事件。 "Single clicked"總是觸發:

+0

@uluk biy那麼在我的fxml文件中註冊的onAction處理函數怎麼樣,並且在點擊按鈕時調用。這個處理程序會和它衝突嗎? – likejiujitsu

+1

@Anil。不,它不會。 Button可以同時具有onAction和onMouseClicked事件處理程序。這些事件將作爲他們每個人的API文檔說的觸發。 –

+0

@uluk biy應該單擊處理代碼進入onAction處理程序並雙擊鼠標處理程序? – likejiujitsu

16

,如果你想加入

if(mouseEvent.getClickCount() == 2) 
{ 
    System.out.println("Doubleclicked"); 
} 
else if(mouseEvent.getClickCount() == 1) 
{ 
    System.out.println("Single clicked"); 
} 

結果處理點擊和雙擊不工作。

2

下面是我已經實現雙擊

if (e.getEventType().equals(MouseEvent.MOUSE_CLICKED) && !drag_Flag) { 
       long diff = 0; 
      if(time1==0) 
      time1=System.currentTimeMillis(); 
      else 
      time2=System.currentTimeMillis(); 
      if(time1!=0 && time2!=0) 
      diff=time2-time1; 
      if((diff/1000)<=215 && diff>0) 
      { 
       isdblClicked=true; 
      } 
      else 
      { 
       isdblClicked=false; 
      } 

      System.out.println("IsDblClicked()"+isdblClicked); 

}

+0

我認爲將點擊之間的時間考慮在內是很重要的。如果(diff> 0 &&(diff/1000)<= 215)'if' – Wingie

6

下面是另一個代碼塊,可如果你有一個單和區分使用雙擊並有在這兩種情況下采取具體行動。

import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.ScheduledThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseButton; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class DoubleClickDetectionTest extends Application { 

    boolean dragFlag = false; 

    int clickCounter = 0; 

    ScheduledThreadPoolExecutor executor; 

    ScheduledFuture<?> scheduledFuture; 

    public DoubleClickDetectionTest() { 
     executor = new ScheduledThreadPoolExecutor(1); 
     executor.setRemoveOnCancelPolicy(true); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     StackPane root = new StackPane(); 

     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 

     root.setOnMouseDragged(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent e) { 
       if (e.getButton().equals(MouseButton.PRIMARY)) { 
        dragFlag = true; 
       } 
      } 
     }); 

     root.setOnMouseClicked(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent e) { 
       if (e.getButton().equals(MouseButton.PRIMARY)) { 
        if (!dragFlag) { 
         System.out.println(++clickCounter + " " + e.getClickCount()); 
         if (e.getClickCount() == 1) { 
          scheduledFuture = executor.schedule(() -> singleClickAction(), 500, TimeUnit.MILLISECONDS); 
         } else if (e.getClickCount() > 1) { 
          if (scheduledFuture != null && !scheduledFuture.isCancelled() && !scheduledFuture.isDone()) { 
           scheduledFuture.cancel(false); 
           doubleClickAction(); 
          } 
         } 
        } 
        dragFlag = false; 
       } 
      } 
     }); 
    } 

    @Override 
    public void stop() { 
     executor.shutdown(); 
    } 

    private void singleClickAction() { 
     System.out.println("Single-click action executed."); 
    } 

    private void doubleClickAction() { 
     System.out.println("Double-click action executed."); 
    } 
} 
3

P.Pendey的迴應是實際區分單擊和雙擊的最簡單方法,但它對我無效。首先,函數「currentTimeMillis」已經返回毫秒,因此除以1000似乎不是必須的。下面的版本以更一致的方式爲我工作。

@Override 
public void handle(MouseEvent t) { 

     long diff = 0; 

     currentTime=System.currentTimeMillis(); 

     if(lastTime!=0 && currentTime!=0){ 
      diff=currentTime-lastTime; 

      if(diff<=215) 
       isdblClicked=true; 
      else 
       isdblClicked=false; 
     } 

     lastTime=currentTime; 

     System.out.println("IsDblClicked()"+isdblClicked); 

     //use the isdblClicked flag... 
} 
0

堅持到Java SE 8 lambda表達式會是這個樣子:

node.setOnMouseClicked(event -> { 
    if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) { 
     handleSomeAction(); 
    } 
}); 

一旦你習慣了lambda表達式 - 他們最終會被比原來的類實例化和壓倒一切的(X更容易理解) 方法。 - 在我看來,