ActionListener-Problem bei Schulaufgabe - variable Anzahl von Buttons...

Kryptaesthesie

Erfahrenes Mitglied
Hallo.
Ich habe eine Schulaufgabe zu lösen, stehe aber gerade ein wenig auf dem Schlauch.
Problem bei der Geschichte ist die variable Anzahl der JButton.
Beim Klick auf einen solchen Button soll die Hintergrundfarbe von grün auf rot wechseln und die entsprechenden Zahlenwerte sollen angepasst werden.

Ich habe drei Klassen: Anwendungsfenster (Hauptprogramm), NeueWerte, SitzKlick.
SitzKlick stellt den ActionListener für die ganzen Button dar. Und genau da kommen wir zu meinem Problem. Die Button, anfangs alle grün, stellen freie Sitzplätze dar. Wird ein Button / ein Sitz gedrückt, ist dieser belegt und soll nun rot dargestellt werden.
Wie stelle ich das in SitzKlick an die Farbe zu ändern, da ich ja nicht weiß welcher Button das Ereignis ausgelöst hat. Geht das über die AddActionCommand-Methode? Aber da komme ich nicht weiter, da die Anzahl der Button / Sitze variieren kann.

Habt ihr eine Idee für mich? Wie kann ich die Farbe des Buttons ändern? Den Rest mit den Zahlen, etc. bekomme ich dann sicher raus.

Danke euch schon mal!

Hier noch die drei Klassen (auch für jeden anderen Tipp, bezüglich meines Codes, bin ich dankbar):

Anwendungsfenster:
Code:
package version1;

import java.awt.Color;
import java.awt.Container;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class Anwendungsfenster extends JFrame {
	
	private final int REIHEN_BEI_PROGRAMMSTART = 5;
	private final int SITZE_PRO_REIHE_BEI_PROGRAMMSTART = 4;
	private final int REIHENBREITE = 80;
	
	private Container cont;
	
	// Konstruktor
	public Anwendungsfenster() {
		System.out.println("Konstruktoraufruf!");
		interfaceAufbauen(REIHEN_BEI_PROGRAMMSTART, SITZE_PRO_REIHE_BEI_PROGRAMMSTART);
	}
	
	public void interfaceAufbauen(int anzReihen, int sitzeProReihe) {
		cont = this.getContentPane();
		cont.setLayout(null);
		cont.removeAll();
		
		// Felder, die dem Benutzer Eingaben ermoeglichen
		JTextField jtAnzReihen, jtSitzeProReihe;
		
		// statische Labelfelder
		JLabel jlAnzReihen, jlSitzeProReihe, jlFreieSitze, jlBesaetzteStuehle;
		
		// Button um die Benutzereingaben zu uebernehmen
		JButton jbAenderungenUebernehmen;
		
		
		// Voreinstellungen zum Anwendungsfenster
		this.setTitle("Reservierungssystem");
		this.setSize(800, 600);
		this.setLocation(10, 40);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// Felder fuer die Benutzereingaben
		jlAnzReihen = new JLabel();
		jlAnzReihen.setText("Anzahl der Reihen:");
		jlAnzReihen.setBounds(10, 10, 130, 15);
		cont.add(jlAnzReihen);
		
		jlSitzeProReihe = new JLabel();
		jlSitzeProReihe.setText("Sitze pro Reihe:");
		jlSitzeProReihe.setBounds(10, 30, 130, 15);
		cont.add(jlSitzeProReihe);
		
		jtAnzReihen = new JTextField();
		jtAnzReihen.setText("" + anzReihen);
		jtAnzReihen.setBounds(10 + 130 + 10, 8, 30, 20);
		cont.add(jtAnzReihen);
		
		jtSitzeProReihe = new JTextField();
		jtSitzeProReihe.setText("" + sitzeProReihe);
		jtSitzeProReihe.setBounds(10 + 130 + 10, 30, 30, 20);
		cont.add(jtSitzeProReihe);
		
		// Info ueber die Anzahl der freien und besetzten Stuehle
		jlFreieSitze = new JLabel();
		jlFreieSitze.setText("freie Sitzplaetze: " + (anzReihen * sitzeProReihe));
		jlFreieSitze.setBounds(10 + 130 + 10 + 30 + 30, 10, 150, 15);
		cont.add(jlFreieSitze);
		
		jlBesaetzteStuehle = new JLabel();
		jlBesaetzteStuehle.setText("belegte Sitzeplaetze: 0");
		jlBesaetzteStuehle.setBounds(10 + 130 + 10 + 30 + 30, 30, 150, 15);
		cont.add(jlBesaetzteStuehle);
		
		// Aenderungen-Uebernehmen-Button
		NeueWerte nw = new NeueWerte(this, jtAnzReihen, jtSitzeProReihe);
		jbAenderungenUebernehmen = new JButton();
		jbAenderungenUebernehmen.setText("ANWENDEN");
		jbAenderungenUebernehmen.setBounds(10 + 130 + 10 + 30 + 30 + 150 + 40, 2, 120, 50);
		jbAenderungenUebernehmen.addActionListener(nw);
		cont.add(jbAenderungenUebernehmen);
		
		
		// Objekte bei denen die Anzahl variieren kann
		JButton[] jbSitze = new JButton[Integer.valueOf(jtSitzeProReihe.getText()).intValue()];
		JLabel[] jlAnzFreiProReihe = new JLabel[Integer.valueOf(jtAnzReihen.getText()).intValue()];
		JLabel[] jlReihe = new JLabel[Integer.valueOf(jtAnzReihen.getText()).intValue()];
		
		reihenEinrichten(sitzeProReihe, jlReihe, jlAnzFreiProReihe, jbSitze);
		
		// Fenster jetzt anzeigen
		this.setVisible(true);
	}
	
	private void reihenEinrichten(int sitzeProReihe, JLabel jlUeberschriftReihe[], JLabel jlAnzFreiProReihe[], JButton jbSitz[]) {
		SitzKlick sk = new SitzKlick();
		
		for( int i = 0; i < jlUeberschriftReihe.length; i++ ) {
			// Wert der x-Koordinate der jeweiligen Reihe
			int ausrichtungLinks = 10 + (i * (REIHENBREITE + 10));
			// Reihennr, anzeigen
			jlUeberschriftReihe[i] = new JLabel();
			jlUeberschriftReihe[i].setText("Reihe " + (i+1));
			jlUeberschriftReihe[i].setBounds(ausrichtungLinks + 10, 80, REIHENBREITE, 13);
			cont.add(jlUeberschriftReihe[i]);
			// Anzahl der freien Plätze am unteren Rand des Anwendungsfensters anzeigen
			jlAnzFreiProReihe[i] = new JLabel();
			jlAnzFreiProReihe[i].setText("" + sitzeProReihe + " frei");
			jlAnzFreiProReihe[i].setBounds(ausrichtungLinks, this.getHeight() - 50, REIHENBREITE, 13);
			cont.add(jlAnzFreiProReihe[i]);
			// Buttons, die die Sitze darstellen, platzieren
			for( int j = 0; j < jbSitz.length; j++ ) {
				jbSitz[j] = new JButton();
				jbSitz[j].setText("R:" + (i+1) + " S:" + (j+1));
				int buttonhoehe = 30;
				jbSitz[j].setBounds(ausrichtungLinks, 100 + (j * (10 + buttonhoehe)), REIHENBREITE, buttonhoehe);
				jbSitz[j].setBackground(Color.GREEN);
				jbSitz[j].addActionListener(sk);
				// ActionCommand?
				cont.add(jbSitz[j]);
			}
		}
	}
	
	public static void main(String[] args) {
		new Anwendungsfenster();
	}

}

