怎样才能让JButton在按下时重复动作?

时间:2008-11-21 18:17:57

标签: java swing event-listener

我正在使用Swing创建一个触摸屏应用程序,并请求更改其中一个按钮,以便在按下按钮时它的行为类似于键盘。
(首先,我不确定触摸屏是否允许用户“按住”按钮,但假装他们现在可以使用)

我打算在调用mousePressed时开始循环,然后在调用mouseReleased时结束循环。这将涉及启动一个线程并且必须处理同步以及invokeLater()以在EventQueue上恢复事件。

有一种非常简单的方法可以做我想要的吗?我希望我没有看到API来做它。

4 个答案:

答案 0 :(得分:9)

javax.swing.Timer是你的朋友。并here's an article提供更多信息。

答案 1 :(得分:5)

我会这样做:

  • 收听mousePressed并安排稍后启动java.util.Timer。
  • 计时器执行操作并将其自身设置为再次安排。
  • 收听mouseReleased取消定时器。

答案 2 :(得分:0)

我选择了java.swing.Timer,因为它会自动回发到Swing EventQueue,这就是我要找的东西。谢谢你的帮助。

答案 3 :(得分: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();
        }
    }

}

它也加速了。

希望有所帮助。