Je voudrais savoir s'il était possible de détecter le double-clic dans JavaFX 2? et comment ?
Je voudrais faire un événement différent entre un clic et un double clic.
Merci
Oui, vous pouvez détecter des clics simples, doubles voire multiples:
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
Est utilisé pour déterminer si le bouton gauche (commun) de la souris déclenche l'événement. Lisez l'api de getClickCount()
pour conclure qu'il peut y avoir plusieurs clics autres que simples ou doubles. Cependant, j'ai du mal à distinguer les événements de simple et double clic. Parce que le nombre de premiers clics du double clic augmentera également un seul événement.
Voici un autre morceau de code qui peut être utilisé si vous devez faire la distinction entre un simple et un double-clic et devez prendre une action spécifique dans les deux cas.
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.");
}
}
La réponse de P. Pandey est l'approche la plus simple qui fait la distinction entre le simple et le double clic, mais cela n'a pas fonctionné pour moi. D'une part, la fonction "currentTimeMillis" renvoie déjà des millisecondes, donc la diviser par 1000 ne semble pas nécessaire. La version ci-dessous a fonctionné pour moi d'une manière plus cohérente.
@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...
}
Voici comment j'ai implémenté le double 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);
}
Adhérer à Java SE 8 expressions lambda ressemblerait à ceci:
node.setOnMouseClicked(event -> {
if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
handleSomeAction();
}
});
Une fois que vous vous êtes habitué aux expressions lambda, elles finissent par être plus compréhensibles que l'instanciation de classe d'origine et la méthode prioritaire (x). -À mon avis-
Puisqu'il n'est pas possible de faire la distinction entre un simple clic et un double clic par défaut, nous utilisons l'approche suivante:
En un seul clic, nous encapsulons l'opération en un seul clic dans un exécutable abortable. Cette exécutable attend un certain temps (c'est-à-dire SINGLE_CLICK_DELAY
) avant d'être exécuté.
En attendant, si un deuxième clic, c'est-à-dire un double-clic, se produit, l'opération de simple clic est abandonnée et seule l'opération de double-clic est effectuée.
De cette façon, soit le simple clic o l'opération de double-clic est effectuée, mais jamais les deux.
Voici le code complet. Pour l'utiliser, seules les trois lignes TODO
doivent être remplacées par les gestionnaires voulus.
private static final int SINGLE_CLICK_DELAY = 250;
private ClickRunner latestClickRunner = null;
private class ClickRunner implements Runnable {
private final Runnable onSingleClick;
private boolean aborted = false;
public ClickRunner(Runnable onSingleClick) {
this.onSingleClick = onSingleClick;
}
public void abort() {
this.aborted = true;
}
@Override
public void run() {
try {
Thread.sleep(SINGLE_CLICK_DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!aborted) {
System.out.println("Execute Single Click");
Platform.runLater(() -> onSingleClick.run());
}
}
}
private void init() {
container.setOnMouseClicked(me -> {
switch (me.getButton()) {
case PRIMARY:
if (me.getClickCount() == 1) {
System.out.println("Single Click");
latestClickRunner = new ClickRunner(() -> {
// TODO: Single-left-click operation
});
CompletableFuture.runAsync(latestClickRunner);
}
if (me.getClickCount() == 2) {
System.out.println("Double Click");
if (latestClickRunner != null) {
System.out.println("-> Abort Single Click");
latestClickRunner.abort();
}
// TODO: Double-left-click operation
}
break;
case SECONDARY:
// TODO: Right-click operation
break;
default:
break;
}
});
}