NeueWerte:
Code:
package version1;

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

import javax.swing.JTextField;

public class NeueWerte implements ActionListener {

	Anwendungsfenster anw;
	JTextField jtAnzahlDerReihen;
	JTextField jtSitzeProReihe;
	
	public NeueWerte(Anwendungsfenster anw, JTextField anzDerReihen, JTextField sitzeProReihe) {
		this.anw = anw;
		this.jtAnzahlDerReihen = anzDerReihen;
		this.jtSitzeProReihe = sitzeProReihe;
	}
	
	public void actionPerformed(ActionEvent arg0) {
		System.out.println("Uebernehmen!");
		anw.interfaceAufbauen(Integer.valueOf(jtAnzahlDerReihen.getText()).intValue(), Integer.valueOf(jtSitzeProReihe.getText()).intValue());
	}

}

SitzKlick
Code:
package version1;

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

public class SitzKlick implements ActionListener {
	

	public void actionPerformed(ActionEvent a) {
		System.out.println("ID: " + a.getID()); // bringt micht nicht weiter
	}

}
 
Hallo,

soweit ich das verstanden habe hast du zwei Belange:

-> Du möchtest die Farbe der Sitze(Buttons) ändern können.
Mit a.getSource() und einem Cast zu JButton kannst du darauf wie gewohnt setBackground() anwenden.

((JButton)a.getSource()).setBackground()

-> Das zweite Problem ist, du möchtest die Anzeige aktualisieren.
Dafür gehst du einfach die Arrays durch in denen du die JButtons gespeichert hast. Und zählst die Anzahl der freien oder belegten und änderst die Anzeige.

Hinweis: Damit die Sitze auch wieder freigegeben werden können, einfach im Listener per if zuerst die aktuelle Farbe abfragen, wenn sie grün ist rot zuweisen und umgekehrt.


Vg Erdal
 
Hallo.

Hallo,

soweit ich das verstanden habe hast du zwei Belange:

-> Du möchtest die Farbe der Sitze(Buttons) ändern können.
Mit a.getSource() und einem Cast zu JButton kannst du darauf wie gewohnt setBackground() anwenden.

