Créer un compteur pour les événements ActionListener
-
28-09-2019 - |
Question
J'ai un JButton dans mon programme, défini comme suit (plus ou moins)
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++;
}
}
);
}
}
Je veux être en mesure de compter le nombre de fois que le bouton est cliqué. Le problème est, je ne peux pas déclarer un compteur puis incrémenter après l'appel à .doSomething (), parce que la variable doit être définitive pour moi de faire référence dans la classe interne.
Est-il possible de le faire, autre que créer ma propre classe wrapper avec sa propre méthode .increment ()?
La solution
En fonction de la situation de filetage, vous pouvez déplacer la variable à la classe englobante. Mais cela peut aller très mal si vous invoquez foo()
plusieurs fois, car cela va utiliser le même compteur.
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++;
}
}
);
}
}
Autres conseils
Vous pouvez déplacer votre comptoir de l'extérieur du ActionListener
à l'intérieur, ce qui en fait un membre de l'auditeur.
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++;
}
});
}
}
Comme suggéré par @akf, le compteur peut être un membre d'une classe imbriquée, à partir de laquelle les membres de l'instance d'enceinte sont visibles. Cet exemple met en œuvre ActionListener
d'étendre 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();
}
});
}
}