Swing JList: ScrollPane auf JPanel ansprechen

Drizzt

Mitglied
Hallo,
ich einer JList als Items ein JPanel zugewiesen. Auf JPanel habe ich 2 TextArea mit einem ScrollPane. Die Darstellung klappt soweit, nur kann ich nicht vernünftig scrollen, wenn ich die TextArea auf der JList anspreche.

Mein CellRenderer zur Darstellung des JPanels
Java:
public class CellRendererBild extends JPanel implements ListCellRenderer {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 6046489657382078802L;
	private JTextArea txtrBildname = null;
	private JTextArea txtrBildbeschreibung = null;
	private JLabel lblId = null;
	private JLabel lblBild = null;
	private JScrollPane scrollPaneBildname;
	private JScrollPane scrollPaneBeschreibung;
	
	public CellRendererBild() {
		lblBild = new JLabel("");
		scrollPaneBildname = new JScrollPane();
		
		scrollPaneBeschreibung = new JScrollPane();
		
		lblId = new JLabel("Id");
		GroupLayout groupLayout = new GroupLayout(this);
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblBild, GroupLayout.PREFERRED_SIZE, 160, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(scrollPaneBildname, GroupLayout.PREFERRED_SIZE, 117, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(scrollPaneBeschreibung)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblId)
					.addContainerGap())
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
						.addGroup(groupLayout.createSequentialGroup()
							.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
								.addComponent(scrollPaneBeschreibung, GroupLayout.PREFERRED_SIZE, 79, GroupLayout.PREFERRED_SIZE)
								.addComponent(lblBild)
								.addComponent(scrollPaneBildname, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE))
							.addContainerGap())
						.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
							.addComponent(lblId)
							.addGap(31))))
		);
		
		txtrBildbeschreibung = new JTextArea();
		txtrBildbeschreibung.setEditable(false);
		txtrBildbeschreibung.setLineWrap(true);
		txtrBildbeschreibung.setText("jksdfjksd klsd klf snkldfnkl ssdnkl nklsddfkl ssdf nklsd nklsd nklsd nklsd nklsd nklsd nkldf sdnkl nklsd nklsd nklsdf nklsd nklsd nklsd nklsd sdnkl sdnkl sdnkl sdnkl sdnkl sdnkl sdfnsdfnkl sd nklsd");
		scrollPaneBeschreibung.setViewportView(txtrBildbeschreibung);
		
		JLabel lblBildbeschreibung = new JLabel("Bildbeschreibung");
		lblBildbeschreibung.setFont(new Font("Tahoma", Font.BOLD, 11));
		scrollPaneBeschreibung.setColumnHeaderView(lblBildbeschreibung);
		
		txtrBildname = new JTextArea();
		txtrBildname.setEditable(false);
		txtrBildname.setLineWrap(true);
		txtrBildname.setText(" jhasdjbksajk as asnkl asdnklas nklas ankl as klas ankl sas ");
		scrollPaneBildname.setViewportView(txtrBildname);
		
		JLabel lblBildname = new JLabel("Bildname");
		lblBildname.setFont(new Font("Tahoma", Font.BOLD, 11));
		scrollPaneBildname.setColumnHeaderView(lblBildname);
		setLayout(groupLayout);
	}

	@Override
	public Component getListCellRendererComponent(JList list, Object value,int index, boolean isSelected, boolean hasCellFokus) {
		txtrBildbeschreibung.setText(((ListItem)value).getTxtrBildbeschreibung());
		txtrBildname.setText(((ListItem)value).getTxtrBildname());
		lblId.setText(((ListItem)value).getLblId());
		lblBild.setIcon(((ListItem)value).getIcon());
	    if(hasCellFokus) {
	    	setBackground(Color.lightGray); 
	    }
        else { 
        	setBackground(list.getBackground()); 
        }
		return this;
	}

}

