Javafx 2 клика и двойной клик

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

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

Спасибо

Ответы на вопрос(6)

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

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

}

 17 июн. 2016 г., 10:34
Я думаю, что важно учитывать время, прошедшее между щелчками. Однако я переворачиваю порядок внутри вашего предложения if следующим образом:if( diff>0 && (diff/1000)<=215)

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

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.");
    }
}
Решение Вопроса

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

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

 15 янв. 2013 г., 15:04
@uluk biy Должен ли код обработки одним кликом войти в обработчик onAction и дважды щелкнуть в обработчике мыши?
 15 янв. 2013 г., 15:29
@Anil. Это не должно, но может пойти по этому пути. Я думаю, что общая семантика не повредит, если вы не знаете, что делаете.
 10 июл. 2013 г., 14:18
Нужно ли нам использоватьequals? Я думаю == работает отлично
 15 янв. 2013 г., 13:59
@Anil. Нет, не будет. Кнопка может иметь как обработчики событий onAction, так и onMouseClicked. Эти события будут вызваны, как указано в документации API каждого из них.
 14 янв. 2013 г., 14:35
@uluk biy, как насчет обработчика onAction, который зарегистрирован в моем файле fxml и вызывается при нажатии кнопки. Будет ли этот обработчик конфликтовать с ним?

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

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

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

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

Ниже приведен полный код. Чтобы использовать его, только три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;
        }
    });
}
 21 мар. 2018 г., 11:40
Кроме того, если различие между одинарным и двойным является настолько важным, в UX есть определенный запах: двойной должен увеличивать сингл, а не что-то совершенно другое (но тогда этот комментарий должен касаться вопроса и любого другого ответа & lt ; г & GT;)
 21 мар. 2018 г., 11:34
хм ... как вы получаете SingleClickDelay? Как правило, это настраиваемое значение ОС
 21 мар. 2018 г., 12:48
@kleopatra Относительно вопроса 1: Да, это зависит от ОС. В настоящее время мы имеем фиксированное значение для нашего прототипа, но должны быть разные способы получения этого значения (поиск в реестре Windows и т. Д.) ... По вопросу 2. Я не являюсь разработчиком UX, но я согласен с вами , Мы просто используем его в прототипе. Я не исследовал вопрос OP, он запрашивал разные события для одного и двух щелчков, я опубликовал нашу мысль. : D

Ответ 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...   
}

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

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

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

Ваш ответ на вопрос