PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java. Auf Objekte global zugreifen?


Ganon
2004-08-01, 01:38:09
Hi.

Mit Hilfe von Javabuch.de arbeite ich mich gerade in Java ein. Erst mal "nur" mit AWT als Oberfläche.

Ich wollte mal versuchen ein kleines XXO-Spiel hinzubekommen.

Nunja. Ich habe mir das erst mal so gedacht das ich mir 9 Schalter mache, von denen ich dann den Text ändere. Ich habe mir aber erst mal angeguckt, wie man solche "Klick-Aktionen" abfängt etc. Deswegen hat der jetzige Quellcode nichts mit dem Spiel zu tun. ;)

Da ich ja im Prinzip global auf die Schalter zugreifen muss/will. Wollte ich mal fragen ob mein jetziger Versuch so in Ordnung geht, oder ob das nicht zu empfehlen ist, bzw. wie man es "besser" machen sollte.

Die Frage bezieht sich jetzt z.B. auf die beiden Objekte "klick" und "cmdSchalter". Stehen die da so richtig?


import java.awt.*;
import java.awt.event.*;

public class XXO
extends Frame
{
SchalterAktion klick = new SchalterAktion();
Button cmdSchalter = new Button("Klick mich!");

class SchalterAktion
implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();
if (cmd.equals("Klick mich!"))
{
cmdSchalter.setLabel("Danke!");
}
if (cmd.equals("Danke!"))
{
cmdSchalter.setLabel("Klick mich!");
}
}
}

public static void main(String[] args)
{
XXO frm = new XXO();
frm.setVisible(true);
};

public XXO()
{
super("XXO");
addWindowListener(new WindowClosingAdapter(true));
setLayout(null);
setSize(640,480);
cmdSchalter.setBounds(50,50,200,100);
cmdSchalter.addActionListener(klick);
add(cmdSchalter);
}
};


Falls das oben jetzt totaler Müll sein sollte, sorry. :) Ich bin (leider) nur komplett RAD-IDEs (z.B. die Dinger von Borland) "gewöhnt".

Das Ding da oben funktioniert zwar, aber ich hab da als Java-Anfänger so meine bedenken. ;)

Danke.

ethrandil
2004-08-01, 01:53:27
Ich hätte die Initialisierung der beiden Variablen mit in den Konstruktor gepackt, ansonsten find ich keine Stil-Fehler :)

(Allerdings hätte ich den Listener nicht als eigenständige Innter-Class realisiert, sondern so:)


import java.awt.*;
import java.awt.event.*;

public class XXO
extends Frame
{
Button cmdSchalter;

public static void main(String[] args)
{
XXO frm = new XXO();
frm.setVisible(true);
};

public XXO()
{
super("XXO");
addWindowListener(new WindowClosingAdapter(true));
setLayout(null);
setSize(640,480);
cmdSchalter = new Button("Klick mich!")
cmdSchalter.setBounds(50,50,200,100);
cmdSchalter.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();
if (cmd.equals("Klick mich!"))
{
cmdSchalter.setLabel("Danke!");
}
if (cmd.equals("Danke!"))
{
cmdSchalter.setLabel("Klick mich!");
}
}
});
add(cmdSchalter);
}
};


Ob das besser ist? k.a.

- Eth

HellHorse
2004-08-01, 10:44:15
Swing, baby! :)