Klasse zur Erstellung der Items
Java:
public class ListItem {
	private ImageIcon icon = null;
	private String bildname = null;
	private String bildbeschreibung = null;
	private String id = null;

	public ListItem(String iconPfad, String bildname, String bildbeschreibung,
			String id) {

		this.icon = BildLaden.loadImageAsThumbNailForSearch(new File(iconPfad), 80);
		this.bildname = bildname;
		this.bildbeschreibung = bildbeschreibung;
		this.id = id;
	}

	public ImageIcon getIcon() {
		return icon;
	}

	public String getTxtrBildname() {
		return bildname;
	}

	public String getTxtrBildbeschreibung() {
		return bildbeschreibung;
	}

	public String getLblId() {
		return id;
	}

}

Die Items werden der JList hinzugefügt z.B. mit:

Java:
	DefaultListModel listmodel = new DefaultListModel();
		JList list = new JList(listmodel);
                listmodel.addElemente(new ListItem("./pics/pz.jpg", "Kirche", String "Am Berg", "5")
 
kannst du überhaupt irgendwie scrollen, kannst du etwas in die TextAreas schreiben?
doch sicher auch nicht,

wie stellst du dir das Rendern vor, dass auf einmal 10 verschiedene ScrollBalken in der GUI existieren, die du alle einzeln bedienen kannst?
das ist doch nicht ganz logisch wenn du nur ein derartiges Panel erstellst

das Rendern ist ein temporärer Vorgang, die Komponente wird kurzzeitig für jeden Eintrag genutzt, gepainted,
und dieses Bild wird dann Pixel für Pixel gemerkt und in der GUI angezeigt,
sieht aus wie ein Screenshot, nichts funktioniert mehr, auch genau wie auf einem Screenshot

bei JTable gibt es den CellEditor der sich aktiv um die aktuell ausgewählte Zelle kümmert, dann kann man auch etwas eintippen, eine ComboBox bedienen usw.,
wie es bei JList aussieht kann ich auf die Schnelle nicht sagen, Editable gibts ja, aber nur Text?

hiernach
JList CellEditor : jlist, celleditor, editable
siehts nicht nach vorhandenen Editor aus, ein Vorschlag ist eine einspaltige Tabelle 😉

edit: funktioniert nur als google-Suchergebnis,
4. Link bei 'java jlist editor'
 
Hallo erstmal danke für deine Antwort.
Also ich kann mir nicht vorstellen, dass das JPanel mit den Komponenten "nur als Screenshot Pixel für Pixel" gezeichnet wird, da ich einzelne Objekte auf dem Panel locker ansprechen kann mit z.B.
Java:
ListItem testItem = (ListItem) list.getSelectedValue();
System.out.println(testItem.getLblId());
Also ich kann den Text nicht ändern auch wenn die TextAreas Editable gesetzt sind. Ich glaube es fehlt vll ein ActionListener/DataListener? Es lässt sich srollen, wenn man raufklicken, aber nur nach ganz oben und ganz unten.

Ich kann leider nichts lesen von dem Link den mir gegeben hast, da ist immer eine Werbung drüber die man nicht schließen kann. Aber mit CellEditor für JTable hört sich ganz gut an. Muss ich noch ausprobieren. Kann ich denn ein komplettes JPanel mit Komponenten als Item in den JTable ablegen? Wie sieht es denn mit der Performance wenn ich 1000 Items in der JTableliste habe?

PS. Ich habe einen Screenshot hochgeladen wie es momentan aussieht (unbekannt.png)
 

Anhänge

  • Unbenannt.jpg
    Unbenannt.jpg
    78,8 KB · Aufrufe: 47
Zuletzt bearbeitet:
Also ich kann mir nicht vorstellen, dass das JPanel mit den Komponenten "nur als Screenshot Pixel für Pixel" gezeichnet wird, da ich einzelne Objekte auf dem Panel locker ansprechen kann mit z.B.
Java:
ListItem testItem = (ListItem) list.getSelectedValue();
System.out.println(testItem.getLblId());
Is aber so ;-) Deswegen nennt sich das ganze auch ListCellRenderer. Das Selektieren ist ja eine Grundfunktion der JList, das muss ja unabhängig vom dargestellten Objekt funktionieren.
Aber mit CellEditor für JTable hört sich ganz gut an. Muss ich noch ausprobieren. Kann ich denn ein komplettes JPanel mit Komponenten als Item in den JTable ablegen? Wie sieht es denn mit der Performance wenn ich 1000 Items in der JTableliste habe?
Genauso JList gibt es auch für die JTable einen Renderer mit dem man die ListItem Objekte darstellen kann. Zusätzlich kann man - im Gegensatz zur JList - bei einer JTable einen CellEditor verwenden, um Einträge direkt zu editieren.
mehrerer Tausend Items in einer JTable sind kein Problem.

