Подтвердить что ты не робот

Javafx 2 клик и двойной щелчок

Я хотел бы узнать, удалось ли обнаружить двойной щелчок в JavaFX 2? и как?

Я хотел бы сделать другое событие между щелчком и двойным щелчком.

Спасибо

4b9b3361

Ответ 1

Да, вы можете обнаружить одиночные, двойные, даже множественные щелчки:

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 используется, чтобы определить, будет ли левая (обычно) кнопка мыши инициировать событие. Прочтите api getClickCount(), чтобы сделать вывод, что, возможно, несколько кликов, кроме одного или двух. Однако мне трудно различать события одиночного и двойного кликов. Поскольку первый щелчок мышью двойного клика также увеличит одно событие.

Ответ 2

Не работает, если вы хотите обрабатывать один клик и двойные щелчки, добавив

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

Результаты в: "Single clicked" всегда запускается.

Ответ 3

Вот еще один фрагмент кода, который можно использовать, если вам нужно различать однократный и двойной щелчок, и в любом случае нужно принять конкретное действие.

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

Ответ 4

Ответ P. Pandey - это самый простой подход, который фактически отличает однократный и двойной щелчок, но для меня это не сработало. Во-первых, функция currentTimeMillis уже возвращает миллисекунды, поэтому деление на 1000 не кажется необходимым. Следующая версия работала для меня более последовательно.

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

Ответ 5

Вот как я реализовал двойной клик

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

}

Ответ 6

Придерживаясь лямбда-выражений Java SE 8, выглядело бы примерно так:

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

Как только вы привыкнете к лямбда-выражениям, они станут более понятными, чем метод создания и переопределения исходного класса (x). -In мой opinion-

Ответ 7

Поскольку по умолчанию невозможно различить одиночный и двойной щелчок, мы используем следующий подход:

По одному щелчку мы оборачиваем операцию по одному щелчку в сбрасываемом исполняемом файле. Этот исполняемый файл ожидает некоторое время (т.е. SINGLE_CLICK_DELAY), прежде чем будет выполнен.

В то же время, если происходит второй щелчок, т.е. двойной щелчок, операция однократного нажатия прерывается и выполняется только операция двойного щелчка.

Таким образом, выполняется операция с одним или двумя щелчками, но не с обеими.


Ниже приведен полный код. Чтобы использовать его, нужно заменить только три строки TODO на нужные обработчики.

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

Ответ 8

Решение с использованием PauseTransition:

PauseTransition singlePressPause = new PauseTransition(Duration.millis(500));
singlePressPause.setOnFinished(e -> {
    // single press
});

node.setOnMousePressed(e -> {

    if (e.isPrimaryButtonDown() && e.getClickCount() == 1) {
        singlePressPause.play();
    }

    if (e.isPrimaryButtonDown() && e.getClickCount() == 2) {
        singlePressPause.stop();
        // double press
    }
});