Javafx 2 클릭 및 더블 클릭
JavaFX 2에서 두 번 클릭을 감지 할 수 있는지 알고 싶습니다. 그리고 어떻게 ?
클릭과 더블 클릭 사이에 다른 이벤트를 만들고 싶습니다.
감사
예, 한 번, 두 번 또는 여러 번의 클릭을 감지 할 수 있습니다.
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()
단일 또는 이중 이외의 여러 클릭 수가있을 수 있다는 결론을 내립니다. 그러나 단일 클릭 이벤트와 더블 클릭 이벤트를 구별하기가 어렵습니다. 더블 클릭의 첫 번째 클릭 횟수도 단일 이벤트를 발생시키기 때문입니다.
다음은 한 번의 클릭과 두 번의 클릭을 구분하고 두 경우 모두 특정 작업을 수행해야하는 경우 사용할 수있는 또 다른 코드입니다.
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.");
}
}
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...
}
두 번 클릭을 구현 한 방법은 다음과 같습니다.
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);
}
Java SE 8 람다 식을 고수하면 다음과 같습니다.
node.setOnMouseClicked(event -> {
if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
handleSomeAction();
}
});
람다 식에 익숙해지면 원래 클래스 인스턴스화 및 (x) 메서드를 재정의하는 것보다 더 이해하기 쉬워집니다. -내 생각 엔-
기본적으로 한 번 클릭과 두 번 클릭을 구분할 수 없으므로 다음 접근 방식을 사용합니다.
한 번 클릭하면 중단 가능한 실행 파일에서 단일 클릭 작업을 래핑합니다. 이 실행 파일 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;
}
});
}
ReferenceURL : https://stackoverflow.com/questions/10949461/javafx-2-click-and-double-click
'IT이야기' 카테고리의 다른 글
비트 엔디안이 비트 필드에서 문제가 되는 이유 (0) | 2021.03.25 |
---|---|
java.lang.RuntimeException : Result ResultInfo {who = null, request = 1888, result = 0, data = null} 에러 (0) | 2021.03.24 |
Google 크롬 비활성화 화면 눈금자 (0) | 2021.03.24 |
ScrollView의 MapFragment (0) | 2021.03.24 |
jacoco.exec 보고서 사용 방법 (0) | 2021.03.24 |