PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Das Grundproblem: dynamische Variablennamen


Zarathustra
2004-09-18, 15:05:46
Das taucht zurzeit schon wieder bei mir auf, diesmal in Java...

Diese Art von Problem war für mich immer schwer zu umgehen:

Ich will eine Gruppe von Schaltflächen (JButton's) dynamisch erstellen. Ich weiss vorher nicht, wieviele es sein werden oder welchen Name sie haben werden. (Das mit den Namen ist an sich kein Problem, sogar namenlose Buttons sind möglich.)
Dazu müsste ich gleichzeitig (dynamisch) Variablennamen erzeugen (z.B.als Strings) und diese dann den Buttons zuweisen, damit ich auch Listener dranhängen oder deren Namen nachträglich mit setLabel(String) ändern kann!
Aber wie mache ich das?


Eine Menge von Buttons fest zu erstellen und nur die Namen dynamisch hinzuzufügen, ist keine gute Option.

KiBa
2004-09-18, 15:19:29
ein dynamisches array? die namen sind dann die indices. oder eine map von string auf buttons, die dynamisch erweitert wird...

Zarathustra
2004-09-18, 21:16:48
hmm Dass das mit den Indizes geht wusste ich nicht, muss man erstmal drauf kommen :D

Wie funktioniert das mit den Maps? Was ist das?

HellHorse
2004-09-19, 01:37:23
Wie funktioniert das mit den Maps? Was ist das?
Maps bilden Schlüsselobjekte auf Wertobjekte ab (English zu Deutsch Übersetzungen regeln).
Im gegebenen Fall könntest du also Namen (Strings) auf Buttons abbilden. Du kannst auch verschiedene Namen auf den gleichen Button abbilden.


Map<String, JButton> buttons = new HashMap<String, JButton>(); //Map erstellen
JButton aButton = new JButton("Klick me!"); //Button erstellen
buttons.put("some cool String", aButton); //Abblidung von "some cool String" auf aButton erstellen
buttons.put("another cool String", aButton); //Abblidung von "another cool String" auf aButton
....
JButton theSameButton = buttons.get("some cool String"); // holen was den "dynamischen Namen" "some cool String" hat


Hatten wir nicht mal schon so was?

Zarathustra
2004-10-15, 15:27:40
So, nun hab ich es wie gesagt per ArrayList gemacht.

Nun erstelle ich zu jedem JBUtton noch eine JComboBox und zu der wiederum einen Listener:

//für gewählte Tabelle die JButtons und ComboBoxes der Spalten aus den Arraylists in die Oberflaeche einbauen
for(int i=0; i < columns.size(); i++)
{
//JButton in die Liste setzen x, y, w, h, wx, wy
gui.dataPanel.addListFrameComponent((JButton)columns.get(i), 0, (2*i), 1, 1, 0, 0);
System.out.println("Eintrag " + i + " hinzugefügt.");

//DropDown-Liste mit den Datensätzen einfuegen
sqlCommand = "SELECT `" + ((JButton)columns.get(i)).getLabel() + "` FROM " + selection;
System.out.println("Building comboBox: " + sqlCommand);
rs = getStatement().executeQuery(sqlCommand);

box = new JComboBox();
rs.last();
if(!(rs.getRow() == 0))
{
rs.first();
while(rs.next())//aus den Spaltennamen die JButtons in ArrayList erzeugen und aufreihen
{
String item = rs.getString(1);
box.addItem(item);
System.out.println(item + " in ComboBox eingefügt.");
}
}
else
System.out.println("rs.getRow() " + rs.getRow());

//ActionListener für die BOX
box.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent e)
{
for(int j=0; j < comboBoxes.size(); j++)
{
if(!((JComboBox)comboBoxes.get(j) == box))
{
int sel = box.getSelectedIndex();
if(!(sel < 0))
((JComboBox)comboBoxes.get(j)).setSelectedIndex(sel);//Item(rs.getString(1));
else
System.out.println("SELECTED INDEX PROBLEM!");
System.out.println("SEL " + sel);
}
}
}
});
box.setEditable(true);
comboBoxes.add(box);
gui.dataPanel.addListFrameComponent(box, 0, ((2*i)+1), 1, 1, 0, 0);
}

Die JComboBoxes werden im Wechsel mit den (noch Listener-losen) JButtons untereinander aufgereiht.
Das Problem: Warum reagiert NUR die LETZTE Combobox?

ethrandil
2004-10-15, 16:36:14
Hi, es wird immer das letzt Element ausgewählt, egal was man drückt, richtig?

dann könnte helfen:
statt

//ActionListener für die BOX
box.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent e)
{
for(int j=0; j < comboBoxes.size(); j++)
{
if(!((JComboBox)comboBoxes.get(j) == box))
{
int sel = box.getSelectedIndex();
if(!(sel < 0))
((JComboBox)comboBoxes.get(j)).setSelectedIndex(sel);//Item(rs.getString(1));
else
System.out.println("SELECTED INDEX PROBLEM!");
System.out.println("SEL " + sel);
}
}
}
});