public class XXO extends JFrame {

public XXO() {
super("XXO");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container contentPane = this.getContentPane();
contentPane.setLayout(new GridLayout(3, 3, 2, 2));
for (int i = 0; i < 9; ++i) {
JButton button = new JButton(new SwitchAction());
contentPane.add(button);
}
contentPane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
this.pack();
this.setResizable(false);
}

private static class SwitchAction extends AbstractAction {

private static String unclicked = "Klick mich!";

private static String clicked = "Danke!";

public SwitchAction() {
super(unclicked);
}

public void actionPerformed(ActionEvent e) {
String name = (String) this.getValue(NAME);
if (name.equals(unclicked)) {
this.putValue(NAME, clicked);
} else {
this.putValue(NAME, unclicked);
}
}
}

public static void main(String[] args) {
Runnable displayFrame = new Runnable() {
public void run() {
try {
String laf = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(laf);
} catch (Exception e) {
e.printStackTrace();
}
Frame frame = new XXO();
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(displayFrame);
}
}

Du brauchst eigentlich nicht wirklich "globale" Daten. Du müsstest bloss eine Referenz auf den entsprechenden Button haben. Die kannst du aber auch einfach im entsprechenden ActionListener vom ActionEvent per getSource() erfragen und dann casten. Alternativ kannst du sie ihm auch sonst wie übergeben (setButton1(einButton) oder so)

Ganon
2004-08-01, 11:52:45
Hi.

Danke erst mal. Ich werd mir das mal angucken. :)

Firepower
2004-08-01, 15:29:15
@HellHorse:
Hab deine Version mal in Eclipse eingefügt,
nur kennt der bei mir die Methode setBorder nicht.
Weiß aber nicht was fehlt.

Hast Du ne Idee?
Benutze JDK 1.4.2_03 + Eclipse 3.0

Ganon
2004-08-01, 15:49:23
Hi.

Kennt er bei mir auch nicht. :) Deshalb habe ich es erst mal raus genommen. Scheint ja wohl nur dazu da zu sein, um einen breiteren Rand zu erstellen.

So. Ich habe erst mal alles das rausgeschmissen was ich auf anhieb nicht kapiert habe und auch eine erste Version. ;) Dazu habe ich aber noch mal ne Frage. :)


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

public class XXO
extends JFrame
{
boolean Spieler;
String clicked;

public XXO()
{
super("XXO - Das Spiel");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(3,3,2,2));
for (int i = 0; i < 9; ++i)
{
JButton button = new JButton(new SwitchAction());
contentPane.add(button);
}
this.setSize(640,480);
Spieler = true;
clicked = "";
}

private class SwitchAction extends AbstractAction
{
public SwitchAction()
{
super("-");
}

public void actionPerformed(ActionEvent e)
{
String name = (String) this.getValue(NAME);
if(Spieler)
{
clicked = "X";
Spieler = false;
}
else
{
clicked = "O";
Spieler = true;
}
if (name.equals("-"))
{
this.putValue(NAME, clicked);
}
}
}

public static void main(String[] args)
{
XXO frm = new XXO();
frm.setVisible(true);
}
};


Meine Frage ist nämlich was dieses this.getValue(NAME); und dieses this.putValue(NAME, clicked);.

1. Woher kommen die Informationen, wegen "this".
2. Was ist dieses "NAME"?
3. Was macht putValue genau?

Im Javabuch steht gar nix davon.

Außerdem musste ich ja für diese Version das "static" aus der actionPerformed raus nehmen, weil ich sonst nicht auf die Variablen zugreifen kann. Was genau hat das für folgen? Bzw. was war vorher, was jetzt?

Schonmal meinen herzlichsten Dank... :)

HellHorse
2004-08-01, 16:44:27
Original geschrieben von Firepower
@HellHorse:
Hab deine Version mal in Eclipse eingefügt,
nur kennt der bei mir die Methode setBorder nicht.

Mal nachgeschaut, und die sollte eigentlich da sein.
JComponent.html#setBorder(javax.swing.border.Border) (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html#setBorder(javax.swing.border.Border))
Hast du es auch gecasted?
(sollte bei C&P eigentich der Fall sein.)
Aber ist egal, macht nur einen Rand.

