# JList füllen mit LinkedList-Elementen



## Fabian030 (22. Mai 2009)

ich hab ein klassisches MVC aufgebaut.

im model hab ich meine LinkedList mit Kundendaten (Kundennummer und Kundenname)
und eine methode

public void kundenAusgeben() {
String alleKunden = null; 
for (Kunde i : kundenListe) {
alleKunden += ""+i + "\n";
}
if (alleKunden == null){
controlString = "keine Kunden vorhanden";
fireModelEvent2(new ModelEvent(this));
}
else {
lastString = ""+alleKunden;
fireModelEvent(new ModelEvent(this));
}
}

controlString und lastString werden über return-String-Methoden zurückgegeben.


im Controller sieht der dazugehörige aufruf dann so aus:

if(e.getActionCommand().equals(Mete2View.KUNDEN)){
((Mete2Model)getModel()).kundenAusgeben();
}


und in der View passiert dann das:
JTextArea texfeld = new JTextArea(10, 100);

public void modelChanged(ModelEvent e) {
textfeld.setText((((Mete2Model) getMvcModel()).getLastString()));
textfeld.setText((((Mete2Model) getMvcModel()).getControlString()));
}

----------------

klappt super mit dem JTextArea

nun will ich aber den inhalt aus der LinkedList (also die Kundennummer und den Kundennamen) in ner JList darstellen (um dann später auf einen eintrag zu klicken und das was für den eintrag in einer anderen klasse - in einer hashmap - gespeichert wurde in einem zweiten JList anzuzeigen)

hat jemand ne idee wie das funktioniert? :/
JList mag nur Object[]-Datentypen aufnehmen und keine Strings oder gar meine ganze LinkedList


----------



## 0001001 (22. Mai 2009)

Das ist eigentlich ganz einfach.
Zwei Möglichkeiten:
1. du schreibst dir ne Methode, die aus deiner LinkedList ein DefaultListModel macht und das dann der JList zuweist. Also einfach mit ner Schleife über alle Einträge der LinkedList laufen und jeden Eintrag dem DefaultListModel zuweisen. Am Schluss übergibst du das Model dann der JList mit der Methode setModel(deinModel);

2. Du erweiterst das DefaultListmodel und überschreibst die Methoden dort und fügst ne neue Methode hinzu die mit ner LinkedList umgehen kann.


----------



## Gast2 (22. Mai 2009)

```
//1. Möglichkeit
JCombobox box = new JCombobox(LinkedList#toArray())
//2te
box.setModel(new DefaultComboboxModel(LinkedList#toArray()))
```

Eventuell brauchst du aber einen eigenen Renderer für die Combobox


----------



## Fabian030 (22. Mai 2009)

keine Ahnung, was mir da die Combobox bei ner JList helfen soll ...  also im Moment noch nicht.
Aber die Sache mit dem DefaultListModel scheint interessant.
Ich werde mal schauen, ob ich meine LinkedList da reinpacken kann ...




```
public DefaultListModel getKunde(){
DefaultListModel kunden = null; 
for (Kunde i : kundenListe) {
//TODO ???
}
return kunden;
}
```


----------



## 0001001 (22. Mai 2009)

```
public DefaultListModel getKunde(){
DefaultListModel kunden = null; 
int counter = 0;
for (Kunde kunde : kundenListe) {
kunden.add(counter, kunde);
counter++;
}
return kunden;
}
```


----------



## Fabian030 (22. Mai 2009)

eine mögliche Lösung:

View:
unter modelChanged(Event e){
kundenListe.setListData((((Mete2Model) getMvcModel()).getKunden().toArray()));
}

Model:
public LinkedList <Kunde> getKunden(){
	LinkedList<Kunde> kunden = kundenListe;
	return kunden;
}


Frage wäre jetzt, ob ich mit nem ActionListener auf die Elemente in der JList auch rausfinden kann, was hinter den Einträgen für diese Einträge gespeichert ist ...

aber danke soweit für die Hilfe. 
:toll:


----------



## Fabian030 (22. Mai 2009)

0001001 hat gesagt.:


> ```
> public DefaultListModel getKunde(){
> DefaultListModel kunden = null;
> int counter = 0;
> ...



@kunden.add(counter, kunde); // ===> kunden ist an dieser Position immer NULL und er spuckt somit immer n fehler aus beim ausführen - natürlich eine Null-Pointer-Exception.


----------



## Gast2 (22. Mai 2009)

Sorry falsch gelesen, aber die Lösung stand doch trotzdem so gut wie da????
???:L???:L


```
//
JList list = new JList(LinkedList.toArray());

