# Funktionalität von JButtons (Actionlistener etc.)



## Strahlungsleck (27. Jan 2009)

Hallo,

und zwar bin ich gerade dabei mir eine GUI für ein kleines Spiel zu
programmieren.... wollte das erst nur mit awt Elementen machen, dies ging aber
nicht ganz so. Nun habe ich auch Swing und awt umgestellt. Die Oberfläche ist 
auch so wie ich es auch wollte... aber nun fängt es bei mir an wegen der Funktionalität
heißt, das wenn ich auf den Enter Button oder auf der Tastatur auf Return drücke,
soll die Zahl die in textZahl steht halt muss umgewandelt werden in eine Zahlendatentyp

Natürlich muss auch für start Anleitung etc. eine Funktionalität mit eingebaut werden.
Will aber das nur für den Enter Button habe damit ich das selber üben und verstehen 
und auch auf die anderen Buttons anwenden kann.

Dazu hätte ich die Frage, ob man bei Textausgaben im Textarea irgendwas beachten soll/muss ?

Danke im Voraus.




```
import java.awt.*;
import javax.swing.*;

public class GUIZahlenRaten {

	public static void main(String[] args)   {

		// Erzeuges eines JFrame mit Zuweisung des Namen, das Layout und Maße
		// für das Fenster
		JFrame jgrundFlaeche = new JFrame("Zahlenraten");
		jgrundFlaeche.setVisible(true);
		jgrundFlaeche.setSize(450, 400);
		jgrundFlaeche.setLayout(new BorderLayout());

		// Erzeugen des Oberen Labels und Zuweisung des Layouts
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new FlowLayout());

		// Erzeugen der Button für das topPanel
		JButton start = new JButton("Start");
		JButton highscore = new JButton("Highscore");
		JButton hilfe = new JButton("Anleitung");
		JButton ende = new JButton("Ende");

		// Dem topPanel werden die Buttons hinzugefügt
		topPanel.add(start);
		topPanel.add(highscore);
		topPanel.add(ende);
		topPanel.add(hilfe);

		// ich Füge den Grundfarme das Panel hinzu
		jgrundFlaeche.add(topPanel, BorderLayout.NORTH);

		// erzeugen und zuweisen das Layout für das linke Panel
		JPanel linksPanel = new JPanel();
		linksPanel.setLayout(new GridLayout(3, 1));

		// erzeugen der Button für das linke Panel
		JButton zahl = new JButton("Zahl:");
		JButton spiel = new JButton("Spiel:");
		JButton siege = new JButton("Siege:");

		// ich füge dem LinksPanel die Button hinzu
		linksPanel.add(zahl);
		linksPanel.add(spiel);
		linksPanel.add(siege);

		// das LInksPanel wird der grundfläche hinzugefügt
		jgrundFlaeche.add(linksPanel, BorderLayout.WEST);

		// Erzeugen und zuweisung des Layout für das centePanel
		JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new GridLayout(3, 1));

		// Erzeugung der eingabe Textfeler für das Mittelpanel
		TextField textZahl = new TextField();
		TextField textSpiel = new TextField();
		TextField textSiege = new TextField();
		

		// Hinzufügen der Textfelder im centerPanel
		centerPanel.add(textZahl);
		centerPanel.add(textSpiel);
		centerPanel.add(textSiege);

		jgrundFlaeche.add(centerPanel, BorderLayout.CENTER);

		JPanel rechtsPanel = new JPanel();
		rechtsPanel.setLayout(new GridLayout(2, 1));

		JButton enter = new JButton("Enter");
		rechtsPanel.add(enter);

		jgrundFlaeche.add(rechtsPanel, BorderLayout.EAST);
		TextArea ausgabe = new TextArea();
		jgrundFlaeche.add(ausgabe, BorderLayout.SOUTH);

	}
}
```


----------



## Strahlungsleck (27. Jan 2009)

ALso auf gut Deutsch, ich brauche da hilfe, weil ich selbst nach dem ich gegoogle habe nicht wirklich weiß, wie ich das aufbauen
und was ich beachten soll/muss =/


----------



## SlaterB (27. Jan 2009)

wie man Buttons generell benutzt steht in Lehrbüchern/ Tutorials,
http://java.sun.com/docs/books/tutorial/uiswing/components/button.html
sogar mit kompletten Beispielen,

wenn du dennoch keinen eigenen Ansatz hast und die Probleme nicht sprachlich erfassen kannst,
dann hat Hilfe keinen Sinn