Infos dazu gibt's z.B. hier:
http://www.java-forum.org/bilder-gui-damit-zusammenhaengt/4841-jtable-ubersicht-teil-1-teil-8-a.html#post23457
 
> Ich kann leider nichts lesen von dem Link den mir gegeben hast, da ist immer eine Werbung drüber die man nicht schließen kann.
deswegen schrieb ich ja noch einen edit darunter

> Kann ich denn ein komplettes JPanel mit Komponenten als Item in den JTable ablegen?
wenn es dir hilft, etwa um jedes Listenelement anders komplex anzuordnen, könntest du das machen, auch wenn 5 Zeilen Information besser wären als 500kb an Swing-Objekten,
am Renderer-Konzept führt das aber glaube ich auch nicht vorbei,

dann solltest du eher komplett auf JList verzichten und deine mehreren Panel in einem ScrollPane untereinander positionieren
und Selektion mit Hintergrundfarbe usw. selber einbauen
 
Nein geht leider nicht. Ich lese die Ergebnisse aus eine SQL Datenbank aus und die Liste soll dynmisch Einträge anzeigen. Ich möchte doch nur Scrollen im Bildnamen und in der Bildbeschreibung pro Eintrag. Ich hab mir den TableCellEditor angeschaut, aber das ist auch nicht das wahre, denn ich möchte ja nichts editieren, nur anzeigen.
deswegen schrieb ich ja noch einen edit darunter
ja ich habe über google gesucht, keine sorge, nur war der werbebanner trotzdem da

wenn es dir hilft, etwa um jedes Listenelement anders komplex anzuordnen, könntest du das machen, auch wenn 5 Zeilen Information besser wären als 500kb an Swing-Objekten,
Ich denke, es wird schwierig in einer Zelle viel mit Layout zu machen, zudem noch andere Elemente eventuell dazukommen. Aber ich spiele mit dem Gedanken einfach die Scrolleiste wegzulassen. Es scheint mir sonst auszuufern

dann solltest du eher komplett auf JList verzichten und deine mehreren Panel in einem ScrollPane untereinander positionieren
und Selektion mit Hintergrundfarbe usw. selber einbauen
Guter Vorschlag, dann müsste ich nur eine Navigationsleiste einbauen "Nächste Seite" oder so. Hört sich allerdings weniger nach Objektorientierungen an, aber ich denke ich werde es ausprobieren, scheint mir eine einfach Lösung zu sein
 
Zuletzt bearbeitet:
So ich habs jetzt mit JTable (eigener Renderer und Editor) umgesetzt. Leider habe ich dort das selbe Problem, dass ich dort die Scrollleiste nicht vernünftig ansprechen kann. Klar kann man dem CellEditor Werte von ComboBoxen ändern, aber ich habe keine Ahnung wie ich ihm dort sage, dass er scrollen soll. Ich finde mich damit ab, dass ich nicht scrollen kann. Trotzdem danke.
 

Zurück
Oben