Crear un contador de eventos ActionListener
-
28-09-2019 - |
Pregunta
Tengo un JButton en mi programa, que se define de la siguiente manera (más o menos)
public class MyTester{
public static void main(String[] args)
{
int counter = 0;
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
startButton.doSomething()
counter++;
}
}
);
}
}
Quiero ser capaz de contar el número de veces que se hace clic en el botón. El problema es que no se puede declarar un mostrador y luego se incrementará después de la llamada a .doSomething (), ya que la variable tiene que ser definitiva para mí hacer referencia a ella en la clase interna.
¿Hay una manera de hacer esto, aparte de la creación de mi propia clase contenedora con su propio método .increment ()?
Solución
Dependiendo de la situación de roscado, se puede mover la variable a la clase envolvente. Pero esto puede ir muy mal si se invoca foo()
varias veces, ya que utilizará el mismo contador.
public class MyClass {
// Notice the placement outside the main()
private static int counter = 0;
public static void main(String[] args) {
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
startButton.doSomething()
//do some more stuff
counter++;
}
}
);
}
}
Otros consejos
Puede mover su contador desde fuera del ActionListener
al interior, por lo que es un miembro del oyente.
public class MyTester {
public static void main(String[] args) {
final JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
int counter; // you make one per listener
public void actionPerformed(ActionEvent e) {
startButton.doSomething();
counter++;
}
});
}
}
Como se sugiere por @akf, el contador puede ser un miembro de una clase anidada, de la que los miembros de la instancia de encerramiento son visibles. Este ejemplo implementos ActionListener
extender AbstractAction
.
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/questions/4290117 */
public class ClickCount extends JPanel {
private JButton button = new JButton(new ClickHandler("Click"));
private JLabel label = new JLabel("0");
public ClickCount() {
this.add(button);
this.add(label);
}
private class ClickHandler extends AbstractAction {
int counter;
public ClickHandler(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(++counter));
}
}
private void display() {
JFrame f = new JFrame("ClickCount");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ClickCount().display();
}
});
}
}