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
_は、左(通常)マウスボタンがイベントをトリガーするかどうかを決定するために使用されます。 getClickCount()
のAPIを読んで、シングルまたはダブル以外の複数のクリックカウントがある可能性があると結論付けてください。ただし、シングルクリックイベントとダブルクリックイベントを区別することは困難です。ダブルクリックの最初のクリックカウントによって、1つのイベントも発生するためです。
シングルクリックとダブルクリックを区別し、どちらの場合でも特定のアクションを実行する必要がある場合に使用できる別のコードを次に示します。
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の反応は、実際にシングルクリックとダブルクリックを区別する最も単純なアプローチですが、私にはうまくいきませんでした。 1つは、関数「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
)実行される前。
その間に、2回目のクリック、つまりダブルクリックが発生した場合、シングルクリック操作は中止され、ダブルクリック操作のみが実行されます。
この方法では、シングルクリックまたはダブルクリック操作が実行されますが、両方は実行されません。
完全なコードは次のとおりです。これを使用するには、3つの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;
}
});
}