list.setListData(LinkedList.toArray())
```


----------



## Gast2 (22. Mai 2009)

Fabian030 hat gesagt.:


> @kunden.add(counter, kunde); // ===> kunden ist an dieser Position immer NULL und er spuckt somit immer n fehler aus beim ausführen - natürlich eine Null-Pointer-Exception.



ist ja wohl logisch oder ?? steht doch auch da kunden = null!!!!!!!!


----------



## Fabian030 (22. Mai 2009)

SirWayne hat gesagt.:


> ist ja wohl logisch oder ?? steht doch auch da kunden = null!!!!!!!!



hehe. sicher. is mir schon aufgefallen.
aber ich kann die defaultlist ja nicht einfach auf das erste element von der kundenListe (kundenListe.getFirst() setzen. 
aber irgendwas muss ich ja anfangs erstmal reinschreiben ... ???:L


----------



## Gast2 (22. Mai 2009)

1. Was ist das Problem wenn du die von mir genannten varianten nimmst???? musst doch nicht selber dein model füllen...
2. wie wärs mit DefaultListModel kunden = new DefaultListModel ();  
brauchst ja auch erstmal eine Instanz oder


----------



## Fabian030 (22. Mai 2009)

SirWayne hat gesagt.:


> 1. Was ist das Problem wenn du die von mir genannten varianten nimmst???? musst doch nicht selber dein model füllen...
> 2. wie wärs mit DefaultListModel kunden = new DefaultListModel ();
> brauchst ja auch erstmal eine Instanz oder



@1: keins. ich hab ja jetzt deine einfache lösung genutzt 
public LinkedList<Kunde> getListe(){
	return kundenListe;
}

und in der view sag ich einfach:
kundenListe.setListData((((Mete2Model) getMvcModel()).getListe().toArray())); 
(kundenListe ist die JList)

2. super idee. ich seh den wald vor lauter bäumen nicht mehr ... ;( (PS: siehe oben, es geht auch einfacher. ich glaub nicht, dass mir das DefaultListModel irgendwelche vorteile bringt, eh?)


----------



## Gast2 (22. Mai 2009)

Die Methode nimmt intern auch ein DefaultListModel ... Nur dass du das füllen nicht übernehmen musst.Also passt es so schon...

```
kundenListe.setListData((((Mete2Model) getMvcModel()).getListe().toArray()));
```


----------



## Fabian030 (22. Mai 2009)

SirWayne hat gesagt.:


> Die Methode nimmt intern auch ein DefaultListModel ... Nur dass du das füllen nicht übernehmen musst.Also passt es so schon...



achso? na das wusst ich nicht.  man lernt ja immer wieder dazu, deswegen sind wir hier :rtfm:

ich häng inzwischen an dem zweiten problem, dass ich eben ein eintrag der liste selektieren soll und dazugehörige werte auf einer zweiten JList ausgegeben werden sollen.
die sind in ner HashMap gespeichert ... 
aber hier gibt's ständig cast-probleme oder er mag meinen ListSelectionListener nicht und und und. :/

View:

```
ListSelectionListener listListener;

kundenListe.addListSelectionListener(listListener);

