Note that there are some explanatory texts on larger screens.

plurals
  1. POJava swing hold buttons
    text
    copied!<p>I'm trying to create a subclass of JButton or AbstractButton that would call specified .actionPerformed as long as the mouse is held down on the button.</p> <p>So far I was thinking of extending JButton, adding a mouse listener on creation (inside constructor) and calling actionPerformed while the mouse is down. So far i came up with that but I was wondwering if I was on the right track and if so, how to correctly implement the "held down" logic.</p> <pre><code>package components; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JButton; public class HoldButton extends JButton { private class HeldDownMouseListener implements MouseListener { private boolean mouseIsHeldDown; private HoldButton button; private long millis; public HeldDownMouseListener(HoldButton button, long millis) { this.button = button; this.millis = millis; } @Override public void mouseClicked(MouseEvent arg0) { } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { mouseIsHeldDown = true; // This should be run in a sub thread? // while (mouseIsHeldDown) { // button.fireActionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "heldDown")); // try { // Thread.sleep(millis); // } catch (InterruptedException e) { // e.printStackTrace(); // continue; // } // } } @Override public void mouseReleased(MouseEvent arg0) { mouseIsHeldDown = false; } } public HoldButton() { addHeldDownMouseListener(); } public HoldButton(Icon icon) { super(icon); addHeldDownMouseListener(); } public HoldButton(String text) { super(text); addHeldDownMouseListener(); } public HoldButton(Action a) { super(a); addHeldDownMouseListener(); } private void addHeldDownMouseListener() { addMouseListener(new HeldDownMouseListener(this, 300)); } } </code></pre> <p>Thanks a lot for your time.</p> <p>edit: Choosing the Timer method I came up with a working implementation:</p> <pre><code>package components; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Timer; import java.util.TimerTask; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JButton; public class HoldButton extends JButton { private static final long serialVersionUID = 1L; public static final long CLICK_LAG = 300; public static final long INITIAL_FIRE_DELAY = 500; public static final double FIRE_DELAY_STEP_MULTIPLIER = 25; public static final long MIN_FIRE_DELAY = 100; private class HeldDownMouseListener implements MouseListener { private class HeldDownCheckerTask extends TimerTask { private HeldDownMouseListener listener; public HeldDownCheckerTask(HeldDownMouseListener listener) { this.listener = listener; } @Override public void run() { long delay = INITIAL_FIRE_DELAY; while (listener.isMouseHeldDownOnButton()) { listener.fireMouseHeldDown(); try { Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } if (delay &gt; MIN_FIRE_DELAY) { final long decrease = Math.round(FIRE_DELAY_STEP_MULTIPLIER * Math.pow(INITIAL_FIRE_DELAY / delay, 2)); delay = Math.max(delay - decrease, MIN_FIRE_DELAY); } } } } private boolean mouseIsHeldDown; private boolean mouseIsOnButton; private HoldButton button; private Timer timer; public HeldDownMouseListener(HoldButton button) { this.button = button; } public boolean isMouseHeldDownOnButton() { return mouseIsHeldDown &amp;&amp; mouseIsOnButton; } private void cancelTimer() { if (timer != null) { timer.cancel(); timer = null; } } private void fireMouseHeldDown() { button.fireActionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "heldDown")); } @Override public void mouseClicked(MouseEvent arg0) { cancelTimer(); } @Override public void mouseEntered(MouseEvent arg0) { mouseIsOnButton = true; } @Override public void mouseExited(MouseEvent arg0) { mouseIsOnButton = false; } @Override public void mousePressed(MouseEvent arg0) { cancelTimer(); mouseIsHeldDown = true; timer = new Timer(); timer.schedule(new HeldDownCheckerTask(this), CLICK_LAG); } @Override public void mouseReleased(MouseEvent arg0) { mouseIsHeldDown = false; } } public HoldButton() { addHeldDownMouseListener(); } public HoldButton(Icon icon) { super(icon); addHeldDownMouseListener(); } public HoldButton(String text) { super(text); addHeldDownMouseListener(); } public HoldButton(Action a) { super(a); addHeldDownMouseListener(); } private void addHeldDownMouseListener() { addMouseListener(new HeldDownMouseListener(this)); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload