2012-06-08 83 views

Respuesta

72

Sí se puede detectar individuales, dobles, incluso varios clics:

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 se utiliza para determinar si el botón izquierdo del ratón (normalmente) se activa el evento. Lea la API de getClickCount() para concluir que tal vez haya varios clics adicionales que no sean simples o dobles. Sin embargo, me resulta difícil distinguir entre los eventos de clic simple y doble. Debido a que el primer clic en el doble clic se levantará un solo evento también.

+0

@uluk biy, qué pasa con el controlador onAction que está registrado en mi archivo fxml y se llama cuando se hace clic en el botón. ¿Este controlador chocará con eso? – likejiujitsu

+1

@Anil. No, no lo hará. El botón puede tener controladores de eventos onAction y onMouseClicked. Estos eventos se desencadenarán según lo indique el documento API de cada uno de ellos. –

+0

@uluk biy debería tener un solo clic en el código de manejo entrar en el controlador de Acción y hacer doble clic en el controlador del mouse? – likejiujitsu

16

no funciona si desea manejar un solo clic y doble clics mediante la adición de

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

Resultados en: "Single clicked" siempre se dispara.

2

Aquí es cómo he implementado doble clic

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

Creo que es importante tener en cuenta el tiempo transcurrido entre los clics. Sin embargo, daría la vuelta al orden dentro de tu if-clause como esta: 'if (diff> 0 && (diff/1000) <= 215)' – Wingie

6

Aquí es otra pieza de código que puede ser utilizado si usted tiene que distinguir entre un mono y un doble clic y tienen para tomar una acción específica en cualquier caso.

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 respuesta de P. Pandey es el método más sencillo que en realidad distingue entre sencillo y doble clic, pero no funcionó para mí. Por un lado, la función "currentTimeMillis" ya devuelve milisegundos, por lo que dividirlo por 1000 no parece ser necesario. La versión siguiente funcionó para mí de una manera más consistente.

@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

La adhesión a Java SE expresiones 8 lambda sería algo como esto:

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

Una vez que se acostumbre a las expresiones lambda - terminan siendo más comprensible que la instanciación de la clase original y primordial (x) método. -En mi opinión,

Cuestiones relacionadas