AWT Eventhandling

MisterB

Mitglied
Hallo zusammen,

studienbedingt muss ich mich derzeit mit AWT und Eventhandling beschäftigen. Da ich allerdings urspünglich aus der Visual Studio Welt komme, bin ich was das erstellen von GUIs betrifft dementsprechend verwöhnt.
Ich bin mittlerweile dahinter gekommen das Java einem unterschiedliche Konzepte zum Abfangen von Events zur Verfügung stellt, Schnittstelle implementieren, Vererben und Anonyme Klassen. Vom derzeitgen Wissensstand aus halte ich den Weg über Anonymeklasse momentan für den flexibleren und daher auch besseren Weg.

Ich habe also ein Frame und bin gerade dabei eine seperate Klasse für die Menüleiste mit Leben zufüllen. Dort stehen dann so Dinge drin wie (Das ist natürlich nur ein kleiner Auszug aus dem Quellcode um das Problem darstellen zu können).

Java:
public mubMain() {
    Menu mnuSpiel = new Menu("Spiel");
    MenuItem mitNeu = new MenuItem("Neues Spiel");
    mnuSpiel.add(mitNeu);
    this.add(mnuSpiel);
    mitNeu.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent AE) {
            System.out.println(AE.getActionCommand());
        }
    });
}

Ich erstelle also alles an Elementen was benötigt wird und hänge einen ActionListener ran. Die so angefertigte Klasse instanziere ich dann in einem Frame-Object in welchem sich auch die Main befindet und hänge es ein.

Was ich mich jetzt frage ist, wie komme ich von hier aus an andere Steuerelemente auf dem Frame. Zum Beispiel Beschriftungen eine Labels ändern etc.???:L

Wäre wirklich sehr nett wenn mir jemand helfen könnte. Danke im voraus. 🙂
 
Ich erstelle also alles an Elementen was benötigt wird und hänge einen ActionListener ran. Die so angefertigte Klasse instanziere ich dann in einem Frame-Object in welchem sich auch die Main befindet und hänge es ein.

Was ich mich jetzt frage ist, wie komme ich von hier aus an andere Steuerelemente auf dem Frame. Zum Beispiel Beschriftungen eine Labels ändern etc.???:L

Du willst Beschriftungen ändern wenn du auf ein menü Knopf drückst?:bahnhof:

Normalerweise hat man einen Controller oder ein Command welches regelt was passiert wenn man xyz drückt.

Observer (Entwurfsmuster) ? Wikipedia
und
Model View Controller ? Wikipedia
 
Mit mubMain.this.variablenName
(oder andersrum was die ersten beiden Teile angeht, da vertue ich mich oft^^)

Ich finde persönlich besser die Klasse, zu der die Komponenten hinzugefügt werden, zB ActionListener implementieren zu lassen und mit

JComponent.addActionListener(this);

die Klasse das EventHandling machen zu lassen, aber für einen einzelnen Button lohnt sich das natürlich nicht^^ Aber bei mehreren MenuItems kann sich das denke ich schon lohnen^^ Innerhalb der einen actionPerformed-Methode kann man ja mit ActionEvent.getActionCommand() abfragen, welches Item gedrückt wurde.
 
Ich hoffe, die "allgemein akzeptierte" Variante ist nicht die, dass man nach jedem erzeugten Button etc. erstma ne Annonyme Klasse baut? Dass man bei größeren Softwares das nach MVC macht, ist klar, aber für ein kleines Menü für ein kleines Spielchen oder ähnliches wäre mir das zu viel drumrum^^
 
Ich hoffe, die "allgemein akzeptierte" Variante ist nicht die, dass man nach jedem erzeugten Button etc. erstma ne Annonyme Klasse baut? Dass man bei größeren Softwares das nach MVC macht, ist klar, aber für ein kleines Menü für ein kleines Spielchen oder ähnliches wäre mir das zu viel drumrum^^

Versteh nicht was du meinst? Aber ja so macht man es...
Besser als 100 if Abfragen mit getActionCommand
 
Mich störts beim Erstellen der GUI, wenn immer die ganzen Klassen im Weg stehen^^ Gibt ja auch Fälle, wo man zB nur den ActionCommand an ne Methode weitergeben muss.. Ist denke ich mal ne Geschmackssache^^
Vllt kann der TO ja aus den Argumenten lernen 🙂
 
Mich störts beim Erstellen der GUI, wenn immer die ganzen Klassen im Weg stehen^^ Gibt ja auch Fälle, wo man zB nur den ActionCommand an ne Methode weitergeben muss.. Ist denke ich mal ne Geschmackssache^^
Vllt kann der TO ja aus den Argumenten lernen 🙂

Mach mal ein Beispiel ich verstehe deine Argumente nicht.
 
Selbstverständlich ein sehr stumpfes Beispiel^^ Aber das gehört zu meinem Argument, dass man vllt nur den Text des Buttons oder dessen ActionCommand übermitteln muss an eine Methode^^

Java:
public class Action extends JFrame implements ActionListener {
	
	JLabel lbl;
	
	Action() {
		this.setSize(400, 400);
		this.setLayout(new FlowLayout());
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		
		JButton btn = new JButton("Hallo");
		btn.addActionListener(this);
		this.add(btn);
		
		btn = new JButton("Welt");
		btn.addActionListener(this);
		this.add(btn);
		
		btn = new JButton("!");
		btn.addActionListener(this);
		this.add(btn);
		
		lbl = new JLabel();
		this.add(lbl);
		
		this.setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		lbl.setText(e.getActionCommand());
		validate();
		repaint();
	}

