2017-08-07 4 views
0

HINWEIS: Mein Englisch ist nicht das Beste Also bitte nicht zu viel Grammatik Fehler.Java; Wie bekomme ich die Variable außerhalb des Action-Listeners?

Hey da, Java Anfänger hier, Wie auch immer, ich habe mein CPS Tester Programm programmiert, nur als erstes Mini Programm. Wie auch immer, diese Frage gestellt haben, bevor aber, Ich brauche eine Variable außerhalb eines Action Code erhalten:

public static void startB() { 
Font f = new Font(null, Font.BOLD , 0); 

    Font size = f.deriveFont(20f); 

    JLabel text = new JLabel(""); 
    text.setPreferredSize(new Dimension(250,250)); 
    text.setFont(size); 

    JButton b = new JButton(); 
    JFrame cps = new JFrame("CLICK"); 
    cps.setPreferredSize(new Dimension(400,400)); 
    cps.setLocationRelativeTo(null); 
    cps.setLayout(new FlowLayout()); 
    b.setText("<html> CLICK ME <br> As much as you can! <html> "); 
    cps.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    cps.getContentPane().add(b , BorderLayout.CENTER); 
    cps.getContentPane().add(text, BorderLayout.CENTER); 
    cps.pack(); 
    cps.setVisible(true); 

    text.setText("<html> Starting in... <br> 3<html>"); 
    try { 
     TimeUnit.SECONDS.sleep((long)1.0); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    text.setText("<html> Starting in... <br> 2<html>"); 
    try { 
     TimeUnit.SECONDS.sleep((long)1.0); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    text.setText("<html> Starting in... <br> 1<html>"); 
    try { 
     TimeUnit.SECONDS.sleep((long)1.0); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    text.setText("<html> CLICK! <html>"); 
    b.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      double clicks = 0; 
      clicks++; 
      // How to get Clicks variable out of the actionListener? 
     } 
    }); 
    try { 
     TimeUnit.SECONDS.sleep((long)10.0); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    //I need get the Clicks Variable to here. 
} 

Wenn Sie mir helfen können, sich auf die Post antworten Bitte. Vielen Dank.

Antwort

3

Hier erstellen Sie eine anonyme Klasse von ActionListener:

b.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
    double clicks = 0; 
    clicks++; 
     // How to get Clicks variable out of the actionListener? 

    } 
    }); 

Und Sie erklärte die clicks Variable in seinem Inneren.
Sie könnten clicks in der äußeren Klasse deklarieren, aber es wird nicht funktionieren, da der Compiler erwartet, dass clicksfinal sein. Was mit Ihrer Verwendung nicht vereinbar ist: Sie mutieren es innerhalb actionPerformed().

Eine Alternative Ihre Notwendigkeit zu erreichen, ist eine nicht anonyme Implementierung von ActionListener schaffen, in dem Sie clicks als ein Feld gespeichert werden und einen Getter liefern den Wert um es abzurufen.

Es könnte eine innere Klasse sein:

private static class MyActionListener implements ActionListener { 

    private double clicks; 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     clicks++; 
    } 

    public double getClicks() { 
     return clicks; 
    } 

} 

Und Sie es auf diese Weise nutzen könnten:

MyActionListener actionListener = new MyActionListener(); 
myComponent.addActionListener(actionListener); 
... 
// later retrieve clicks 
double clicks = actionListener.getClicks(); 
1

Sie können nur final Variablen Ihrer äußeren Klasse zugreifen in einer anonymen inneren Klasse. Aber wie der Modifikator final schlägt vor, der Wert einer solchen Variablen kann nicht mehr einmal nach der Zuweisung geändert werden.

Um dies zu umgehen Sie eine AtomicInteger anstelle eines einfachen int oder double verwenden könnte die Klicks zu speichern und diese final Variable außerhalb Ihrer Aktion Hörer erklären:

final AtomicInteger clicks = new AtomicInteger(0); 
b.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     clicks.incrementAndGet(); 
    } 
} 
clicks.get(); // will return the desired number of invocations of actionPerformed 

diese Weise können Sie immer noch eine anonyme Klasse verwenden können, für Ihre Aktion Listener.

Es wäre jedoch besser - aus einer Code-Stil-Perspektive - eine benannte Klasse zu definieren und einen Getter für die Klickanzahl bereitzustellen, wie in der anderen Antwort vorgeschlagen.

+0

@davidxxx Ich habe nur eine Antwort auf die Frage und bereits erwähnt, dass es nicht der beste Weg ist, es zu tun. – dpr

+0

Ah sorry ich schlecht lesen. Ich habe das Gegenteil verstanden. Es ist gut als Alternative mit dieser Warnung. – davidxxx

Verwandte Themen