//ActionListener für die BOX
box.addActionListener(new
ActionListener(){
public void actionPerformed(ActionEvent e){
JComboBox box = (JComboBox)e.getSource();
System.out.println("SEL " + box.getSelectedIndex());
}
});

Ich weiß ehrlich gesagt nicht was du mit deinem Code genau machen willst... irgendwie willst du comboboxen aus ner SQL-DB erstellen... okay... Das Durchlaufen der Schleife im Actionlistener ist unnötig, wenn du da auf die Combobox zugreifen willst.
Außerdem würde ich Bedingungen wie (!(rs.getRow() == 0)) als (rs.getRow() != 0) oder (!(sel < 0)) als (sel >= 0) schrieben. find ich übersichtlicher.

- Eth

Zarathustra
2004-10-15, 18:32:05
Hi, es wird immer das letzt Element ausgewählt, egal was man drückt, richtig?

dann könnte helfen...

Nein, nur die unterste (=letzte) Combobox reagiert überhaupt auf ein Auswählen. Dann allerdings wird wie gewünscht bei allen anderen Boxes der richtige Index ausgewählt:

Und das durchlaufen der Schleife im Actionlistener soll bewirken, dass bei allen anderen Comboboxes, die sonst noch erstellt wurden (also mit dort aufgereiht wurden), bei einer Auswahl (->ActionListener) auch dort derselbe Index ausgewählt wird.
Hab ich vergessen zu erwähnen...

Zarathustra
2004-10-20, 15:16:39
sorry aber... *push*

Ich möchte hinzufügen, dass bei den Comboboxes, bei denen der Listener nicht reagiert, auch selbst nicht auf eine Auswahl eines ihrer eigenen Elemente reagieren!

Und
if(!((JComboBox)comboBoxes.get(j) == box))
soll eigentlich nur verhindern, dass dieselbe Box ihren eigenen Index nochmal zugewiesen bekommt, ist eigentlich überflüssig ich weiss. :rolleyes:

Hat zu oben wer ne Idee?
Das Problem besteht noch! (Hatte in letzter Zeit keine Zeit nochmal reinzuschauen, aber jetzt...)

mithrandir
2004-10-20, 15:56:24
Dere!

Und
if(!((JComboBox)comboBoxes.get(j) == box))
soll eigentlich nur verhindern, dass dieselbe Box ihren eigenen Index nochmal zugewiesen bekommt, ist eigentlich überflüssig ich weiss. :rolleyes:
Ich habe das jetzt nur überflogen, ober vergleichst du hier zwei ComboBox-Objekte mit == ? Das liefert dann natürlich IMMER true, im Gegensatz zur equals()-Methode, die ich dann einsetzen würde.

bye, mith

HellHorse
2004-10-20, 16:47:55
Dere!


Ich habe das jetzt nur überflogen, ober vergleichst du hier zwei ComboBox-Objekte mit == ? Das liefert dann natürlich IMMER true, im Gegensatz zur equals()-Methode, die ich dann einsetzen würde.

bye, mith
Korrigier' mich, wenn ich falsch liege, aber afaik overridet weder JComboBox noch irgendeine Superklasse (ausser Object) equals(). Es ist hier ist es also egal, ob man equals() oder == verwendet.


Sollte das gleiche machen, ist aber verständlicher.

if(comboBoxes.get(j) != box)

mithrandir
2004-10-20, 16:54:14
Dere!

Du hast natürlich recht, vergesst mein Posting. Da war ich wohl komplett von der Rolle...

bye, mith

Pinoccio
2004-10-20, 17:18:32
Korrigier' mich, wenn ich falsch liege, aber afaik overridet weder JComboBox noch irgendeine Superklasse (ausser Object) equals(). Es ist hier ist es also egal, ob man equals() oder == verwendet.

Also == ist echt verpönt in Java. Immer equals! Und die üblichen fertigen Klassen, also wohl auch JComboBox, solltern equals immer geeignet überrschreiben.

mfg Sebastian

Zarathustra
2004-10-20, 17:20:16
Hmm...
Ich hab jetzt mal diese zeile wegen überflüssig ebtfernt und es geht! Mal testen ob es mit equals auch ginge...)

nur wenn ich einen Eintrag weit unten in der Combobox wähle, detoniert irgendwie das System.out mit meinen Fortschrittsmeldungen in einer Schleife, keine Ahnung, muss erstmal gucken woran das liegen kann...


Andere Frage: Wie kann ich die Breite einer Combobox festlegen? Die, deren Einträge etwas länger sind, sprengen schnell mal den Rahmen...
Oder muss ich da das JPanel behandeln wo sie drinliegen?

