PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [JAVA] Variable Attribute-Namen?


M@tes
2006-03-05, 20:37:04
Wie kann ich in JAVA folgendes realisieren?
Kontrolliere in einer Schleife Alle Attribute von Field_a1 ... Field_a5 ob sie true sind. Wie kann man das am besten machen? Ev als Hash?

//edit:
Hmm schlechtes Beispiel..
Naja es geht eigentlich um folgendes:
Ich brauch ein 3x3 grosses Feld (TicTacToe) und will nicht jedes Feld einzeln erstellen, sondern sie mit einer Schleife.
Bisher hab ichs so gemacht:
Button_a1 = new Button("");
Button_a1.setBounds(71, 42, 32, 32);
Button_a1.setActionCommand("a1");
Button_a1.addActionListener(this);
this.add(Button_a1);
Ja ich weiss, is scheisse, bin halt noch n blutiger Anfänger :rolleyes:

Osborn
2006-03-05, 20:43:56
Mach doch ein Array aus Buttons und verändere dann diese in einer Schleife.

M@tes
2006-03-05, 20:50:10
? Habs jetzt so gemacht:

Button a1 = new Button("");
a1.setBounds(71, 42, 32, 32);
a1.setActionCommand("a1");
a1.addActionListener(this);
this.add(a1);
Jetzt hab ich aber das Problem, das ichs im "public void actionPerformed(ActionEvent e) {"
nicht auslesen/ verändern kann :confused:

Monger
2006-03-05, 21:02:24
Bei einem ActionListener gibt es zwei Varianten. Entweder, du leitest alle Nachrichten auf den selben ActionListener um, und wertest dann anhand des ActionCommands aus, was denn der ActionListener konkret tun soll. Das ist wohl momentan die Variante wie du sie hast.


Diese Variante spart zwar Speicher, weil man nur einen einzigen Listener hat - dafür wird der Code im Listener unverhältnismäßig komplex. Oft ist es da geschickter, einfach für jeden Eventtyp einen eigenen Listener zu schreiben, der immer auslöst - egal was für ein Event es nun ist.


a1.addActionListener(new MyActionListener());

Ich weiß ja nicht, was du konkret machen willst. Wenn du z.B. irgendwelche Eigenschaften des zugrundeliegenden Buttons ändern willst (schwarz färben, Beschriftung ändern...), solltest du deinem Listener am besten gleich im Konstruktor die Referenz des Objektes mitgeben, damit er daran was manipulieren kann.

Also zum Beispiel:


public class MyActionListener{

private final Button button;
public MyActionListener(Button button){
super();
this.button = button;
}

public void actionPerformed(){
button.setVisible = false;
}
}