SwitchAction erbt von AbstractAction (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/AbstractAction.html).
Eine Action (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/Action.html) ist eine Art erweiterter ActionListener, der zusätzliche Information über ein zu clickendes Objekt liefert, wie der Text, das Icon, der Tooltiptext, ...
Eine Action kann zum erstllen von JButtons, JMenuItems und ähnlichem verwendet werden.
AbstractAction implementiert das meiste davon. Daher kommt auch NAME (statische Varibale von Action). Mit setValue und putValue kann man eben die Werte für Name, Icon, Tooltiptext, ... für alle Komponenten ändern, die diese Action verwenden. Die Konstante gibt an, welchen Wert man ändern will.
So setzte ich z.B. den Text auf dem Button nie explizit, ich ändere bloss den Wert den NAME properties.
How to (http://java.sun.com/docs/books/tutorial/uiswing/misc/action.html)

In meiner Version ist SwitchAction eine statische innere Klasse. Im Gegenstatz zu einer normalen inneren Klasse kann sie statische Variablen enthalten (die beiden Strings) allerdings nicht auf nicht-statische Variablen der äusseren Klasse zugreiffen. Damit hat man einen ähnlichen Effekt wie friends in C++.
Das Ganze etwas hmm, naja, es spart etwas Code, aber wirklich sauber ist es nicht. Also im Zweifelsfall die Finger von (statischen) inneren Klassen lassen. Hier habe ich es nur gemacht, damit alles in ein File passt.

Ganon
2004-08-01, 17:12:02
Achso. Ist ja gar nicht mal so schlecht. :)

Aber ne Frage wäre da noch. ;)

Wie kann ich die einzelnen Schalter ansprechen?

Also z.B. wie kann ich dem Schalter in der Mitte sagen das er den und den Text haben soll, bzw. der Schalter oben rechts?

Kann man die Objekte einzeln abfragen?

Das wäre jetzt z.B. nötig um zu gucken, wer wann gewonnen hat. ;)

HellHorse
2004-08-01, 17:39:51
Original geschrieben von Ganon
Wie kann ich die einzelnen Schalter ansprechen?

Also z.B. wie kann ich dem Schalter in der Mitte sagen das er den und den Text haben soll, bzw. der Schalter oben rechts?

Kann man die Objekte einzeln abfragen?

Einfach eine Referenz darauf speichern, in einer Instanzvaribale, Liste, Array, was auch immer.
Oder du könntest das ContentPane z.B. auch nach dem fünften Komponenten fragen, aber das ist mühsamer.

Du solltest dir aber schon überlegen wann und wo du die Beschriftung von Buttons änderst. Am besten bloss an einem Ort, damit sich die Sachen nicht in die Quere kommen.

...
import java.util.List;
import java.util.ArrayList;

public class XXO
extends JFrame
{
...
private List buttons;

public XXO()
{
...
this.buttons = new ArrayList(9);
for (int i = 0; i < 9; ++i)
{
JButton button = new JButton(new SwitchAction());
this.buttons.add(button);
...
}

public void machWas() {
JButton mittlererButton = (JButton) this.buttos.get(4);
mittlererButton.setEnabled(false)
...
}


Oops, mir ist bei deinem Code aufgefallen. Du solltest einen Sichtbarkeitsmodifikator vor die Instanzvaribalen tun. Entweder private oder protected. Im Zweifelsfall private.

Ganon
2004-08-01, 18:47:07
Hi.

Danke. Scheint zu funktionieren. Aber ich glaube ich mache irgendetwas falsch.

edit: UUUPS. Ich sehe gerade das das so gar nicht funktioniert. Ich kann zwar den Schaltern einen neuen Text geben, aber dann funktioniert der Klick nicht mehr. D.h. es passiert nix.

Also. Meine Frage bezog sich u.a. darauf alle Schalter wieder in den Urzustand zu bringen. D.h. überall wieder "-" reinzuschreiben.

Nun möchte ich es per Schalterklick erledigen.


public void actionPerformed(ActionEvent event)
{
// Menü für XXO
String cmd = event.getActionCommand();
if(cmd.equals("Beenden"))
{
System.exit(0);
}
if(cmd.equals("Nochmal"))
{
for(int i=0;i<9;++i)
{
JButton Schalter = (JButton) this.SchalterListe.get(i);
Schalter.setLabel("-");
}
}
}


Jetzt kommt beim kompilieren folgende Meldung:
---
Note: XXO.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.
---

Mache ich das, dann kommt das:
---
XXO.java:83: warning: setLabel(java.lang.String) in javax.swing.AbstractButton has been deprecated
Schalter.setLabel("-");
^
1 warning
---

Muss ich das temporäre Schalter-Objekt erst wieder löschen, oder was muss ich machen?

HellHorse
2004-08-01, 23:22:37
Original geschrieben von Ganon
setLabel(java.lang.String) in javax.swing.AbstractButton has been deprecated
Schalter.setLabel("-");
Dass will sagen, dass javax.swing.AbstractButton#setLabel(java.lang.String) deprecated ist und dass du das hier verwendet hast:

Schalter.setLabel("-");

Alternative:

Schalter.setText("-");

DocEW
2004-08-02, 10:44:17
Original geschrieben von HellHorse
Mal nachgeschaut, und die sollte eigentlich da sein.
JComponent.html#setBorder(javax.swing.border.Border) (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html#setBorder(javax.swing.border.Border))
Hast du es auch gecasted?
(sollte bei C&P eigentich der Fall sein.)
Aber ist egal, macht nur einen Rand.
Ich glaube es liegt daran, daß JFrame.getContentPane() einen java.awt.Container zurückliefert. Dieser ist von java.awt.Component abgeleitet und nicht von javax.swing.JComponent. Daher hat er die setBorder()-Methode nicht.

HellHorse
2004-08-02, 10:59:12
Original geschrieben von DocEW
Ich glaube es liegt daran, daß JFrame.getContentPane() einen java.awt.Container zurückliefert.
edit: so wie ich es gepostet habe, kann es nicht hinhauen. Keine Ahnung was da passiert ist. Wie ich es posten wollte.

JComponent contentPane = (JComponent) this.getContentPane();
...
contentPane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));

