Problem mit ActionListener
-
Hallo,
ich habe folgendes Problem. Ich programmiere ein Spiel um einfach was mehr oder weniger sinnvolles zu programmieren, aber irgendwie komme ich mit dem ActionListener nicht klar. Ich habe immer diesen Fehler:
Spiel.java:54: error: local varialbe p is accessed from within inner class; needs to be declared final
p.setEnabled(true);Kann mir das jemand erklären? Nebenbei bin ich dem Fehler schon öfters begegnet, habe auch danach gesucht (u. a. hier im Forum), aber ich komme einfach nicht mit
den Lösungsvorschlägen zurecht. Wäre nett, wenn mir das jemand relativ einfach
erklären könnteAch und hier ist mein Quelltext:
import javax.swing.*; import java.awt.*; import java.awt.event.*; // Hauptfenster von Klasse JFrame ableiten public class Spiel extends JFrame { // Spielfeld anlegen Spielfeld s_spiel; public static void main(String[] args) { Spiel fenster = new Spiel("blubb"); fenster.pack(); fenster.setSize(800,650); fenster.setVisible(true); fenster.setResizable(false); } // Konstruktor Spiel(String titel) { super(titel); // Layout-Manager setLayout(new FlowLayout()); // Spielfeld erzeugen und einbinden s_spiel = new Spielfeld(); add(s_spiel); // Panel-Container für Schalflächen JPanel panel = new JPanel(); // Gitter mit 2 Zeilen, 1 Spalte panel.setLayout(new GridLayout(2,1,20,20)); //Buttons anlegen und in Panel einbinden JButton p = new JButton("Zug beenden"); JButton s = new JButton("Spiel starten"); panel.add(s); panel.add(p); // Ein Button solange deaktivieren bis Spiel startet p.setEnabled(false); // Panel in Fenster aufnehmen add(panel); // Ereignisbehandlung für Buttons class game implements ActionListener { public void actionPerformed(ActionEvent e) { // Variable um zu erkennen, welcher Button benutzt wurde String label; label = e.getActionCommand(); if(label.equals("Spiel starten")) p.setEnabled(true); } } // Spiel schließen, wenn Fenster geschlossen wird setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } class Spielfeld extends Canvas { // Konstruktor Spielfeld() { // Hintergrund auf schwarz setzen setBackground(Color.black); // Vordergrund bzw. Zeichenfarbe setForeground(Color.green); } // Diese Methode liefert die minimale Größe der Canvas public Dimension getMinimumSize() { return new Dimension(600,600); } // Die Lieblingsgröße wird auf die Minimalgröße gesetzt public Dimension getPreferredSize() { return getMinimumSize(); } } }
-
Also ich habe jetzt den Button als Instanzvariable angelegt und es funktioniert, aber gibt es andere vllcht bessere Lösungen?
Gruß
al3pou
-
... Nein!
Denn du benutzt innerhalb deiner Funktion deiner Anonymen Klasse eine Variable deren Lebenszyklus mit dem Schliessen der geschweiften Klammer endet bzw. Ist das ganze eine Zyklische Referenz. Der Button hat den Listener, der Listener ist der einzige der den Button hat.
Allein aus Wartbarkeits- und Übersichtsgründen solltest du alle Controls (Buttons, Textfelder, etc. ) als Member einer Klasse (am besten der View) halten. Damit du zukünftig eines oder mehrere in irgendeiner Art und weise bearbeiten kannst bzw. alle auf einen Blick ahst..
Was ist denn das Problem dabei? Das ist Objektorientierung!
-
Der König... schrieb:
... Nein!
Doch:
final JButton p = new JButton("Zug beenden");
Danach kann man auf den Button auch in inneren Klassen verwenden. Ob das allerdings eine bessere Lösung ist, ist eine andere Frage.