how do I detect double clic in JavaFX ?
14 December 2008I am currently confronted to this problem: detect double clic in JavaFX.
What I want to do :
When you make a double click, you click twice, so this is what will occurs:
- The first click will be catch and the simpleClickAction will be done (because clickCount != 2) ---> I don't want it : this is a double click and I want the simpleClick action to be perform only on single click !,
- The second click will be catch and the double clickAction will be done --> This is what I want.
So what I want is :
- To perform a simpleClick action on single click only (and not those which are part of a double click),
- To perform a double click action on doubleClick only.
How I did it
In swing this is done by using timer. So why not do the same with a Timeline in JavaFX.
This is how I solve the problem (the code is also linked to this post) :
/* * Main.fx * * Created on 14 déc. 2008, 15:10:59 */ package fr.antoinj.detectdoubleclick; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.scene.Group; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.Scene; import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; import javafx.stage.Stage; /** * @author Jonathan */ var textContent = "Nothing detected"; var clickInTheLastFewMoments: Boolean = false; var lastLauchedTimeLine:Timeline ; var clickedTimeLine: Timeline= Timeline { keyFrames: [KeyFrame { time: 0s action:function(){ lastLauchedTimeLine.stop(); clickInTheLastFewMoments=true; } } , KeyFrame { time: 200ms action:function(){ clickInTheLastFewMoments=false; simpleClick(); } } ] } function simpleClick(){ textContent="Simple click detected"; } function doubleClick(){ textContent="Double click detected"; } Stage { title: "How I detect doubleClick in JavaFX" width: 400 height: 80 scene: Scene { content: Group{ content: [Rectangle { x: 75, y: 0 width: 400, height: 50 fill: Color.BLACK onMouseClicked: function(me:MouseEvent){ if(clickInTheLastFewMoments){ clickInTheLastFewMoments=false; clickedTimeLine.stop(); doubleClick(); }else { clickedTimeLine.playFromStart(); } } }, Rectangle { x: 0, y: 0 width: 75 height: 50 fill: Color.ORANGERED onMouseClicked: function(me:MouseEvent){ textContent="Nothing detected"; } }, Text { font: Font.font("Verdana",FontWeight.BOLD,12) fill: Color.BLACK x: 8 y: 25 content: "REFRESH" } , Text { font: Font.font("Verdana",FontWeight.MEDIUM,24) fill:Color.PINK x: 80 y: 30 content: bind textContent; }] } } }
You can also see a demo of this javaFx apps here : link to the demo page or launch this JNLP : link to the JNLP
My question is : Do you have a better way to do this ?
- By JonathanANTOINE@falsemail.com
- - JavaFX
- - Tags :
Comments
why not use the 'clickCount' prperty of the javafx.scene.input.MouseEvent class
pavan:
Hey,
I can use this property but if I do this the simpleClick action will be done each time. %%%
The behavior of the click event is execute the function with clickCount=1 then execute the function again with clickCount = 2. %%%
So if you want to execute a differente function on simple click and on double click, you can't only do this.
+ + +
That is not right, just do:
if(ev.clickCount == 2){
// Process Double Click
} else {
// Process Single Click
}
Or:
if(ev.clickCount >= 2){
// Process Double Click
} else {
// Process Single Click
}
The time is auto-restarted.
Ps: Edited by Jonathan : I grouped together your 2 comments.
@Roger Padilla : If I do this, the simpleClick action will be done each time:
You does not understand, that is an "if-else", so, if it goes inside the 'if' it will never goes inside the 'else' at the same time. In the below code, if it is a double click it will never read as a single click and vice-versa.
if(ev.clickCount >= 2){
// Process Double Click
} else {
// Process Single Click
}
@Roger Padilla :
I got the point but :
When you make a double click, you click twice, so this is what will occurs:
onMouseClicked: function(me:MouseEvent){
if(me.clickCount >= 2){
doubleClick();
} else {
simpleClick();
}
}
@Roger Padilla :
By doing this you will perform simpleClick each time you will make a double click: on the first click of your double click...@"What I want is :
* To perform a simpleClick action on single click only (and not those which are part of a double click),
* To perform a double click action on doubleClick only."
That is just what the "if-else" approach does
This will works for you:
onMouseClicked: function(me:MouseEvent){
if(me.clickCount >= 2){
doubleClick();
} else {
simpleClick();
}
}
@"By doing this you will perform simpleClick each time you will make a double click: on the first click of your double..."
Not because of "clickCount" is a sum value which is controlled in background.
You don't need to do that in Java/Swing neither in JavaFX.
@Roger Padilla : You will sure perform the doubleclick action but also the firstClick action: I don't want this !
I let you check this little app : http://www.lexique-du-net.com/javafx/ClickApp.zip
This app just add "simple" or "double" to a text when click are done using your code...
@Mauro : The proble seems to be the same with Swing :
Ohh yes!, You are right and I'm wrong, my fail, sorry. That is a not implemented feature.
You have the solution
@Roger Padilla :
Ouf, I was thinking I was mad ^^Absolutely Your are not, the mad was Me
I would point out that double-click functionality should always be an extension of the single-click functionality. That is how user interfaces are designed, and you shouldn't try to avoid it. Users will expect a double-click to perform the single-click functionality, and then the double-click extension. If you violate that expectation, users will be surprised and confused. The principle of "least surprise" is very important in user interfaces.
@David Karr : I fully agree with you ^^ !