@Override
public void valueChanged(ListSelectionEvent event) {
	Kunde k = (Kunde)kundenListe.getSelectedValue();
	kontenListe.setListData((k.getKonten());
}
```

Klasse Kunde:

```
private HashMap <Integer, Konto> meineKonten = new HashMap <Integer, Konto> ();

public  HashMap<Integer, Konto> getKonten(){
	return meineKonten;
}
```

fehler bei setListData - und wenn ich wieder ein .ToArray() anhänge, will er kunde K casten in ne List oder LinkedList ... :bahnhof:


----------



## Gast2 (22. Mai 2009)

Fabian030 hat gesagt.:


> achso? na das wusst ich nicht.  man lernt ja immer wieder dazu, deswegen sind wir hier :rtfm:


oh stimmt gar net der nimmt ein AbstractListModel... aber passt scho 

mehr code??kompilierbares Bsp???

Was soll den das hier? Muss doch ein compile Fehler sein... 

```
kontenListe.setListData((k.getKonten());
```


EDIT:
suchst du das hier?

```
k.getKonten().values().toArray();
```


----------



## Fabian030 (23. Mai 2009)

musste ja einen compiler-fehler geben, sagte ich ja. 

letzteres dürfte sein, was ich gesucht habe ...
allerdings 

```
public void valueChanged(ListSelectionEvent event) {
	Kunde k = (Kunde)kundenListe.getSelectedValue();
	System.out.println("kunde: "+k);
	kontenListe.setListData(k.getKonten().values().toArray());
}
```

System.out.println("kunde: "+k);
wird nie erreicht. der listener schlägt anscheinend fehl und somit wird auch nie die valueChanged von der JList angeschupst.

View:

```
ListSelectionListener listListener;
...
...
kundenListe = new JList();
kundenListe.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
kundenListe.setLayoutOrientation(JList.VERTICAL);
kundenListe.setVisibleRowCount(-1);
kundenListe.addListSelectionListener(listListener);
JScrollPane kundenScroll = new JScrollPane(kundenListe);
kundenScroll.setPreferredSize(new Dimension(350, 120));
gridBag.setConstraints(kundenScroll, constr);
container.add(kundenScroll);
```

@kompilierbarer code: ich könnt dir das ganze programm rüberschicken, aber es hier zu posten würde wohl jeden rahmen sprengen. es sind 14 klassen und 8 weitere UI.mvc-klassen damit das MVC funktioniert ... ^^


----------



## Gast2 (23. Mai 2009)

ja und du sollst ein kleines ding machen wo der effekt auftritt da brauchst du kein MVC das sind net mehr wie 100 zeilen code...


----------



## Fabian030 (23. Mai 2009)

da magst du recht haben.
deswegen is ja die valueChanged, der ListSelectionListener und das dazugehörige zeug jetzt der einfachheit halber in der view.
das sollte den ja nicht stören und sollte dort auch aufgerufen werden können. ^^


----------



## André Uhres (24. Mai 2009)

Fabian030 hat gesagt.:


> der listener schlägt anscheinend fehl und somit wird auch nie die valueChanged von der JList angeschupst.


Wahrscheinlich hängst du den Listener an eine JList, aber das ist nicht dieselbe JList, die du schliesslich anzeigst. Überprüf mal, ob alle JList Instanzen einen ListSelectionListener haben.


----------



## Fabian030 (25. Mai 2009)

naja, setze mir als erstes den ListSelectionListener
dann hab ich meine Liste die die Kunden anzeigt und setze für die den listListener dachte ich, denn auf die soll ja "gelauscht" werden bei Änderungen ...
ich hab der kontenListe, wo die daten der kunden angezeigt werden sollen auch noch den listListener spendiert

und dann dacht ich, dass die valueChanged() automatisch ausgeführt wird, sobald ich n listenelement aus der JList kundenListe auswähle/anklicke ...


```
ListSelectionListener listListener;
...
kundenListe.addListSelectionListener(listListener);
...
kontenListe.addListSelectionListener(listListener);
...
...
public void valueChanged(ListSelectionEvent event) {
	Kunde k = (Kunde)kundenListe.getSelectedValue();
	System.out.println("kunde: "+k);
	kontenListe.setListData(k.getKonten().values().toArray());
}
```

oder seh ich das falsch? aber so hab ich das prinzip des ListSelectionListeners verstanden ... :/


----------



## Gast2 (25. Mai 2009)

Mach doch einfach ein kurzes Beispiel, dann hättest du schon längst die Antwort...


----------



## Fabian030 (25. Mai 2009)

SirWayne hat gesagt.:


> Mach doch einfach ein kurzes Beispiel, dann hättest du schon längst die Antwort...



tadaaaa ...
es geht. xD


```
kundenListe.addListSelectionListener(new ListSelectionListener() { 
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting() == false) {
					if (kundenListe.getSelectedIndex() == -1) {
						System.out.println("kein Kunde gewählt.");
					} else {
						Kunde k = (Kunde)kundenListe.getSelectedValue();
						System.out.println("kunde: "+k);
						aktuellerKunde = k;
				        //einKunde = new JMenuItem("einen Kunden waehlen");
				        //einKunde.addActionListener((ActionListener) getController());
				        //einKunde.setActionCommand(Mete2View.EINKUNDE);
						kontenListe.setListData(k.getKonten().values().toArray());
					}
				}
			} } );;
```

die System.outs sind nur kontrollausgaben für mich ...

danke für die bisherige Hilfe. ich komm wieder auf euch zurück 

:toll::toll:


----------