	public static void main(String[] args) {
		new Action();
	}
}
 
Warum sollte man sowas tun?^^ Nicht gerade sinvoll 😉. Listener stellen auch GUI-Controller dar!!!

Wie gesagt meistens folgt auf einen Button Druck ein Controller/Comman aufruf.
 
Naja, natürlich bietet sichs bei sowas schon an, das nach MVC zu lösen, aber sagen wir, du willst eine Liste mit Daten darstellen (jeder Datensatz hat seine eigene ID) und am Ende jeder Zeile steht ein Button mit nem x zum Löschen (und der ID als ActionCommand) und du willst dann die ID haben und die deiner Methode zum Löschen eines Datensatzes mitgeben^^ Da könnte man das so lösen wie bei dem Label-Text im Beispiel oben^^

Edit: Zeig mir bitte mal ein Beispiel, damit ich wirklich deine Skepsis nachvollziehen kann, dann hätte ich auch nachhaltig was gelernt in diesem Thread 😉
 
Zunächst einmal vielen herzlichen Dank für die vielen schnellen Antworten.🙂

Du willst Beschriftungen ändern wenn du auf ein menü Knopf drückst?:bahnhof:

Na ja, eigentlich nicht, das Beispiel sollte nur meine Fragestellung etwas illustrieren. Wenn ich allzu sehr auf das Problem eingehe und hier fertigen Code erhalten sollte, mosern die Tutoren wieder. Also habe ich etwas vom eigentlichen Problem abstrahiert damit ich mir wenigstens etwas Transferleistung zuschreiben darf. 🙂

Ich habe es mir jetzt einfach gemacht und alle GUI-Elemente in eine Klasse geschmissen, welche von Frame erbt. Sieht nach meinem dafürhalten zwar nicht allzu schön aus, erfüllt aber seinen Zweck.
 
Edit: Zeig mir bitte mal ein Beispiel, damit ich wirklich deine Skepsis nachvollziehen kann, dann hätte ich auch nachhaltig was gelernt in diesem Thread 😉

hier mal ein beispiel meinerseits sourcen liegen bei:

Der Teil der dich wahrscheinlich am meisten interessiert ist hier:
Ich mach das so :
Java:
public class InfoView extends JPanel{

	private JTextField  field;
	public InfoView(final KundenController controller){
		super();
		setBorder(BorderFactory.createTitledBorder("Kunde anlegen"));
		field = new JTextField();
		field.setPreferredSize(new Dimension(100,25));
		add(field);
		add(new JButton(new AbstractAction("Anlegen") {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				controller.addKunde(createKunde());
				field.setText("");
			}
		}));
		
		add(new JButton(new AbstractAction("Löschen") {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				controller.removeKunde(createKunde());
			}
		}));
	}
	
	private Kunde createKunde(){
		//Hier ne Factory oder Sosntiges benutzen
		Kunde k = new KundenImpl();
		k.setName(field.getText());
		return k;
	}
}


Anstatt

Java:
public class InfoView extends JPanel implements ActionListener{

	private JTextField  field;
	private KundenController controller;
	public InfoView(final KundenController controller){
		super();
		this.controller = controller;
		setBorder(BorderFactory.createTitledBorder("Kunde anlegen"));
		field = new JTextField();
		field.setPreferredSize(new Dimension(100,25));
		add(field);
		
		JButton buttonAnlegen = new JButton("Anlegen");
		buttonAnlegen.addActionListener(this);
		
		add(buttonAnlegen);
		
		JButton buttonRemove = new JButton("Löschen");
		buttonRemove.addActionListener(this);
		
		add(buttonRemove);
	}
	
	private Kunde createKunde(){
		//Hier ne Factory oder Sosntiges benutzen
		Kunde k = new KundenImpl();
		k.setName(field.getText());
		return k;
	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		if(ae.getActionCommand().equals("Anlegen")){
			controller.addKunde(createKunde());
			field.setText("");
		}else if(ae.getActionCommand().equals("Löschen")){
			controller.removeKunde(createKunde());
		}
		
	}
}

1. die ifs sind häßlich vor allem wenn man bedenkt es kommen noch mehr Elemente hinzu
2. wenn sich die Beschriftung des Buttons ändert musst du den rest auch nachziehen (Mehr Aufwand)
3. Außerdem kann jetzt von außen jeder die InfoView als ActionListener adden obwohl die InfoView KEINE Action darstellt.
 

Anhänge

wenn sich die Beschriftung des Buttons ändert musst du den rest auch nachziehen (Mehr Aufwand)

Das ist für mich am überzeugensten^^ Selbst wenn mans mit setActionCommand macht, hab ich schonma gemerkt, dass es ätzend sein kann (insbesondere, weil der Compiler einen hier nicht auf Tippfehler hinweist 😉)^^ Und beim Hinzufügen neuer Buttons etc. muss man immer durch die Gegend scrollen^^
 
Das ist für mich am überzeugensten^^ Selbst wenn mans mit setActionCommand macht, hab ich schonma gemerkt, dass es ätzend sein kann (insbesondere, weil der Compiler einen hier nicht auf Tippfehler hinweist 😉)^^ Und beim Hinzufügen neuer Buttons etc. muss man immer durch die Gegend scrollen^^

Du musst auch so sehen, dass ein ActionListener ein Controller darstellt und deine widgets z.B. JPanel sind eben keine Controller. Deshalb eher eine innere Klasse machen oder aber was ich am besten sind sind die anonymen Klassen übersichtlich und kurz.
 

Neue Themen


Zurück
Oben