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

¿Fue útil?

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();
            }
        });
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top