----------



## Strahlungsleck (27. Jan 2009)

***EDIT***


Argh so werd das mal schnell umbauen, hatte nen ganz doofen denkfehler drinne.....
jetzt geht das auch shice static method fehler xD


thx

Hoffe mal das klappt alles so wie es soll !


----------



## SlaterB (27. Jan 2009)

ist 'this' denn ein ActionListener? 

public class GUIZahlenRaten implements ActionListener { 
statt
public class GUIZahlenRaten { 
?

dann wäre zunächst ohne groß umzubauen
 addActionListener(new GUIZahlenRaten()); 
denkbar

ein Umbauen ist aber generell immer zu empfehlen, also sollte man dem kaum widersprechen


----------



## Ebenius (27. Jan 2009)

Strahlungsleck hat gesagt.:
			
		

> Heißt, wieder alles umbauen oder nicht ?!


Du brauchst eine Instanz eines ActionListeners... Das geht ja mannigfaltig zu lösen, zum Beispiel: 
	
	
	
	





```
publis static void main(String[] args) {
  final JButton button = new JButton();
  button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
      System.out.println("Wo ist das Problem?");
    }
  }
}
```

Ebenius


----------



## Strahlungsleck (27. Jan 2009)

@Ebnius wenn du oben liest hab das gepostete
geedit, weil ich nen kompletten Denkfehler drinne hatte....

muss ja das garnet alles umbauen sondern nur ein wenig was ändern.
Das war ja das.... 
Manchmal ist die Lösung so einfach und man sieht den Wald vor lauter Bäumen nicht. So werde das mal ein wenig ändern und hoffen das es klappt und dann nochmal den fertigen Code posten.



*****EDIT*****



			
				SlaterB hat gesagt.:
			
		

> ist 'this' denn ein ActionListener?
> 
> public class GUIZahlenRaten implements ActionListener {
> statt
> ...



hab das jetzt mit implements ActionListener......
gemacht....


----------



## Strahlungsleck (27. Jan 2009)

Hab nun für die Button, welche eine FUnktionalität erhalten sollen, 
ein ActionListener und ein ActionCommand hinzugefügt.

Ist das denn so Richtig ?


```
// ActionListener für die Buttons
		start.addActionListener(this);
		ende.addActionListener(this);
		highscore.addActionListener(this);
		hilfe.addActionListener(this);
		enter.addActionListener(this);

		// setzen des ActionCommand
		start.setActionCommand("start_button");
		ende.setActionCommand("ende_button");
		highscore.setActionCommand("highscore_button");
		hilfe.setActionCommand("hilfe_button");
		enter.setActionCommand("enter_button");
```

Nun bin ich da bei die actionPerformed zu machen....
Und da komme ich nicht weiter, da mir 2 Fehler angezeigt werden und ich gerne wüsste wieso ich diesen Typ
nicht verwenden darf und welchen ich dafür nutzen könnte. Hier der Code:

```
public void actionPerformed(ActionEvent e) { // <<--------------- Fehlerzeile (Fehler: siehe unten)
			if (e.getActionCommand().equalsIgnoreCase("start_button")) {
				// Programmstart
			}
			else if (e.getActionCommand().equalsIgnoreCase("ende_button")) {
				//Programmende
				System.exit(0);
			}
			else if (e.getActionCommand().equalsIgnoreCase("highscore_button")) {
				//Highscore anzeigen
			}
			else if (e.getActionCommand().equalsIgnoreCase("hilfe_button")) {
				// text mit Anleitung öffnen
			}
			else if (e.getActionCommand().equalsIgnoreCase("enter_button")) {
				// eingebene Zahl (String) umwandeln und prüfen
			}
		}
```

Fehler#1: void is an invalid type for the variable actionPerformed 

Fehler#2: Syntax error on token ")", ; expected
Dieser Fehler ist beim "e)"

@Ebenius
Jeder der Programmiert, hat klein Angefangen und Probleme gehabt.....


----------



## Ebenius (27. Jan 2009)

Strahlungsleck hat gesagt.:
			
		

> @Ebenius
> Jeder der Programmiert, hat klein Angefangen und Probleme gehabt.....


Eigentlich wollte ich nur Hilfestellung geben. :shock: Ich hab wenig geschlafen, vielleicht drücke ich mich heute weniger freundlich aus als sonst. Sorry...

Was den Code oben angeht: Dein Ansatz ist super. Die Compiler-Fehler kann ich mir nur so erklären, dass Du woanders im Code einen Fehler hast. Die Methode ist jedenfalls richtig geschrieben, daran liegt's also nicht. Entweder noch etwas mehr Source Code posten, oder die Methode mal auskommentieren und nachsehen, was noch für Fehler kommen.

Ein Hinweis: Die if's in actionPerformed() am besten so schreiben: 
	
	
	
	





```
final String cmd = e.getActionCommand();
if("myActtionCommand".equals(cmd)) {
```

Ebenius


----------



## Strahlungsleck (27. Jan 2009)

Ebenius hat gesagt.:
			
		

> Strahlungsleck hat gesagt.:
> 
> 
> 
> ...



Das war net Böse gemeint Ebenius dann leg dich hin und schlaf weiter Morgenmuffel 
Aber find das gut das Leute wie du solchen "n00bs" wie mir helfen  =)

Und wieso wäre das denn besser als das was ich habe ?



```
final String cmd = e.getActionCommand();
if("myActtionCommand".equals(cmd)) {
```
Hab auch dein Code Ebenius gleich mal mit eingebaut
Hier ist nun der ganze Code für die GUI




```
package zahlenRaten;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GUIZahlenRaten implements ActionListener {  // <--- Fehler: The type GUIZahlenRaten must implement the 
// inherited abstract method ActionListener.actionPerformed(ActionEvent)

	// public static void main(String[] args) {
	public void test() {

		// Erzeuges eines JFrame mit Zuweisung des Namen, das Layout und Maße 
		// für das Fenster
		JFrame jgrundFlaeche = new JFrame("Zahlenraten");
		jgrundFlaeche.setVisible(true);
		jgrundFlaeche.setSize(450, 400);
		jgrundFlaeche.setLayout(new BorderLayout());

		// Erzeugen des Oberen Labels und Zuweisung des Layouts
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new FlowLayout());

		// Erzeugen der Button für das topPanel
		JButton start = new JButton("Start");
		JButton highscore = new JButton("Highscore");
		JButton hilfe = new JButton("Anleitung");
		JButton ende = new JButton("Ende");

		// Dem topPanel werden die Buttons hinzugefügt
		topPanel.add(start);
		topPanel.add(highscore);
		topPanel.add(ende);
		topPanel.add(hilfe);

		// ich Füge den Grundfarme das Panel hinzu
		jgrundFlaeche.add(topPanel, BorderLayout.NORTH);

		// erzeugen und zuweisen das Layout für das linke Panel
		JPanel linksPanel = new JPanel();
		linksPanel.setLayout(new GridLayout(3, 1));

		// erzeugen der Button für das linke Panel
		JButton zahl = new JButton("Zahl:");
		JButton spiel = new JButton("Spiel:");
		JButton siege = new JButton("Siege:");

		// ich füge dem LinksPanel die Button hinzu
		linksPanel.add(zahl);
		linksPanel.add(spiel);
		linksPanel.add(siege);

		// das LInksPanel wird der grundfläche hinzugefügt
		jgrundFlaeche.add(linksPanel, BorderLayout.WEST);

		// Erzeugen und zuweisung des Layout für das centePanel
		JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new GridLayout(3, 1));

		// Erzeugung der eingabe Textfeler für das Mittelpanel
		TextField textZahl = new TextField();
		TextField textSpiel = new TextField();
		TextField textSiege = new TextField();

		// Hinzufügen der Textfelder im centerPanel
		centerPanel.add(textZahl);
		centerPanel.add(textSpiel);
		centerPanel.add(textSiege);

		jgrundFlaeche.add(centerPanel, BorderLayout.CENTER);

		JPanel rechtsPanel = new JPanel();
		rechtsPanel.setLayout(new GridLayout(2, 1));

		JButton enter = new JButton("Enter");
		rechtsPanel.add(enter);

		jgrundFlaeche.add(rechtsPanel, BorderLayout.EAST);
		TextArea ausgabe = new TextArea();
		jgrundFlaeche.add(ausgabe, BorderLayout.SOUTH);

		// ActionListener für die Buttons
		start.addActionListener(this);
		ende.addActionListener(this);
		highscore.addActionListener(this);
		hilfe.addActionListener(this);
		enter.addActionListener(this);

		// setzen des ActionCommand
		start.setActionCommand("start_button");
		ende.setActionCommand("ende_button");
		highscore.setActionCommand("highscore_button");
		hilfe.setActionCommand("hilfe_button");
		enter.setActionCommand("enter_button");
		
		public void actionPerformed(ActionEvent e) { // <<<< immer noch Fehler wie oben beschrieben
			final String cmd = e.getActionCommand();
			if ("start_button".equals(cmd)) {
				// Programmstart
			}
			else if ("ende_button".equals(cmd)) {
				//Programmende
				System.exit(0);
			}
			else if ("highscore_button".equals(cmd)) {
				//Highscore anzeigen
			}
			else if ("hilfe_button".equals(cmd)) {
				// text mit Anleitung öffnen
				
			}
			else if ("enter_button".equals(cmd)) {
				// eingebene Zahl (String) umwandeln und prüfen
			}
		}
	}
}
```


----------



## Ebenius (27. Jan 2009)

Strahlungsleck hat gesagt.:
			
		

> Und wieso wäre das denn besser als das was ich habe ?


Drei Veränderungen: 
Ich hab das String-Literal (das in Anführungszeichen ist ein Literal) nach vorn gestellt, weil das nicht null sein kann. Das heißt, NullPointerException ausgeschlossen.  :toll: Außerdem steht so das wichtige vorn. Wenn man den Code liest, erkennt man schneller, wo der Unteschied ist.
Das e.getActionCommand() habe ich an eine einzige Stelle verschoben und in eine Variable geschrieben. Das geht schneller weil der Methodenaufruf nur einmal gemacht wird und sieht besser aus, weil die Zeilen kürzer werden.
Die equals()-Methode ist schlanker als equalsIgnoreCase(). Und Du kannst ja bei actionCommands aufpassen, dass sie die selbe Schreibweise haben. Da sollte man sich ohnehin einen Stil angewöhnen. Am besten wie Variablenbezeichner *camelCase* (← kleiner Anfangsbuchstabe, keine Unterstriche).

Ebenius


----------



## Strahlungsleck (27. Jan 2009)

achso ok... 

Hab das mal ein wenig angepasst, aber das Problem ist das das Programm
Immer noch die oben genannten Fehler hat ujnd ich einfach nicht weiß,
wieso und wie ich die beheben soll !


----------



## Ebenius (27. Jan 2009)

So - Source-Code hab ich mir angesehen. Du deklarierst die actionPerformed()-Methode *innerhalb* der test()-Methode. Verschieb Zeile 119 nach Zeile 98 und alles wird gut.


----------



## Strahlungsleck (27. Jan 2009)

ha warst zu langsam =P

Hab gerade aber auch den Fehler gefunden ^^ 

weil ich oben mal auf autogenerate von der Methode geklickt hab
und der hat die gleiche, bis auf die If-teile, erzeugt.
Nur halt nen Stück weiter unten.

Nun kommt der Fehler:
java.lang.NoSuchMethodError: main
Exception in thread "main" 

happens danke erstmal =)


----------



## Ebenius (27. Jan 2009)

Probier's doch mal so... dann wird da langsam was draus. Ich hab eigentlich nur ein bisschen umverschoben: 
	
	
	
	





```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class GUIZahlenRaten extends JFrame implements ActionListener {

  /** Creates a new <code>GUIZahlenRaten</code>. */
  public GUIZahlenRaten() {
    super("Zahlenraten");
    setLayout(new BorderLayout());
    setSize(450, 400);
    installComponents();
  }

  private void installComponents() {
    // Erzeugen des Oberen Labels und Zuweisung des Layouts
    JPanel topPanel = new JPanel();
    topPanel.setLayout(new FlowLayout());

    // Erzeugen der Button für das topPanel
    JButton start = new JButton("Start");
    JButton highscore = new JButton("Highscore");
    JButton hilfe = new JButton("Anleitung");
    JButton ende = new JButton("Ende");

    // Dem topPanel werden die Buttons hinzugefügt
    topPanel.add(start);
    topPanel.add(highscore);
    topPanel.add(ende);
    topPanel.add(hilfe);

    // ich Füge den Grundfarme das Panel hinzu
    this.add(topPanel, BorderLayout.NORTH);

    // erzeugen und zuweisen das Layout für das linke Panel
    JPanel linksPanel = new JPanel();
    linksPanel.setLayout(new GridLayout(3, 1));

    // erzeugen der Button für das linke Panel
    JButton zahl = new JButton("Zahl:");
    JButton spiel = new JButton("Spiel:");
    JButton siege = new JButton("Siege:");

    // ich füge dem LinksPanel die Button hinzu
    linksPanel.add(zahl);
    linksPanel.add(spiel);
    linksPanel.add(siege);

    // das LInksPanel wird der grundfläche hinzugefügt
    this.add(linksPanel, BorderLayout.WEST);

    // Erzeugen und zuweisung des Layout für das centePanel
    JPanel centerPanel = new JPanel();
    centerPanel.setLayout(new GridLayout(3, 1));

    // Erzeugung der eingabe Textfeler für das Mittelpanel
    TextField textZahl = new TextField();
    TextField textSpiel = new TextField();
    TextField textSiege = new TextField();

    // Hinzufügen der Textfelder im centerPanel
    centerPanel.add(textZahl);
    centerPanel.add(textSpiel);
    centerPanel.add(textSiege);

    this.add(centerPanel, BorderLayout.CENTER);

    JPanel rechtsPanel = new JPanel();
    rechtsPanel.setLayout(new GridLayout(2, 1));

    JButton enter = new JButton("Enter");
    rechtsPanel.add(enter);

    this.add(rechtsPanel, BorderLayout.EAST);
    TextArea ausgabe = new TextArea();
    this.add(ausgabe, BorderLayout.SOUTH);

    // ActionListener für die Buttons
    start.addActionListener(this);
    ende.addActionListener(this);
    highscore.addActionListener(this);
    hilfe.addActionListener(this);
    enter.addActionListener(this);

    // setzen des ActionCommand
    start.setActionCommand("start_button");
    ende.setActionCommand("ende_button");
    highscore.setActionCommand("highscore_button");
    hilfe.setActionCommand("hilfe_button");
    enter.setActionCommand("enter_button");
  }

  public void actionPerformed(ActionEvent e) { // <<<< immer noch Fehler wie
    // oben beschrieben
    final String cmd = e.getActionCommand();
    if ("start_button".equals(cmd)) {
      // Programmstart
    } else if ("ende_button".equals(cmd)) {
      // Programmende
      System.exit(0);
    } else if ("highscore_button".equals(cmd)) {
      // Highscore anzeigen
    } else if ("hilfe_button".equals(cmd)) {
      // text mit Anleitung öffnen

    } else if ("enter_button".equals(cmd)) {
      // eingebene Zahl (String) umwandeln und prüfen
    }
  }

  /**
   * Test main method.
   * 
   * @param args ignored
   */
  public static void main(String[] args) {
    final GUIZahlenRaten gui = new GUIZahlenRaten();
    SwingUtilities.invokeLater(new Runnable() {

      @Override
      public void run() {
        gui.setLocationRelativeTo(null); // frame centered
        gui.setVisible(true);
      }
    });
  }
}
```

Ebenius


----------



## Strahlungsleck (30. Jan 2009)

*push*

Hab mal noch ne Frage und zwar, was ist besser halt
die einzelnen Funktionen/Methoden in der GUI Klasse selber 
zu schreiben oder für die FUnktionalität eine Extra Klasse mit
Methoden anzulegen ?




*****EDIT*****

Hab da noch ne Frage ^^
Wie kann ich erzeugtes TextField-Objekt vor eingabe
schützen ?!


----------



## Ebenius (30. Jan 2009)

Strahlungsleck hat gesagt.:
			
		

> Hab mal noch ne Frage und zwar, was ist besser halt die einzelnen Funktionen/Methoden in der GUI Klasse selber zu schreiben oder für die FUnktionalität eine Extra Klasse mit
> Methoden anzulegen ?


Kommt immer auf die Komplexität an. Wenn's komplizierte Logik ist, dann sollte die gesamte "Funktionalität" in eine extra Klasse. Bei Kleinkram kann man's sich auch sparen.



			
				Strahlungsleck hat gesagt.:
			
		

> Wie kann ich erzeugtes TextField-Objekt vor eingabe schützen ?!


Da fällt mir grad auf, dass Du die _TextField_-Klasse(AWT) benutzt. Nimm JTextField(Swing), der Rest Deiner GUI ist auch Swing. Und dann JTextField.setEditable(false) (geerbt von JTextComponent).

Ebenius


----------



## Strahlungsleck (30. Jan 2009)

Habe das hier genutzt

textSpiel.setEnabled(false);

Aber dein funzt auch danke =)

Bin nun dabei die Methoden in die andere
Klasse zu schreiben, damit das sauber getrennt ist !


----------

