Frage Wie kann ich einen Swing-JButton wiederholen, wenn er gedrückt gehalten wird?


Ich erstelle eine Touch-Screen-Anwendung mit Swing und habe eine Aufforderung, eine der Tasten zu ändern, so dass sie sich wie eine Tastatur verhält, wenn die Taste gedrückt gehalten wird.
(Zuallererst bin ich mir nicht sicher, ob der Touchscreen es dem Benutzer erlauben wird, den Knopf "niederzuhalten", aber so zu tun, als ob er das jetzt kann)

Ich wollte den Weg machen, eine Schleife zu beginnen mousePressed wurde aufgerufen und dann die Schleife beendet, wenn mouseReleased hieß. Dies beinhaltet das Starten eines Threads und das Erledigen der Synchronisation invokeLater() um die Ereignisse wieder auf die Beine zu stellen EventQueue.

Gibt es eine sehr einfache Möglichkeit, das zu tun, was ich will? Ich hoffe, ich sehe die API nicht, um das zu tun.


5
2017-11-21 18:17


Ursprung


Antworten:


javax.swing.Timer ist dein Freund. Und Hier ist ein Artikel mit etwas mehr Info.


9
2017-11-21 18:24



Ich würde es so machen:

  • Hören Sie mousePressed und planen Sie einen java.util.Timer, der zu einem späteren Zeitpunkt gestartet werden soll.
  • Der Timer führt die Aktion durch und stellt sich selbst auf einen neuen Zeitplan ein.
  • Hören Sie die Maus, um den Timer abzubrechen.

5
2017-11-21 18:25



Ich ging mit dem java.swing.Timer, da es automatisch zurück in die Swing EventQueue posten wird und das ist, was ich suche. Danke für die Hilfe.


0
2017-11-21 18:45



So können Sie das tun, indem Sie JButton unterklassifizieren:

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();
        }
    }

}

Es beschleunigt auch.

Ich hoffe, das hilft.


0
2018-05-11 14:35