((JButton)a.getSource()).setBackground()
Also das hat schon mal super geklappt! :)


-> Das zweite Problem ist, du möchtest die Anzeige aktualisieren.
Dafür gehst du einfach die Arrays durch in denen du die JButtons gespeichert hast. Und zählst die Anzahl der freien oder belegten und änderst die Anzeige.
Hier verstehe ich nicht, wieso ich nicht wieso ich nicht einfach die .setText-Methode anwenden kann.
Mein Code der Klasse SitzKlick sieht jetzt in etwa so aus:
Code:
public class SitzKlick implements ActionListener {
	
	JLabel[] freiProReihe;
	
	public SitzKlick(JLabel[] freiProReihe) {
		this.freiProReihe = freiProReihe;
	}
	

	public void actionPerformed(ActionEvent a) {
		System.out.println("Button / Sitz geklickt!");
		int reihenID = zahlAusString(a.getActionCommand());
		int frei = zahlAusString(freiProReihe[reihenID].getText());
		// Hintergrundfarbe des jeweiligen Buttons ändern 
		if(((JButton) a.getSource()).getBackground() == Color.GREEN) {
			((JButton) a.getSource()).setBackground(Color.RED);
			freiProReihe[reihenID].setText("" + frei-- + " frei");
		}
		else {
			((JButton) a.getSource()).setBackground(Color.GREEN);
			freiProReihe[reihenID].setText("" + frei++ + " frei");
		}
		// REPAINT?
	}
...
}
Warum kann ich an der Stelle // Repaint nicht freiProReihe[reihenID].repaint() anwenden? Auch ein repaint auf die ganze Anwendungsfenster-Klasse hat nichts gebracht.
Dabei soll doch nur ein simpler Text geändert werden?! :(

Muss ich da echt noch mal mit ner Schleife in der Anwendungsfenster-Klasse jeden Button abfragen?


MfG Gerrit
 
Wie sieht die Methode Zahlausstring aus? Und zweitens welches Array übergibst du dem Konstruktor der Klasse Sitzklick?


Vg Erdal
 
Wie sieht die Methode Zahlausstring aus? Und zweitens welches Array übergibst du dem Konstruktor der Klasse Sitzklick?
Das Array jlAnzFreiProReihe das in Anwendungsfenster eingerichtet wird.
Allerdings übergebe ich das, bevor ich in einer Schleife alle Felder des Arrays einrichte.
Also vor:
Code:
		for( int i = 0; i < jlUeberschriftReihe.length; i++ ) {
			// Anzahl der freien Plätze am unteren Rand des Anwendungsfensters anzeigen
			jlAnzFreiProReihe[i] = new JLabel();

Habe das Package mal aufn Server gepackt: Direktlink zur ZipDatei

Irgendwie habe immer mehr das Gefühl, ich bin total falsch an die Sache ran gegangen. :(


Die Methode zahlAusString
Code:
	// alle Zahlen eines Strings zu einem Int zusammensetzen: aus (String) ab5cd6f7 wird (int) 567
	private int zahlAusString(String str) {
		if( str != null && str.length() > 0 ) {
			StringBuffer sbInt = new StringBuffer();
			for(int i = 0; i < str.length(); i++) {
				if(Character.isDigit(str.charAt(i)))
					sbInt.append(str.charAt(i));
			}
			System.out.println("" + Integer.parseInt(sbInt.toString()));
			return Integer.parseInt(sbInt.toString());
		}
		else
			return 0;
	}
 
Du hast in der Methode actionPerformed() die Post-(In/De)krement Operatoren benutzt. Wenn du diese mit Prä-(In/De)krement Operatoren ersetzt, funktioniert die Anzeige der Reihenwerte ;) . Ein Zeichnen mit repaint() ist nicht notwendig.


Vg Erdal
 
Zuletzt bearbeitet:
Du hast in der Methode actionPerformed() die Post-(In/De)krement Operatoren benutzt. Wenn du diese mit Prä-(In/De)krement Operatoren ersetzt, funktioniert die Anzeige der Reihenwerte ;) . Ein Zeichnen mit repaint() ist nicht notwendig.
Tut mir leid, ich verstehe deine Antwort leider nicht :(


Jedenfalls habe ich alle Probleme lösen können.

Damit das Zählen klappt habe ich in SitzKlick aus "frei++" --> "++frei" gemacht.
Dann klappt's auch :)

Das zweite was noch zu tun war:
nachdem in Anwendungsfenster alle Komponenten dem Container hinzugefügt wurden, fehlten noch
Code:
this.validate();
this.repaint();

Dann geht alles :)

Danke! MfG Gerrit
 
Genau das habe ich gemeint.
frei++ heißt Postinkrement, ++frei Präinkrement

Stimmmt repaint() und validate() sind notwendig wenn du die Anzahl der Reihen und Stühle änderst.


Vg Erdal
 
Zurück