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önnte 🙂

    Ach 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.


Anmelden zum Antworten