M@tes
2006-03-05, 21:16:47
Es is für die Schule, dabei nicht mal Ansatzweise so Sachen durchgenommen. :P Bins dennoch am probieren. Ich versuch halt von meinen Perl-Kenntnissen einige Dinge zu "übertragen". Das von dir probier ich gleich mal aus.
Was ist aber daran falsch? Was in Perl geht, heisst ja leider nciht das es auch in JAVA geht ;-(
public static String[] Fields = {"a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3", };
public void actionPerformed(ActionEvent e) {
System.out.println("->\n");
for(int i = 0; i < 9; i++) {
System.out.println("- "+Fields[i]+"\n");
if (Button.Fields[i].getLabel() == "o") {
Button.Fields[i].setLabel("x");
}
else {
Button.Fields[i].setLabel("o");
}
}
}

Ok das mit dem Fields[i] is Schwachsinn, aber ich hoffe ihr seht, worauf ich hinaus will :confused: Es geht darum, die Buttons "variabel" ansprechen zu können.

/edit:
oder:
public void actionPerformed(ActionEvent e) {
Object i = e.getActionCommand();
if (Button.i.getLabel() == "o") {
Button.i.setLabel("x");
}
else {
Button.i.setLabel("o");
}
}

Monger
2006-03-05, 21:44:47
public static String[] Fields = {"a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3", };
public void actionPerformed(ActionEvent e) {
System.out.println("->\n");
for(int i = 0; i < 9; i++) {
System.out.println("- "+Fields[i]+"\n");
if (Button.Fields[i].getLabel() == "o") {
Button.Fields[i].setLabel("x");
}
else {
Button.Fields[i].setLabel("o");
}
}
}
Was zur Hölle machst du hier eigentlich?!?
Ein String ist kein Button, hat also auch kein Label. Und selbst wenn: willst du wirklich die Beschriftung von allen Buttons kippen, wenn man nur auf einen davon klickt?

public void actionPerformed(ActionEvent e) {
Object i = e.getActionCommand();
if (Button.i.getLabel() == "o") {
Button.i.setLabel("x");
}
else {
Button.i.setLabel("o");
}
}
Erstens musst du richtig casten. Zweitens: willst du jetzt das ActionCommand haben, oder das aufrufende Objekt? Das ActionCommand ist ja ein String - davon kriegst du garantiert kein Label, egal wie du hin und her castest. Drittens: bei "Button.i.setLabel()" kannst du dir den Button sparen. i ist kein statisches Klassenattribut, also kannst du es auch nicht auf die Weise ansprechen.
Im Prinzip ist es aber richtig, aber ich finde den Umgang mit dem ActionCommand relativ fehleranfällig: sobald sich irgendwo mal ein Tippfehler einschleicht, ist gleich der ganze Listener kaputt, und man kriegt nichtmal eine Fehlermeldung. Deshalb mache ich es gerne auf die harte Tour, und instanziiere für jeden Eventtyp den ich verarbeiten will auch einen eigenen Listener.

M@tes
2006-03-05, 23:01:07
public static String[] Fields= {"a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3", };
public void actionPerformed(ActionEvent e) {
for(int i = 0; i < 9; i++) {
if (Button.Fields[i].getLabel() == "o") {
Button.Fields[i].setLabel("x");
}
else {
Button.Fields[i].setLabel("o");
}
}
}
Es geht darum, das ich alle Buttons ansprechen will. Von Button.a1 bis Button.c3 das über eine Schleife. Die Funktion in dem Beispiel is Banane.
Wenns besser gefällt nimm das:

public static String[] Fields= {"a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3", };

public void actionPerformed(ActionEvent e) {

for(int i = 0; i < 9; i++) {
System.out.println("->" + Button.Fields[i].getLabel() + "<- \n");
}

}

Was ich bezwecken will, is das gleiche. In Perl gehts aber Java will nciht. Jedenfalls nicht so

Monger
2006-03-06, 01:32:23
Sorry, ich bin begriffsstutzig. WAS genau willst du machen?

Ich verstehe momentan einfach nicht, was du erreichen willst. Was genau löst ein ActionEvent aus, und was soll dann passieren?

mithrandir
2006-03-06, 09:16:23
Dere!

Er will Tic-Tac-Toe implementieren, mit einer 3x3 Button-Matrix. Ich würde folgendes vorschlagen:

Klasse MyButtonMatrix:
package test;

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

import javax.swing.JButton;

public class MyButtonMatrix implements ActionListener
{
private JButton[][] buttons;

public MyButtonMatrix( int y, int x )
{
buttons = new JButton[y][x];

for ( int i = 0; i < y; i++ )
{
for ( int j = 0; j < x; j++ )
{
JButton b = new JButton( "Button_"+i+"_"+j );
b.setActionCommand( i+"_"+j );
b.addActionListener( this );

buttons[i][j] = b;
}
}
}

public JButton getButtonAt( int y, int x )
{
// TODO: Fehler/Exception-Handling
// fuer den Schlechtfall (an diesen
// Koordinaten existiert kein Button);
return buttons[y][x];
}

public void actionPerformed( ActionEvent e )
{
String actionCommand = e.getActionCommand();
int idx = actionCommand.indexOf( '_' );
int y = Integer.parseInt( actionCommand.substring( 0, idx ) );
int x = Integer.parseInt( actionCommand.substring( idx + 1 ) );
JButton b = buttons[y][x];

// TODO Mit Button weiterarbeiten
System.out.println( "Button: <"+b+">" );
}

}

Startklasse (Hauptfenster) MyFrame:
package test;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyFrame extends JFrame
{
private MyButtonMatrix buttonMatrix;

public MyFrame()
{
super( "MyFrame" );

this.buttonMatrix = new MyButtonMatrix( 3, 3 );

Container c = this.getContentPane();

JPanel gridPanel = new JPanel( new GridLayout( 3, 3 ) );

for ( int i = 0; i < 3; i++ )
{
for ( int j = 0; j < 3; j++ )
{
gridPanel.add( this.buttonMatrix.getButtonAt( i, j ) );
}
}

c.add( gridPanel, BorderLayout.CENTER );

this.addWindowListener( new WindowAdapter()
{
public void windowClosing()
{
System.exit( 1 );
}
} );

this.pack();
}

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

Einfach einmal ausprobieren. Es werden 3x3 Buttons angelegt, die man über die y/x Koordinaten ansprechen kann. Jeder Button hat denselben ActionListener und über das ActionCommand wird auf die Koordinaten zugegriffen (umständlich, besser wäre evtl. wirklich ein eigenes ActionListener-Objekt für jeden Button. Dieses muss dann aber evtl. auch mehr kennen als nur "seinen" Button).

bye, Peter

M@tes
2006-03-06, 22:45:37
:| Is ja Haarstreubend :eek:
Du löst das ganze über ein Array? Wäre ne Möglichkeit, hab mich wohl zu sehr auf meine Idee fixiert.
Für was ist:
import javax.swing.JButton;
??

mithrandir
2006-03-07, 08:14:36
Dere!

Wofür? Um die Klasse JButton aus dem Package javax.swing in meiner Klasse bekannt zu machen. Siehe auch:
http://java.sun.com/docs/books/tutorial/
http://www.javabuch.de/

bye, Peter