Search code examples
javaswingjbuttontouchscreen

How to make Java JButton visually depress with touch screen?


I've got a simple Swing GUI with JButtons being run on a Surface tablet with a touchscreen. The buttons have ActionListeners. When these buttons are clicked from a mouse they visually depress correctly. However when they are tapped on the touchscreen they remain visually the same but still fire off an actionPerformed(). If they are double tapped then they visually depress correctly but fire off 2 actionPerformed()s.

Is there a way to get this button animation change to take place when the button is pressed, rather than clicked? I've tested it and I could use a MouseListener and put all my logic in mouseClicked() but it's not very elegant to ask touchscreen users to double tap a button.


Solution

  • The problem you have is that whereas a mouse click is a compound event, a touch on the screen is not. So there's no way that it can go down at the first event and up again at the second.

    But what you can do, when you receive a touch event, is change the visual state of the button so it looks depressed (using setPressed(true)), then set a timer for 100ms or so, and set the state back to normal when the timer expires (using setPressed(false)).

    Careful with the timer expiration: you need the setPressed(false) to happen on the UI thread. So you'll need to use SwingUtilities.invokeLater() as a wrapper round the second call to setPressed. Or, alternatively, use a javax.swing.Timer as the means of queueing the second call; it takes a delay and an Action, and the Action gets performed on the UI thread.