wie es sicher geht:

JComponent contentPane = new JPanel();
...
contentPane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
this.setContentPane(contentPane);

Ganon
2004-08-02, 16:43:29
Hi.

Also mit setText kommt die Meldung nicht mehr.

Aber wenn ich die Schalter zurück setze, dann behalten sie aber ihren ActionCommand von "X" oder "O", obwohl der Schalter-Text nun anders ist. "setActionCommand" hilft auch nicht.

Woran liegt das nun wieder? :(

Ganon
2004-08-08, 19:20:38
Hi.

OK. Da es ja so keiner zu wissen scheint, habe ich mal mit meinem "Wissen" weiter gemacht.

Weiß einer zufällig irgendwelche "Code-Verkürzungen"? z.B. bei den Ganzen if-Abfragen, welcher Schalter nun gedrückt wurde? Kann man ein String der entweder 1,2,3,4,5,6,7,8 oder 9 ist in einen Integer umwandeln? Wenn ja, wie?

Sorry, wenn der Code eine Katastrophe ist. *ggg* ;)


import java.awt.*;
import java.awt.event.*;

public class XXO
extends Frame
implements ActionListener
{
private Button Schalter1 = new Button("-");
private Button Schalter2 = new Button("-");
private Button Schalter3 = new Button("-");
private Button Schalter4 = new Button("-");
private Button Schalter5 = new Button("-");
private Button Schalter6 = new Button("-");
private Button Schalter7 = new Button("-");
private Button Schalter8 = new Button("-");
private Button Schalter9 = new Button("-");
private String Spieler;

private void WechsleSpieler()
{
if (Spieler == "X")
Spieler = "O";
else
Spieler = "X";
}

private void SetzeAllesZurueck()
{
Schalter1.setLabel("-");
Schalter2.setLabel("-");
Schalter3.setLabel("-");
Schalter4.setLabel("-");
Schalter5.setLabel("-");
Schalter6.setLabel("-");
Schalter7.setLabel("-");
Schalter8.setLabel("-");
Schalter9.setLabel("-");
Spieler = "X";
}

private void AendereSchalter(int i)
{
switch(i)
{
case 1:
if (Schalter1.getLabel() == "-")
{
Schalter1.setLabel(Spieler);
WechsleSpieler();
}
break;
case 2:
if (Schalter2.getLabel() == "-")
{
Schalter2.setLabel(Spieler);
WechsleSpieler();
}
break;
case 3:
if (Schalter3.getLabel() == "-")
{
Schalter3.setLabel(Spieler);
WechsleSpieler();
}
break;
case 4:
if (Schalter4.getLabel() == "-")
{
Schalter4.setLabel(Spieler);
WechsleSpieler();
}
break;
case 5:
if (Schalter5.getLabel() == "-")
{
Schalter5.setLabel(Spieler);
WechsleSpieler();
}
break;
case 6:
if (Schalter6.getLabel() == "-")
{
Schalter6.setLabel(Spieler);
WechsleSpieler();
}
break;
case 7:
if (Schalter7.getLabel() == "-")
{
Schalter7.setLabel(Spieler);
WechsleSpieler();
}
break;
case 8:
if (Schalter8.getLabel() == "-")
{
Schalter8.setLabel(Spieler);
WechsleSpieler();
}
break;
case 9:
if (Schalter9.getLabel() == "-")
{
Schalter9.setLabel(Spieler);
WechsleSpieler();
}
break;
}
}

public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();

if (cmd == "Nochmal")
{
SetzeAllesZurueck();
return;
}
if (cmd == "Beenden")
{
System.exit(0);
}

if (cmd == "1")
{
AendereSchalter(1);
return;
}
if (cmd == "2")
{
AendereSchalter(2);
return;
}
if (cmd == "3")
{
AendereSchalter(3);
return;
}
if (cmd == "4")
{
AendereSchalter(4);
return;
}
if (cmd == "5")
{
AendereSchalter(5);
return;
}
if (cmd == "6")
{
AendereSchalter(6);
return;
}
if (cmd == "7")
{
AendereSchalter(7);
return;
}
if (cmd == "8")
{
AendereSchalter(8);
return;
}
if (cmd == "9")
{
AendereSchalter(9);
return;
}
}

