<Swing Dev> BasicButtonListener surprising behaviour

Pavel Porvatov pavel.porvatov at oracle.com
Sat Apr 9 07:33:34 UTC 2011


Hi Jean,

I don't see any problems with the code and it works as expected (and 
documented). If a user clicks the left mouse button very fast and the 
MultiClickThreshhold value is big enough than only first action event on 
the button occurs and other clicks are discarded. I attached a test and 
it works fine for me.

I see what you'd expect. I don't have ideas why the current behavior is 
implemented in such way, may be other people will help you.. Anyway it's 
impossible to change the functionality because of backward compatibility.

Regards, Pavel
> Hi,
>
> I came across this some time ago while working on a project using JDK 
> 6. I found the behaviour odd and looked at the source code for JDK 7 
> and was able find the code that was responsible for the odd behaviour.
>
> Of course, it may well be intended behaviour, but to me it was surprising.
>
> I have looked at the most recent release of the JDK 7 source code, and 
> the behaviour is still as it was.
>
> I call your attention to the mousePressed(MouseEvent e) function 
> present at line 213 of BasicButtonListener (javax.swing.plaf.basic) :
>
> public void mousePressed(MouseEvent e) {
>        if (SwingUtilities.isLeftMouseButton(e) ) {
>           AbstractButton b = (AbstractButton) e.getSource();
>
>           if(b.contains(e.getX(), e.getY())) {
>  long multiClickThreshhold = b.getMultiClickThreshhold();
>               long lastTime = lastPressedTimestamp;
>               long currentTime = lastPressedTimestamp = e.getWhen();
>               if (lastTime != -1 && currentTime - lastTime < 
> multiClickThreshhold) {
>                   shouldDiscardRelease = true;
>                   return;
>               }
>
>              ButtonModel model = b.getModel();
>              if (!model.isEnabled()) {
>                 // Disabled buttons ignore all input...
>                 return;
>              }
>              if (!model.isArmed()) {
>                 // button not armed, should be
>                 model.setArmed(true);
>              }
>              model.setPressed(true);
>              if(!b.hasFocus() && b.isRequestFocusEnabled()) {
>                 b.requestFocus();
>              }
>           }
>        }
>     }
>
> This behaviour seems odd to me because if one sets the threshold to 
> 0.6 seconds for instance, and the user clicks every 0.5 seconds for 
> whatever length of time, no mouse clicked event while be generated and 
> application code while never get notified of any mouse click event. 
> The behaviour I expected from setting the threshold in the JButton 
> class was that the second click from the user would generate an event. 
> Indeed, this seems like it would be the generally desired behaviours 
> and appears to be the documented behaviour :
>
> Copied from the JDK 7 API documentation :
>
> Sets the amount of time (in milliseconds) required between mouse press 
> events for the button to generate the corresponding action events. 
> After the initial mouse press occurs (and action event generated) any 
> subsequent mouse press events which occur on intervals less than the 
> threshhold will be ignored and no corresponding action event 
> generated. By default the threshhold is 0, which means that for each 
> mouse press, an action event will be fired, no matter how quickly the 
> mouse clicks occur. In buttons where this behavior is not desirable 
> (for example, the "OK" button in a dialog), this threshhold should be 
> set to an appropriate positive value.
>
> Could someone let me know if I am missing something or if this is 
> expected behaviour and why.
>
> Jean-Remi Desjardins
>
> n.b. The code to deliver the behaviour I expect would be something 
> like this (but I haven't bothered compiling this so no promises) :
>
> public void mousePressed(MouseEvent e) {
>        if (SwingUtilities.isLeftMouseButton(e) ) {
>           AbstractButton b = (AbstractButton) e.getSource();
>
>           if(b.contains(e.getX(), e.getY())) {
>  long multiClickThreshhold = b.getMultiClickThreshhold();
>               long lastTime = lastPressedTimestamp;
>               long currentTime = e.getWhen();
>               if (lastTime != -1 && currentTime - lastTime < 
> multiClickThreshhold) {
>                   shouldDiscardRelease = true;
>                   return;
>               }
> else {
>                   lastPressedTimestamp = currentTime;
>               }
>
>              ButtonModel model = b.getModel();
>              if (!model.isEnabled()) {
>                 // Disabled buttons ignore all input...
>                 return;
>              }
>              if (!model.isArmed()) {
>                 // button not armed, should be
>                 model.setArmed(true);
>              }
>              model.setPressed(true);
>              if(!b.hasFocus() && b.isRequestFocusEnabled()) {
>                 b.requestFocus();
>              }
>           }
>        }
>     }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110409/a88c4996/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MultiClickThreshholdTest.java
Type: text/java
Size: 916 bytes
Desc: not available
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110409/a88c4996/MultiClickThreshholdTest.java>


More information about the swing-dev mailing list