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