wake-up-neo.com

Javafx 2 klicken und doppelklicken

Ich würde gerne wissen, ob es möglich war, den Doppelklick in JavaFX 2 zu erkennen. und wie ?

Ich möchte ein anderes Ereignis zwischen einem Klick und einem Doppelklick machen.

Vielen Dank

53
Delkaspo

Ja, Sie können einzelne, doppelte oder sogar mehrere Klicks erkennen:

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 Wird verwendet, um zu bestimmen, ob die linke (allgemeine) Maustaste das Ereignis auslöst. Lesen Sie die API von getClickCount(), um zu dem Schluss zu gelangen, dass es möglicherweise mehrere andere Klickzahlen als einfach oder doppelt gibt. Es fällt mir jedoch schwer, zwischen Einzel- und Doppelklickereignissen zu unterscheiden. Da die Anzahl der ersten Klicks des Doppelklicks auch ein einzelnes Ereignis auslöst.

87
Uluk Biy

Hier ist ein weiterer Code, der verwendet werden kann, wenn Sie zwischen einem Einzel- und einem Doppelklick unterscheiden und in beiden Fällen eine bestimmte Aktion ausführen müssen.

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.");
    }
}
7
mipa

Die Antwort von P. Pandey ist der einfachste Ansatz, der tatsächlich zwischen Einfach- und Doppelklick unterscheidet, aber bei mir hat es nicht funktioniert. Zum einen gibt die Funktion "currentTimeMillis" bereits Millisekunden zurück, sodass eine Division durch 1000 nicht erforderlich zu sein scheint. Die folgende Version funktionierte für mich konsistenter.

 @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...   
}
3
parityerror

So habe ich Doppelklick implementiert

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); 

}

2
P. Pandey

Das Einhalten von Java SE 8 Lambda-Ausdrücken würde ungefähr so ​​aussehen:

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

Sobald Sie sich an Lambda-Ausdrücke gewöhnt haben, werden diese verständlicher als die ursprüngliche Methode zur Instanziierung und zum Überschreiben von (x). -Meiner Meinung nach-

1

Da standardmäßig nicht zwischen Einfachklick und Doppelklick unterschieden werden kann, verwenden wir den folgenden Ansatz:

Beim Ein-Klick-Vorgang wird der Ein-Klick-Vorgang in eine abbrechbare ausführbare Datei gewickelt. Dieses ausführbare Programm wartet eine gewisse Zeit (d. H. SINGLE_CLICK_DELAY) vor der Ausführung.

Wenn in der Zwischenzeit ein zweiter Klick, d. H. Ein Doppelklick, auftritt, wird die Einzelklickoperation abgebrochen und nur die Doppelklickoperation ausgeführt.

Auf diese Weise wird entweder der Einfachklick oder der Doppelklick-Vorgang ausgeführt, jedoch niemals beides.


Es folgt der vollständige Code. Um es zu benutzen, müssen nur die drei TODO Zeilen durch die gewünschten Handler ersetzt werden.

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;
        }
    });
}
1
Markus Weninger