2012-06-08 25 views
41

Mi piacerebbe sapere se è stato possibile rilevare il doppio clic in JavaFX 2? e come ?Javafx 2 clic e doppio clic

Vorrei fare un evento diverso tra un clic e un doppio clic.

Grazie

risposta

72

Sì, è possibile rilevare singole, doppie anche più clic:

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 viene utilizzato per determinare se il tasto sinistro (comunemente) del mouse viene attivato l'evento. Leggi l'api di getClickCount() per concludere che potrebbero esserci più conteggi di clic diversi da singoli o doppi. Tuttavia trovo difficile distinguere tra eventi single e double click. Poiché il primo conteggio dei clic del doppio clic aumenterà anche un singolo evento.

+0

@uluk biy E il gestore onAction registrato nel mio file fxml e viene chiamato quando si fa clic sul pulsante. Questo handler si scontrerà con esso? – likejiujitsu

+1

@Anil. No, non lo farà. Il pulsante può avere sia gestori di eventi onAction che onMouseClicked. Questi eventi verranno attivati ​​come dice il documento API di ciascuno di essi. –

+0

@uluk biy dovrebbe fare clic sul codice di gestione con singolo clic sul gestore onAction e fare doppio clic sul gestore del mouse? – likejiujitsu

16

non funziona se si desidera gestire un solo clic e doppio clic aggiungendo

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

Risultati in: "Single clicked" è sempre licenziato.

2

Ecco come ho implementato doppio click

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

Penso che sia importante prendere in considerazione il tempo trascorso tra i clic. Girerei l'ordine all'interno della tua if-clausola come questa, però: 'if (diff> 0 && (diff/1000) <= 215)' – Wingie

6

Ecco un altro pezzo di codice che può essere utilizzato se si deve distinguere tra un singolo e un doppio clic e hanno intraprendere un'azione specifica in entrambi i casi.

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

La risposta di P. Pandey è l'approccio più semplice che effettivamente distingue tra singolo e doppio clic, ma non ha funzionato per me. Per uno, la funzione "currentTimeMillis" restituisce già millisecondi, quindi dividerlo per 1000 non sembra essere necessario. La versione di seguito ha funzionato per me in modo più coerente.

@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

Aderendo a Java SE espressioni 8 lambda sarebbe simile a questa:

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

Una volta che ci si abitua ad espressioni lambda - essi finiscono per essere più comprensibile l'istanza di classe originale e prioritario (x) metodo. -Per mio parere-

Problemi correlati