public XXO()
{
super("XXO - Das Spiel");
addWindowListener(new WindowClosingAdapter(true));
setSize(640,480);
setLayout(new GridLayout(3,3));

// Schalter
Schalter1.addActionListener(this); Schalter2.addActionListener(this); Schalter3.addActionListener(this);
Schalter4.addActionListener(this); Schalter5.addActionListener(this); Schalter6.addActionListener(this);
Schalter7.addActionListener(this); Schalter8.addActionListener(this); Schalter9.addActionListener(this);

Schalter1.setActionCommand("1"); Schalter2.setActionCommand("2"); Schalter3.setActionCommand("3");
Schalter4.setActionCommand("4"); Schalter5.setActionCommand("5"); Schalter6.setActionCommand("6");
Schalter7.setActionCommand("7"); Schalter8.setActionCommand("8"); Schalter9.setActionCommand("9");

add(Schalter1); add(Schalter2); add(Schalter3);
add(Schalter4); add(Schalter5); add(Schalter6);
add(Schalter7); add(Schalter8); add(Schalter9);
// ...

// Menü-Leiste
MenuBar Main = new MenuBar();
Menu Ablage = new Menu("Ablage");

MenuItem mi = new MenuItem("Nochmal");
mi.addActionListener(this);
Ablage.add(mi);

Ablage.addSeparator();

mi = new MenuItem("Beenden");
mi.addActionListener(this);
Ablage.add(mi);

Main.add(Ablage);
setMenuBar(Main);
// ...

Spieler = "X";
}

public static void main(String[] args)
{
XXO frm = new XXO();
frm.setVisible(true);
}
};


Dickes Danke. :)

HellHorse
2004-08-08, 20:15:52
Habs mir noch nicht angeschaut, aber was mir gerade aufgefallen ist:
Java ist nicht python. Strings mit == zu vergleichen, vergleicht bloss die Referenzen. Das ist ziemlich sicher nicht, was du willst.
also equals verwenden.

Ganon
2004-08-08, 20:32:33
Ach schei**e, stimmt ja. ;)

Ich denke dabei übrigens an C++. Es scheint aber trotzdem zu funktionieren. ;)

Naja. Ich stell´s mal um. ;)

HellHorse
2004-08-08, 20:40:22
Das macht das gleiche mit weniger Code. Arrays kennst du sicher von C++ her. War zu faul um == zu ändern.

