Problem mit dynamisch erzeugtem ActionListener

Hallo :smile:

Ich schreibe gerade ein Java-Programm und habe ein grundsätzliches
Problem mit einem dynamisch erzeugten ActionListener.

Also:
In meiner Swing-Applikation sind Eingabefelder und ein JButton
„berechnen“. Außerdem gibt es noch einen JButton „Zeigen“, der
aber auf setVisible(false) gesetzt ist. Beim Start der Applikation
ist der „Zeigen“-Button also nicht sichtbar.

Klickt man auf „berechnen“, werden die Werte aus
den Eingabefeldern genommen und mit der Funktion „pruefen()“ auf
Gültigkeit geprüft. Sind die Werte okay, wird die Funktion
„berechnen()“ aufgerufen. In einem JLabel in der Swing-Oberfläche
wird dann das Ergebnis angezeigt. Zusätzlich wird jetzt der
„Zeigen“-Button auf setVisible(true) gesetzt und ihm wird ein
ActionListener verpasst, dem 3 dynamisch erzeugte Werte übergeben
werden. Der ActionListener soll ein neues Fenster öffnen, in dem
diese 3 Werte grafisch dargestellt werden. Deswegen heisst der
ActionListener „Darsteller“ (also ich habe eine weitere Klasse
namens „Darsteller“).

Nun kommt mein Problem:
Wenn ich zum ersten Mal auf „berechnen“ klicke, läuft alles
wunderbar, das neue Fenster geht auf. Klicke ich noch einmal
auf „berechnen“, gehen 2 neue Fenster auf. Klicke ich noch einmal
auf „berechnen“, gehen 3 neue Fenster auf, usw. Der JButton hat jetzt
also 3 ActionListener (bzw. so viele je nachdem wie oft ich auf
den „berechnen“-Button klicke), obwohl er nur einen haben soll.

Ich muss diesen ActionListener aber in der Funktion „berechnen()“
erzeugen, weil ich erst hier Werte zur Übergabe habe.
Ich kann den Listener also noch nicht in er Oberfläche an den JButton
hängen!

Ich habe auch schon versucht, den ActionListener über
removeActionListener(…) erst wieder zu entfernen und dann wieder
mit addActionListener(…) die neuen Werte zu übergeben, der alte
ActionListener wird aber irgendwie nicht gelöscht.

Hier mal beispielhaft das Programm, falls jemand nicht verteht was ich
meine:

import ...;

class Test extends JFrame
{
 private Darsteller darsteller;

 public Test()
 {
 // Erzeugung der Oberfläche mit Eingabefeldern usw.
 ...

 JButton btnRechnen = new JButton("berechnen");
 btnRechnen.addActionListener(.....); // ruft pruefen() auf
 ...

 JButton btnZeigen = new JButton("zeigen");
 btnZeigen.setVisible(false);
 ...
 }

 public void pruefen()
 {
 int x1, x2, x3;
 ...

 // Wenn alle Eingaben gültig
 berechnen(x1, x2, x3); // x1,x2,x3 haben hier gültige Werte
 }

 public void berechnen(int p1, int p2, int p3)
 {
 int wert1, wert2, wert3;

 // eine Berechnung mit den übergebenen Parametern p1,p2,p3
 ...

 // wert1,wert2,wert3 haben hier Werte, die grafisch darstellbar
 // sein sollen. Der "Zeigen"-Button wird also sichtbar gemacht
 // und bekommt den ActionListener mit den aktuellen Werten
 btnZeigen.removeActionListener(darsteller);
 darsteller = new Darsteller(wert1,wert2,wert3);
 btnZeigen.addActionListener(darsteller);
 btnZeigen.setVisible(true);
 }
}

Hat jemand eine Idee, was ich falsch mache?
Oder gibt es eine Lösung, den ActionListener zwar in der Oberfläche
zu erzeugen (z.B. mit Dummy-Werten, der Button ist beim Start ja eh
nicht sichtbar), und dann in Funktion berechnen() diesem trotzdem
dynamisch Werte mitzugeben?
Über Hilfe / Denkanstöße würde ich mich freuen :smile:

mfG PoiSoN

Hallo,

Du kannst ja testen, ob getActionListener() null zurückgibt und nur dann den neuen ActionListener erzeugen. - wenn Du Dein schlechtes Design unbedingt retten willst.

Was ich allerdings nicht verstehe: warum darf Dein Button den ActionListener nicht schon vorher haben. Da er ja unsichtbar ist, kann auch nichts passieren.

Gruß

Peter

Hallo,

Hallo Peter,

Du kannst ja testen, ob getActionListener() null zurückgibt
und nur dann den neuen ActionListener erzeugen.

Ich MUSS aber JEDES MAL wenn auf „berechnen“ geklickt wurde,
einen neuen ActionListener für den Button „zeigen“ erzeugen, weil die
aktuellen Werte für den Listener ja erst NACH Klick auf den
Button „berechnen“ generiert werden. Es sind jedes Mal andere!

  • wenn Du Dein
    schlechtes Design unbedingt retten willst.

Warum schlechtes Design? Was kann ich besser machen?
Dem Button „zeigen“ gleich von Anfang an einen ActionListener zu geben
und dann nichts mehr zu tun, geht nicht, da der Listener dann
nie die aktuellen Werte bekommt sondern nur die, die ich am
Anfang übergeben habe…!

Was ich allerdings nicht verstehe: warum darf Dein Button den
ActionListener nicht schon vorher haben. Da er ja unsichtbar
ist, kann auch nichts passieren.

Das geht nicht. Beispiel: Der Button „zeigen“ ist unsichtbar. Ich gebe
ihm hier schon den ActionListener. Ich klicke auf den Button „berechnen“.
Die Werte in den Eingabefeldern werden überprüft und anhand dieser neue
Werte ermittelt. Und genau diese neuen Werte soll der ActionListener
von Button „zeigen“ bekommen!! Wie, wenn ich dem Button nur einmal am
Anfang den ActionListener gebe?

Meine Idee an der Stelle war halt, den alten ActionListener mit
removeActionListener(…) zu entfernen und dem Button einen neuen
ActionListener mit den neu ermittelten Werten zu geben.
Aber das mit dem removen ging ja leider nicht (warum auch immer)…

mfG PoiSoN

Hallo,

Du musst doch nicht die Werte dem Actionlistener im Konstruktor übergeben.
int a, b, c, d;

berechnenButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
berechnen();
}
});
zeigenButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
zeigen();
}
});

private void berechnen() {
hier holst Du die Werte in den Speicher
a = Integer.parseInt(erstesTextfeld.getText());

// berechnungen anstellen und wieder speichern z.B. in d
}
private void zeigen() {
// neues Fenster aufmachen und a, b, c, d anzeigen.
}

Fertig. Ohne irgendeinen ActionListener neu zu überschreiben.

Gruß

peter