2008-11-21 19 views
5

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.
(Antes que nada, no estoy seguro de que la pantalla táctil permita al usuario "mantener presionado" el botón, pero pretendo que pueden hacerlo por ahora)¿Cómo puedo hacer un swing JButton repite su acción cuando se mantiene presionada?

Iba a seguir el camino de comenzar un cuando se llamó a mousePressed y luego se finalizó el ciclo cuando se llamó a mouseReleased. Esto implicará iniciar un hilo y tener que lidiar con la sincronización, así como invokeLater() para recuperar los eventos en el EventQueue.

¿Hay una manera muy simple de hacer lo que quiero? Espero no ver la API para hacerlo.

+0

No hay una manera simple. Creo que lo que trazaste con un hilo haciendo duermes cronometrados y sondeando el botón es la única manera. –

Respuesta

5

lo haría así:

  • Escucha mousePressed y programar una java.util.Timer para ser lanzado en un momento posterior.
  • El temporizador realiza la acción y se establece a programar de nuevo.
  • Escuchar mouseReleased para cancelar el temporizador.
0

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.

0

Así es como puede hacerlo creando una subclase 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.

Cuestiones relacionadas