public class XXO2 extends Frame implements ActionListener
{
private Button[] schalter;
private String Spieler;

private void WechsleSpieler()
{
if (Spieler == "X")
Spieler = "O";
else
Spieler = "X";
}

private void SetzeAllesZurueck()
{
for (int i = 0; i < schalter.length; ++i) {
schalter[i].setLabel("-");
}
Spieler = "X";
}

private void AendereSchalter(int i)
{
Button zuAendern = schalter[i];
if (zuAendern.getLabel() == "-")
{
zuAendern.setLabel(Spieler);
WechsleSpieler();
}
}

public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();

if (cmd == "Nochmal")
{
SetzeAllesZurueck();
return;
}
if (cmd == "Beenden")
{
System.exit(0);
}

try {
int buttonNumber = Integer.parseInt(cmd);
AendereSchalter(buttonNumber);
return;
} catch (NumberFormatException e) {
// huh, wasn't a number
}
}

public XXO2()
{
super("XXO - Das Spiel");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(640,480);
setLayout(new GridLayout(3,3));
schalter = new Button[9];
for (int i = 0; i < schalter.length; ++i) {
Button newButton = new Button("-");
newButton.addActionListener(this);
newButton.setActionCommand(Integer.toString(i));
add(newButton);
schalter[i] = newButton;
}

// Menü-Leiste
MenuBar Main = new MenuBar();
Menu Ablage = new Menu("Ablage");

MenuItem mi = new MenuItem("Nochmal");
mi.addActionListener(this);
Ablage.add(mi);

Ablage.addSeparator();

mi = new MenuItem("Beenden");
mi.addActionListener(this);
Ablage.add(mi);

Main.add(Ablage);
setMenuBar(Main);
// ...

Spieler = "X";
}

public static void main(String[] args)
{
XXO2 frm = new XXO2();
frm.setVisible(true);
}
}

edit:
*erledigt*

edit2:
Java Namenskonvention:
Klassennamen gross (hast du gemacht)
Methodennamen klein (hast du nicht gemacht)

Ganon
2004-08-08, 21:08:33
Das macht das gleiche mit weniger Code. Arrays kennst du sicher von C++ her. War zu faul um == zu ändern.
edit2:
Java Namenskonvention:
Klassennamen gross (hast du gemacht)
Methodennamen klein (hast du nicht gemacht)

Ah, danke. Also scheint es mit AWT zu klappen mit den Arrays. :)
OK. :) Jetzt kann es endlich weiter gehen. Als nächstes kommt dann etwas Auslagerung, Punkte zählen, dann Klassenkommunikation und dann noch Netzwerk. :)

Hier noch mal so wie es jetzt ist:


import java.awt.*;
import java.awt.event.*;

public class XXO
extends Frame
implements ActionListener
{
private Button[] schalter;
private String Spieler;

private void wechsleSpieler()
{
if (Spieler.equals("X"))
Spieler = "O";
else
Spieler = "X";
}

private void setzeAllesZurueck()
{
for (int i = 0; i < schalter.length; ++i)
{
schalter[i].setLabel("-");
}
Spieler = "X";
}

private void aendereSchalter(int i)
{
Button zuAendern = schalter[i];
if (zuAendern.getLabel().equals("-"))
{
zuAendern.setLabel(Spieler);
wechsleSpieler();
}
}

public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();

if (cmd.equals("Nochmal"))
{
setzeAllesZurueck();
return;
}
if (cmd.equals("Beenden"))
{
System.exit(0);
}

try
{
int buttonNumber = Integer.parseInt(cmd);
aendereSchalter(buttonNumber);
return;
}
catch (NumberFormatException e)
{ // huh, wasn't a number
}
}

public XXO()
{
super("XXO - Das Spiel");
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
setSize(640,480);
setLayout(new GridLayout(3,3));
schalter = new Button[9];
for (int i = 0; i < schalter.length; ++i)
{
Button newButton = new Button("-");
newButton.addActionListener(this);
newButton.setActionCommand(Integer.toString(i));
add(newButton);
schalter[i] = newButton;
}

// Menü-Leiste
MenuBar Main = new MenuBar();
Menu Ablage = new Menu("Ablage");

MenuItem mi = new MenuItem("Nochmal");
mi.addActionListener(this);
Ablage.add(mi);

Ablage.addSeparator();

mi = new MenuItem("Beenden");
mi.addActionListener(this);
Ablage.add(mi);

Main.add(Ablage);
setMenuBar(Main);
// ...

Spieler = "X";
}

public static void main(String[] args)
{
XXO frm = new XXO();
frm.setVisible(true);
}
};