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 ()?

Était-ce utile?

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();
            }
        });
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top