How can I get Swing JButton to repeat an action when it is held?

I am creating a touchscreen application using Swing and have a request to change one of the buttons so that it behaves like a keyboard when the button is held down.
(First of all, I'm not sure that the touch screen will allow the user to “hold” the button, but pretends that they can do it)

I was about to go down the path of starting the cycle when it was called mousePressed, and then finished the cycle when it was called mouseReleased. This will include starting a thread and having to deal with synchronization as well invokeLater(), in order to return events to EventQueue.

Is there an easy way to do what I want? Hope I just don't see the API for this.

+5
source share
4 answers

javax.swing.Timer is your friend. And here is an article with more information.

+9
source

I would do it like this:

  • Listen to mousePressed and schedule java.util.Timer to start later.
  • The timer will execute the action and tune in to planning again.
  • Listen to mouseReleased to cancel the timer.
+5
source

java.swing.Timer, Swing EventQueue, , . .

0

, JButton:

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.SwingUtilities;

public class TypomaticButton extends JButton implements MouseListener {
    private boolean autotype = false;
    private static Thread theThread = null;
    private String myName = "unknown";
    private int 
        speed = 150, 
        wait = 300,
        decrement = (wait - speed) / 10; 

    TypomaticButton(Action action){
        super(action);
        myName = action.getValue(Action.NAME).toString();
        addMouseListener(this);
    }

    TypomaticButton(String text){
        super(text);
        setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));

        myName = text;
        addMouseListener(this);
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {}

    @Override
    public void mouseEntered(MouseEvent arg0) { }

    @Override
    public void mouseExited(MouseEvent arg0) {  }

    @Override
    public void mousePressed(MouseEvent arg0) {
        autotype = true;
        theThread = new Thread(new Runnable() { // do it on a new thread so we don't block the UI thread
            @Override
            public void run() {
                for (int i = 10000; i > 0 && autotype; i--) { // don't go on for ever
                    try {
                        Thread.sleep(wait);     // wait awhile
                    } catch (InterruptedException e) {
                        break;
                    }
                    if(wait != speed){
                        wait = wait - decrement;        // gradually accelerate to top speed
                        if(wait < speed)
                            wait = speed;
                    }
                    SwingUtilities.invokeLater(new Runnable() { // run this bit on the UI thread
                        public void run() {
                            if(!autotype)   // it may have been stopped meanwhile
                                return;
                            ActionListener[] als = getActionListeners();
                            for(ActionListener al : als){   // distribute to all listeners
                                ActionEvent aevent = new ActionEvent(getClass(), 0, myName);
                                al.actionPerformed(aevent);
                            }
                        }
                    });
                }
                autotype = false;
            }
        });
        theThread.start();
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        autotype = false;
        wait = 300;
    }

    void speed(int millisecs){
        speed = millisecs;
        decrement = (wait - speed) / 10; 
    }

    void stop(){
        autotype = false;
        if(theThread != null){
            theThread.interrupt();
        }
    }

}

.

, .

0

All Articles