Domanda

Ho un JButton nel mio programma, definito come segue (più o meno)

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++;
             }
           }
         );
    }
}

Voglio essere in grado di contare il numero di volte che il pulsante viene premuto. Il problema è, non posso dichiarare un banco e poi incrementarlo dopo la chiamata a .doSomething (), perché la variabile deve essere finale per me per fare riferimento nella classe interna.

C'è un modo per fare questo, altro che creare la mia classe wrapper con un proprio metodo .increment ()?

È stato utile?

Soluzione

A seconda della situazione di threading, è possibile spostare la variabile classe contenitrice. Ma questo può andare molto male se si richiama foo() più volte, dal momento che utilizzerà lo stesso contatore.

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++;

             }
           }
         );    
    }
}

Altri suggerimenti

È possibile spostare il contatore da fuori ActionListener verso l'interno, rendendolo un membro di chi ascolta.

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++;
            }
        });
    }
}

Come suggerisce @akf, il contatore può essere un membro di una classe nidificata, da cui i membri dell'istanza racchiude sono visibili. Questo esempio implementa ActionListener per estendere 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();
            }
        });
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top