java - propiedades - ¿Cómo puedo hacer un swing JButton repite su acción cuando se mantiene presionada?
propiedades jbutton java (4)
Estoy creando una aplicación de pantalla táctil usando Swing y solicito cambiar uno de los botones para que se comporte como un teclado cuando se mantiene presionado el botón.
(En primer lugar, no estoy seguro de que la pantalla táctil permita al usuario "mantener presionado" el botón, pero pretende que puede hacerlo por el momento)
Iba a seguir el camino de iniciar un ciclo cuando se llamaba mousePressed
y luego se terminaba el ciclo cuando se llamaba mouseReleased
. Esto implicará comenzar un hilo y tener que lidiar con la sincronización, así como con invokeLater()
para volver a los eventos en el EventQueue
.
¿Hay una manera muy simple de hacer lo que quiero? Espero no ver la API para hacerlo.
Fui con el java.swing.Timer ya que se publicará automáticamente en Swing EventQueue y eso es lo que estoy buscando. Gracias por la ayuda.
Lo haría así:
- Escuche mousePressed y programe un java.util.Timer para que se inicie en otro momento.
- El temporizador realiza la acción y se establece para programar nuevamente.
- Escucha mouseReleased para cancelar el temporizador.
javax.swing.Timer es tu amigo. Y aquí hay un artículo con más información.
Así es cómo puedes hacerlo subclasificando 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();
}
}
}
Acelera también
Espero que ayude.