HellHorse
2004-10-20, 17:59:26
Also == ist echt verpönt in Java. Immer equals!
Also wenn ich die Referenzen zweier Objekte vergleichen will, soll ich equals() verwenden und darauf vertauen, dass es nicht overridet wurde? :|

Und nie vergessen auch hashCode() zu overriden wenn man schon dabei ist. ;)
Und die üblichen fertigen Klassen, also wohl auch JComboBox, solltern equals immer geeignet überrschreiben.
Wie sieht denn ein geeignetes equals für JComboBox deiner Meinung nach aus und was würde man daraus gewinnen?

Pinoccio
2004-10-20, 18:09:32
Also wenn ich die Referenzen zweier Objekte vergleichen will, soll ich equals() verwenden und darauf vertauen, dass es nicht overridet wurde? :|
Und nie vergessen auch hashCode() zu overriden wenn man schon dabei ist. ;)
1.) http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
Vielleicht reden wir auch etwas aneinander vorbei ...
2.) Dito.

mfg Sebastian

Zarathustra
2004-10-20, 18:18:49
ACH du Scheisse!


System.out.println("Erstelle ActionListener für ComboBox Nr." + (i+1) + " von " + columns.size() + "...");
box.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//int sel = ((JComboBox)e.getSource()).getSelectedIndex();
System.out.println("ComboBox reagiert...");
System.out.println("comboBoxes.size() " + comboBoxes.size());

//durchläuft alle Boxes, um sie auf denselben Index zu setzen
for(int j=0; j < comboBoxes.size(); j++)
{
int sel = ((JComboBox)e.getSource()).getSelectedIndex();
if(sel >= 0)
((JComboBox)comboBoxes.get(j)).setSelectedIndex(sel);
else
System.out.println("SELECTED INDEX PROBLEM!");
System.out.println("SEL " + sel);
System.out.println("index j " + j);
}
System.out.println("... ComboBox hat reagiert!");
}
});
System.out.println("... OK.");


Kann es sein, dass das "setSelectedIndex(sel)" auch den ActionEvent auslöst?? :eek:
Arghl! Welche Alternativen gibt es? Ich glaib es gibt keinen ComboBoxListener der sowas... :frown:

HellHorse
2004-10-20, 19:13:56
Vielleicht reden wir auch etwas aneinander vorbei ...
Scheint so ...

HellHorse
2004-10-20, 19:15:42
Kann es sein, dass das "setSelectedIndex(sel)" auch den ActionEvent auslöst?? :eek:
Arghl! Welche Alternativen gibt es? Ich glaib es gibt keinen ComboBoxListener der sowas... :frown:
Warum setzt du überhaupt den selektierten Index bei einer JComboBox?

Zarathustra
2004-10-20, 21:09:00
Ich hab (hatte?) vor, auf diese Weise den Datensatz auszuwählen:
Erst in einer JList die Tabelle, dann in einer Spalte daneben zu jeder Tabellenspalte eine Combobox, in der der Datensatz ausgewählt wird, indem in den anderen Comboboxes die anderen Daten dieses Datensatzes anzeigen, sodass man danach den zur Combobox gehörenden Button anklickt, und so den entsprechenden Eintrag verändern kann.
Kling vielleicht komisch, weiss nicht wie ichs sonst schnell erklären kann...

HellHorse
2004-10-20, 21:39:13
Kann es sein, dass das "setSelectedIndex(sel)" auch den ActionEvent auslöst?? :eek:
Is so, steht auch so in der Doku (http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComboBox.html#addActionListener(java.awt.event.ActionListener))
The ActionListener will receive an ActionEvent when a selection has been made. If the combo box is editable, then an ActionEvent will be fired when editing has stopped.

Ich kann dir leider nicht helfen, denn ich habe weder dein Problem noch deinen Code verstanden.

zeckensack
2004-10-20, 22:07:53
ACH du Scheisse!
Kann es sein, dass das "setSelectedIndex(sel)" auch den ActionEvent auslöst?? :eek:
Arghl! Welche Alternativen gibt es? Ich glaib es gibt keinen ComboBoxListener der sowas... :frown:removeActionListener, dann setSelectedIndex, und dann wieder addActionListener.
Sollte klappen. Das ActionListener-Objekt sollte dann allerdings irgendwo dauerhaft geparkt werden. Zur Not kann man es auch mit getListeners ein Array der registrierten ActionListener-Objekte kriegen, aber ich glaube das willst du nicht wirklich ...

HellHorse
2004-10-20, 22:20:56
Oder man programmiert es von Anfang an so, dass es keinen Unterschied macht, ob ein User oder das Programm selektiert ....

zeckensack
2004-10-21, 01:46:21
Oder man programmiert es von Anfang an so, dass es keinen Unterschied macht, ob ein User oder das Programm selektiert ....Das wäre natürlich noch besser ;)