Problem mit ListCellRenderer für JPanel

i.b.fan

Aktives Mitglied
Hallo zusammen,

ich versuche gerade verzweifelt einen ListCellRenderer für eine JList zu implementieren, welcher mir Objekte anzeigt, die von JPanel erben.
Ich habe ein ListModel, in welchem Objekte vom Typ Group stecken. Group erbt von JPanel und enthält mehrere Elemente (im Beispiel Labels mit Text und Farbe).
Diese Group-Panels möchte ich mir jetzt in einer JList anzeigen lassen. Ich bekomme das aber nur so hin, dass er mir immer NEUE Instanzen anzeigt, nicht aber die schon bestehenden aus dem ListModel (siehe auch Kommentar).

Was mache ich falsch? Wo ist mein Denkfehler?

Vielen Dank für Tipps oder Links zu einem vergleichbaren Beispiel!

i.b.fan :)

Edit: Wenn ich mir die Group-Panels einzeln anzeigen lasse, werden sie korrekt dargestellt

Ich habe den Code zusammengefasst und vereinfacht:
[Java]
package testlistcellrenderer;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Main {

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable(){@Override public void run(){

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GroupListView());
frame.pack();
frame.setVisible(true);
}});
}
}
[/Java]
[Java]
package testlistcellrenderer;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.ScrollPane;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;

public class GroupListView extends ScrollPane{

private DefaultListModel listModel;
JList list;

public GroupListView(){

listModel = new DefaultListModel();

listModel.addElement(new Group("Hans", 23, Color.RED));
listModel.addElement(new Group("Bert", 54, Color.GREEN));
listModel.addElement(new Group("Gabi", 12, Color.BLUE));

list = new JList(listModel);

MyListRenderer renderer = new MyListRenderer();
list.setCellRenderer(renderer);

this.add(list);
this.setVisible(true);
}

public class MyListRenderer extends JPanel implements ListCellRenderer{

public MyListRenderer(){
setOpaque(true);
this.setAlignmentX(CENTER_ALIGNMENT);
this.setAlignmentY(CENTER_ALIGNMENT);
this.setPreferredSize(new Dimension(200, 30));
}

public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus){

if (isSelected) {
setBackground(Color.GREEN);
} else {
setBackground(Color.GRAY);
}

/* UND HIER SITZT DER WURM DRIN
* es soll ja das schon vorhandene Group-Panel (JPanel) malen
* aber egal was ich mache, es legt immer ein NEUES JPanel an
* oder wenn ich MyListRenderer Group extenden lasse, dann eben
* ein NEUES Group-Panel.
* wie kriege ich ihn dazu, "value" anzuzeigen???
*/

return this;
}
}//end class MyList

public class Group extends JPanel{

public Group(String name, int nummer, Color farbe){
JLabel eins = new JLabel(name);
JLabel zwei = new JLabel("Hausnummer: " + nummer);
eins.setForeground(farbe);
eins.setBackground(Color.BLACK);
zwei.setForeground(Color.BLACK);
zwei.setBackground(farbe);
this.add(eins);
this.add(zwei);
this.setVisible(true);
System.out.println("is EDT: " + SwingUtilities.isEventDispatchThread());
}
}//end class Group
}//end class GroupListView
[/Java]
 
Zuletzt bearbeitet:

hansmueller

Bekanntes Mitglied
Hallo,

das gleiche Problem hatte ich auch. Ich habe es einfach nicht geschafft, ein fertiges Objekt (Panel mit Labels) darzustellen.

Ich bin dann folgenden Weg gegangen:
Statt zu versuchen, den CellListRenderer dazu zu bringen meine Objekte darzustellen und in einer Liste die Objekte zu speichern, habe ich den CellListRenderer zu einen meiner Objekte gemacht und die Liste enthält jetzt nur noch die entsprechenden Einträge und Werte.

Setzt deine Labels in den CellListRenderer, so wie du es bei deiner Group-Klasse gemacht hast.
Die Zuweisung von Text und Farben machst du dann in der getListCellRendererComponent-Methode.

Schau dir mal folgendes Beispielprogramm von mir an:
Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;


public class MainProg
{
	JFrame f;
		
	public static void main(String[] args)
	{
		MainProg x = new MainProg();

	}
	
	public MainProg()
	{
		f = new JFrame("Test Auswahlpanel");
		
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		f.setLayout(new GridLayout(1, 1));
		f.setPreferredSize(new Dimension(600, 300));
				
		DefaultListModel StandardListenModel = new DefaultListModel();
			
		ListenEintrag le1 = new ListenEintrag("Test 1","Versuch 1","Irrtum 1","Verzweiflung 1");
		ListenEintrag le2 = new ListenEintrag("Test 2","Versuch 2","","");
		ListenEintrag le3 = new ListenEintrag("Test 3","Versuch 3","","Verzweiflung 3");
		ListenEintrag le4 = new ListenEintrag("Test 4","Versuch 4","Irrtum 4","");
					
		StandardListenModel.addElement(le1);
		StandardListenModel.addElement(le2);
		StandardListenModel.addElement(le3);
		StandardListenModel.addElement(le4);
				
		JList Liste = new JList(StandardListenModel);
		
		Liste.setCellRenderer(new MeinCellRenderer());
				
		
		f.add(new JScrollPane(Liste));
				
		f.pack();
		f.setVisible(true);
		
	}
	
	public class ListenEintrag
	{
		private String s1,s2,s3,s4;
		
		public ListenEintrag(String p_s1, String p_s2, String p_s3, String p_s4)
		{
			this.s1 = p_s1;
			this.s2 = p_s2;
			this.s3 = p_s3;
			this.s4 = p_s4;
		}

		public String getS1()
		{
			return s1;
		}

		public String getS2()
		{
			return s2;
		}

		public String getS3()
		{
			return s3;
		}

		public String getS4()
		{
			return s4;
		}

	}
	
	public class MeinCellRenderer extends JPanel implements ListCellRenderer
	{
		JLabel lb1,lb2,lb3,lb4;
		
		public MeinCellRenderer()
		{
			setLayout(new GridLayout(2, 2));
			setBorder(BorderFactory.createLineBorder(Color.MAGENTA, 3));
			setOpaque(true);
			
			lb1 = new JLabel();
			lb2 = new JLabel();
			lb3 = new JLabel();
			lb4 = new JLabel();
					
			lb1.setOpaque(false);
			lb2.setOpaque(false);
			lb3.setOpaque(false);
			lb4.setOpaque(false);
			
			lb1.setBorder(BorderFactory.createLineBorder(Color.PINK, 2));
			lb2.setBorder(BorderFactory.createLineBorder(Color.PINK, 2));
			lb3.setBorder(BorderFactory.createLineBorder(Color.PINK, 2));
			lb4.setBorder(BorderFactory.createLineBorder(Color.PINK, 2));
			
			add(lb1);
			add(lb2);
			add(lb3);
			add(lb4);
			
		}
					
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus)
		{
			String x1 = (((ListenEintrag)value).getS1());
			String x2 = (((ListenEintrag)value).getS2());
			String x3 = (((ListenEintrag)value).getS3());
			String x4 = (((ListenEintrag)value).getS4());
			
			lb1.setText(x1);
			lb2.setText(x2);
			lb3.setText(x3);
			lb4.setText(x4);
								
			if(isSelected)
			{
				setBackground(Color.green);
			}
			else
			{
				setBackground(list.getBackground());
			}
			
			return this;
		}

	}
	
}

Statt Strings kanns du in deinen ListenEintrag auch Color verwenden. Vergiss bloß nicht die get-Methoden.

Und folgenden Link:
coding:java:java_tut_7 [thwiki]

MfG
hansmueller
 

Michael...

Top Contributor
ich versuche gerade verzweifelt einen ListCellRenderer für eine JList zu implementieren, welcher mir Objekte anzeigt, die von JPanel erben.
Ich habe ein ListModel, in welchem Objekte vom Typ Group stecken. Group erbt von JPanel und enthält mehrere Elemente (im Beispiel Labels mit Text und Farbe).
Das ist ein eher ungünstiger Ansatz, bei den Objekten, die im ListModel enthalten sind, sollte es sich nur um "Daten" nicht um graphische Komponenten handeln - sonst untergräbt man den Grundgedanken, der hinter dem Rendererkonzept steht.
Die graphische Komponente wird durch den Renderer definiert/repräsentiert.
 

i.b.fan

Aktives Mitglied
Hallo,

das gleiche Problem hatte ich auch. Ich habe es einfach nicht geschafft, ein fertiges Objekt (Panel mit Labels) darzustellen.

Ich bin dann folgenden Weg gegangen:
Statt zu versuchen, den CellListRenderer dazu zu bringen meine Objekte darzustellen und in einer Liste die Objekte zu speichern, habe ich den CellListRenderer zu einen meiner Objekte gemacht und die Liste enthält jetzt nur noch die entsprechenden Einträge und Werte.

Setzt deine Labels in den CellListRenderer, so wie du es bei deiner Group-Klasse gemacht hast.
Die Zuweisung von Text und Farben machst du dann in der getListCellRendererComponent-Methode.
[...]
MfG
hansmueller

Hallo Hans (oder besser hansmueller?),

danke für die ausführliche Antwort. Wenn ich das richtig verstanden habe und Dein Listing richtig gelesen habe, dann machst Du genau das, was Michael nach Dir geschrieben hat: In der Liste keinerlei Darstellungsinfo mehr, diese nur noch im Renderer, richtig?

Im Prinzip war ich auch schon fast so weit, im Renderer einfach eins zu eins aus dem übergebenen "value" die Werte auslesen und nochmals im Renderer genau die gleiche Darstellungs-Information wie im Ursprungsobjekt anzugeben.
Das wäre im Gegensatz zu Dir dann aber doppeltgemoppelt, weil ich sie im Ursprungsobjekt ja noch beibehalte. So wirklich pfiffig scheint mir das nicht zu sein... ???:L

i.b.fan :)
 

i.b.fan

Aktives Mitglied
Das ist ein eher ungünstiger Ansatz, bei den Objekten, die im ListModel enthalten sind, sollte es sich nur um "Daten" nicht um graphische Komponenten handeln - sonst untergräbt man den Grundgedanken, der hinter dem Rendererkonzept steht.
Die graphische Komponente wird durch den Renderer definiert/repräsentiert.

Hallo Michael,

den Ansatz kann ich nachvollziehen und macht prinzipiell auch Sinn, wenn man drüber nachdenkt.

Nichtsdestotrotz kann es doch auch vorkommen, dass man schon fertige Objekte hat, die sowohl Daten als auch Darstellungsinformationen beinhalten. Es muss doch auch möglich sein, ein solches Objekt sich selbst darstellen zu lassen, wenn das Objekt diese Informationen ja schon in sich trägt.

Wenn ich nen Kreis, ein Dreieck und ein Quadrat "erfunden" habe, auf nem Panel, und diese schon fröhlich einsetze im Rest meines Programms - warum soll ich das in ner JList (in deren Renderer) nochmals "erfinden"?
Der Kreis kann doch dem Renderer mitteilen: "Hey Du, so werde ich dargestellt"

Das ist doch eine legitime Annahme/Forderung, oder etwa nicht?

i.b.fan :)
 

i.b.fan

Aktives Mitglied
Ich glaub, ich hab nen Ansatz (nach MVC):

Klasse1: Group - ausschliesslich die Nutzdaten

Klasse2: GroupRenderer(Group gp) - stellt die Nutzdaten grafisch dar (egal von welchem Programmteil)

Klasse3: Container (z.B. JPanel) beinhaltet eine
~ JList - welche (auch) Klasse2 als Renderer benutzt und ein
~ DefaultListModel - welches Anzahl x Elemente der Klasse1 "beherbergt"

Bisher war (zumindest gedanklich bei mir) die Klasse2 ja entweder in Klasse1 ODER Klasse3 integriert.

Ich werde berichten, ob das so klappt...

i.b.fan :)
 

i.b.fan

Aktives Mitglied
Hallo nochmals,

ich habs jetzt endlich so hinbekommen wie im Post vorher beschrieben. Ob das nun wirklich sooo viel besser ist, sei mal dahingestellt.
Immerhin funktioniert es so schon mal ;)

Hier die drei Klassen + Main:

Main.java:
Java:
package testlistcellrenderer2;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Main {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable(){@Override public void run(){

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GroupListView());
                frame.pack();
                frame.setVisible(true);
	}});
    }
}
Group.java:
Java:
package testlistcellrenderer2;

import java.awt.Color;

public class Group {     //extends nix und enthält nur Nutzdaten
    
    private String name;
    private int hausnr;
    private Color farbe;

    //Constructor für Renderer -> der kann erstmal "leeres" Objekt erzeugen
    public Group(){   
        name = "leer";
        hausnr = 0;
        farbe = Color.GRAY;
    }

    //Constructor für "echte" Objekte, die nicht vom Renderer aus erzeugt werden
    public Group(String name, int hausnr, Color farbe){
        this.name = name;
        this.hausnr = hausnr;
        this.farbe = farbe;
    }

    public String getName(){
        return name;
    }

    public int getHausnr(){
        return hausnr;
    }

    public Color getFarbe(){
        return farbe;
    }
}
GroupListView.java:
Java:
package testlistcellrenderer2;

import java.awt.Color;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;

public class GroupListView extends JPanel{ //oder irgendein Container

    private DefaultListModel listModel;
    JList list;

    public GroupListView(){

        listModel = new DefaultListModel();

        listModel.addElement(new Group("Hans", 23, Color.RED));
        listModel.addElement(new Group("Bert", 54, Color.GREEN));
        listModel.addElement(new Group("Gabi", 12, Color.GRAY));
        listModel.addElement(new Group("Bine", 17, Color.YELLOW));

        list = new JList(listModel);

        GroupRenderer renderer = new GroupRenderer();
        list.setCellRenderer(renderer);

        this.add(list);
        this.setVisible(true);
        
    }
}
GroupRenderer.java:
Java:
package testlistcellrenderer2;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;

/**
 * kann ganz "normal" von überall als Renderer für die Nutzdaten von Group
 * benutz werden und durch das Interface zusätzlich auch von 
 * einer JList oder JComboBox
 */

public class GroupRenderer extends JPanel implements ListCellRenderer{
    
    private String name;
    private int hausnr;
    private Color farbe;
    JLabel eins, zwei;
    
    //Constructor, der von JList genutzt wird
    public GroupRenderer(){

        this.setOpaque(true);
        this.setAlignmentX(CENTER_ALIGNMENT);
        this.setAlignmentY(CENTER_ALIGNMENT);
        this.setPreferredSize(new Dimension(400,80));
        
        //jetzt alles zusammenbasteln:
        initComponents();
        //das Befüllen der Werte übernimmt die Interface-Methode!
    }

    //Constructor, der von allen anderen Programmteilen genutzt wird
    public GroupRenderer(Group group){
        
        this.setOpaque(true);
        this.setAlignmentX(CENTER_ALIGNMENT);
        this.setAlignmentY(CENTER_ALIGNMENT);
        this.setPreferredSize(new Dimension(400,80));
        
        //ab hier unterscheidet es sich:
        this.name = group.getName();
        this.hausnr = group.getHausnr();
        this.farbe = group.getFarbe();
        
        //jetzt alles zusammenbasteln:
        initComponents();
    }

    //Methode vom Interface!
    public Component getListCellRendererComponent(JList list, 
                                                  Object value, 
                                                  int index, 
                                                  boolean isSelected, 
                                                  boolean cellHasFocus) {
        
        //und hier die (Standard-)Werte der Components durch die
        //der in "value" übergebenen Instanz ersetzen:
        String nam = ((Group)value).getName();
        int nr = ((Group)value).getHausnr();
        Color far = ((Group)value).getFarbe();

        eins.setText(nam);
        zwei.setText("Hausnummer: " + nr);
        eins.setForeground(far);
        eins.setBackground(Color.black);
        zwei.setBackground(far);
        zwei.setForeground(Color.black);
        
        //noch schnell festlegen, wie etwas Ausgewähltes dargestellt wird:
        if (isSelected) {
            setBackground(Color.GREEN);
        } else {
            setBackground(list.getBackground());
        }
        return this; //sich selbst zurückgeben an die JList
    }

    private void initComponents(){

        eins = new JLabel(name);
        zwei = new JLabel("Hausnummer: " + hausnr);
        eins.setOpaque(true);
        zwei.setOpaque(true);
        eins.setForeground(farbe);
        eins.setBackground(Color.BLACK);
        zwei.setForeground(Color.BLACK);
        zwei.setBackground(farbe);
        this.add(eins);
        this.add(zwei);
        this.setVisible(true);
    }
}

i.b.fan :)
 

i.b.fan

Aktives Mitglied
Hallo,

das gleiche Problem hatte ich auch. Ich habe es einfach nicht geschafft, ein fertiges Objekt (Panel mit Labels) darzustellen. [...]

Hallo Hans,

ich hab das jetzt doch noch genau so geschafft! Schau Dir mal mein Listing an, insbesondere die Kommentare...

Das Wesentliche zusammengefasst:
1.) Der Renderer muss von dem fertigen Objekt erben, nicht von JPanel (bei mir ist das Group)
2.) In Group muss es einen Konstruktor OHNE Übergabewerte geben (da der vom Renderer aufgerufen wird)
3.) Im Renderer nicht die Variablen ändern, sondern die Komponenten selber - aber das hattest Du ja schon richtig, nur ich hab das nicht geblickt ;)

Zu dem Lösungsweg aus dem vorigen Post mit den drei Klassen:
Letztlich ist das doch das Gleiche (brauche ja auch zwei unterschiedliche Konstruktoren etc).
Und ob ich diese nun in dem (JPanel-)Objekt integriere oder in den Renderer, spielt wohl weniger eine Rolle. Im Renderer bin ich zwar flexibler für unterschiedliche Darstellungen der selben Daten, aber im Objekt hab ich alles schön beisammen...

i.b.fan :)

Java:
package testlistcellrenderer;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.ScrollPane;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;

public class GroupListView extends ScrollPane{

    private DefaultListModel listModel;
    JList list;

    public GroupListView(){

        listModel = new DefaultListModel();

        listModel.addElement(new Group("Hans", 23, Color.RED));
        listModel.addElement(new Group("Bert", 54, Color.GREEN));
        listModel.addElement(new Group("Gabi", 12, Color.YELLOW));

        list = new JList(listModel);

        MyListRenderer renderer = new MyListRenderer();
        list.setCellRenderer(renderer);

        this.add(list);
        this.setVisible(true);
    }

public class MyListRenderer extends Group implements ListCellRenderer{

    //hier brauche ich nichts deklarieren, da er die Komponenten ja schon erbt!

    public MyListRenderer(){
        //brauch ich auch nichts reinschreiben, denn er ruft ja wegen Vererbung
        //den Constructor ohne Übergabewerte von Group auf
    }

    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus){

        //Werte aus "value" herausholen und hier setzen:
        String  temp1 = ((Group)value).getEinName();
        int     temp2 = ((Group)value).getNummer();
        Color   temp3 = ((Group)value).getFarbe();
        
        //this.setEinName( temp1 );
        //this.setNummer( temp2 );
        //this.setFarbe( temp3 );
        //ACHTUNG: so gehts nicht, denn die Komponenten sind ja schon 
        //initialisiert und bleiben von der Änderung der Variablen unberührt!!!

        //es müssen direkt die JLabels geändert werden (über die Label-Methoden)
        //welche er schon kennt, da MyListRenderer von Group (NICHT JPanel) erbt
        eins.setText(temp1);
        zwei.setText("Hausnummer: " + temp2);
        eins.setForeground(temp3);
        eins.setBackground(Color.BLACK);
        zwei.setForeground(Color.BLACK);
        zwei.setBackground(temp3);
        
        if (isSelected) {
            setBackground(Color.GREEN);
        } else {
            setBackground(Color.GRAY);
        }

        return this; //sich selbst (Typ: Group) an JList übergeben
    }
}//end class MyList


public class Group extends JPanel{
    
    String einName;
    int nummer;
    Color farbe;
    JLabel eins, zwei;

    public Group(String einName, int nummer, Color farbe){

        this.einName = einName;
        this.nummer = nummer;
        this.farbe = farbe;
        initComponents();
    }

    public Group(){

        //mit irgendwas befüllen, wird eh vom Renderer neu befüllt
        this.einName = "leer";
        this.nummer = 0;
        this.farbe = Color.ORANGE;
        initComponents();
    }
    
    private void initComponents(){

        //hier wird das Layout des Panels gestaltet
        eins = new JLabel(einName);
        zwei = new JLabel("Hausnummer: " + nummer);
        eins.setForeground(farbe);
        eins.setBackground(Color.BLACK);
        zwei.setForeground(Color.BLACK);
        zwei.setBackground(farbe);
        eins.setOpaque(true);
        zwei.setOpaque(true);
        this.setPreferredSize(new Dimension(100,30));
        this.setOpaque(true);
        this.add(eins);
        this.add(zwei);
        this.setVisible(true);
    }

    public String getEinName(){
        return this.einName;
    }

    public int getNummer(){
        return this.nummer;
    }

    public Color getFarbe(){
        return this.farbe;
    }

    public void setEinName(String einName){
        this.einName = einName;
    }

    public void setNummer(int nummer){
        this.nummer = nummer;
    }

    public void setFarbe(Color farbe){
        this.farbe = farbe;
    }

}//end class Group
}//end class GroupListView
 

Michael...

Top Contributor
Es ist völlig überflüssig, dass die Objekte im ListModel von JPanel erben und sich aus graphischen Komponenten zusammen setzen.
Ich war mal so frei Deinen Code ein bisschen zu modifizieren:
Java:
import java.awt.Color;
import java.awt.Component;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;

public class GroupListView extends JFrame {

	public static void main(String[] s) {
		new GroupListView().setVisible(true);
	}

	public GroupListView() {
		DefaultListModel listModel = new DefaultListModel();
		listModel.addElement(new Group("Hans", 23, Color.RED));
		listModel.addElement(new Group("Bert", 54, Color.GREEN));
		listModel.addElement(new Group("Gabi", 12, Color.YELLOW));

		JList list = new JList(listModel);
		list.setCellRenderer(new MyListRenderer());

		this.add(new JScrollPane(list));
		this.setBounds(0, 0, 200, 200);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public class MyListRenderer extends JPanel implements ListCellRenderer {
		private JLabel nameLabel, streetLabel;

		public MyListRenderer() {
			nameLabel = new JLabel();
			streetLabel = new JLabel();
			nameLabel.setBackground(Color.BLACK);
			streetLabel.setForeground(Color.BLACK);
			nameLabel.setOpaque(true);
			streetLabel.setOpaque(true);
			add(nameLabel);
			add(streetLabel);
		}

		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			Group group = (Group) value;
			Color color = group.getFarbe();
			nameLabel.setText(group.getName());
			nameLabel.setForeground(color);
			streetLabel.setText("Hausnummer: " + group.getNummer());
			streetLabel.setBackground(color);
			if (isSelected)
				setBackground(Color.GREEN);
			else
				setBackground(Color.GRAY);
			return this;
		}
	}

	public class Group {
		String name;
		int nummer;
		Color farbe;

		public Group(String name, int nummer, Color farbe) {
			this.name = name;
			this.nummer = nummer;
			this.farbe = farbe;
		}

		public String getName() {
			return name;
		}

		public int getNummer() {
			return nummer;
		}

		public Color getFarbe() {
			return farbe;
		}
	}
}// end class GroupListView
 

i.b.fan

Aktives Mitglied
Es ist völlig überflüssig, dass die Objekte im ListModel von JPanel erben und sich aus graphischen Komponenten zusammen setzen.
Ich war mal so frei Deinen Code ein bisschen zu modifizieren: [...]

Hallo Michael,

vielen Dank für die Mühe! Inzwischen wird mir die ganze Sache ja auch klarer.
Wenn ich Deine Modifikationen richtig gelesen habe, hast Du die "grafischen Informationen" aus den Konstruktoren von Group rausgezogen und in die des Renderers reingeschoben, oder?!
Das wäre dann doch aber mein Lösungsvorschlag aus Post #7, oder hab ich da was übersehen?

Und nochmals zum generellen Denkansatz: Prinzipiell ist es ja schon richtig, Daten und deren Darstellung zu trennen. Nur bei einem Label würde ja auch niemand auf die Idee kommen, daraus zwei Klassen zu machen: eine für den Inhalt "Text" + "Vordergrund" + "Hintergrund" und dann noch eine eigene Renderer-Klasse, oder?

Nun kam ich ja von der anderen Seite: ich hatte schon Panels mit mehreren Objekten drauf. Hierbei für die ganz wenigen "echten" Nutzdaten eine extra Klasse zu machen scheint mir nicht sinnvoll. Es funktioniert ja soweit auch alles und die Panels werden an verschiedenen Stellen schon eingesetzt.
Und jetzt erst kommt das Verlangen auf, an einer einzigen Stelle noch schnell eine List/Combobox zu erstellen, die noch dazu die gleiche Darstellung dieser Panels nehmen soll.

Warum sollte ich dafür alles andere wieder umschreiben? Macht das wirklich einen tieferen Sinn? Insbesondere muss ich dann ja für die zehn anderen Stellen dann eine zweite Renderer-Klasse schreiben (was ich in Post #7 versucht habe zu vermeiden - ein Renderer für alle).

Aus meiner Sicht sind Post #7 und #8 zwei unterschiedliche Lösungsansätze, die je nach Bedarfsfall besser oder weniger gut geeignet sind.
Oder ist das wirklich solch ein verwerfliches Teufelswerk??

i.b.fan :)
 

i.b.fan

Aktives Mitglied
Auf die Gefahr hin, geköpft zu werden:

Was spricht eigentlich dagegen, die Renderer-Klasse als eigene Klasse weg zu lassen und stattdessen den ListCellRenderer gleich in der Klasse Group zu implementieren?
 

Michael...

Top Contributor
Was spricht eigentlich dagegen, die Renderer-Klasse als eigene Klasse weg zu lassen und stattdessen den ListCellRenderer gleich in der Klasse Group zu implementieren?
Machbar ist alles. Ob's sinnvoll ist...

Du hättest in dem Fall für jedes Group Objekt - also jeden Listeneintrag - ein JPanel und zwei JLabels, um mal bei dem Beispiel zu bleiben.
Das "intelligente" an einem Renderer ist, das Du unabhängig von der Anzahl der Objekte bzw. Listeneinträge insgesamt nur eine grahische Komponente hast - in dem Fall ein JPanel und zwei JLabel.

Mag jetzt bei drei Einträgen nicht viel ausmachen, aber bei 1000 Listeneinträgen hast statt des notwendigen drei Objekten 3000 Objekte im Speicher...
 

i.b.fan

Aktives Mitglied
Machbar ist alles. Ob's sinnvoll ist...

Du hättest in dem Fall für jedes Group Objekt - also jeden Listeneintrag - ein JPanel und zwei JLabels, um mal bei dem Beispiel zu bleiben.
Das "intelligente" an einem Renderer ist, das Du unabhängig von der Anzahl der Objekte bzw. Listeneinträge insgesamt nur eine grahische Komponente hast - in dem Fall ein JPanel und zwei JLabel.

Mag jetzt bei drei Einträgen nicht viel ausmachen, aber bei 1000 Listeneinträgen hast statt des notwendigen drei Objekten 3000 Objekte im Speicher...

Ahaaaa, so ergibt das plötzlich auch einen Sinn (dachte bisher, dies sei nur um flexibler in der Art des/der Views auf die Daten zu sein)
D.h. der Renderer malt die Objekte in eine Zelle und verwirft sie dann gleich wieder? Solang, bis er sie wieder malen muss, richtig?
 

Michael...

Top Contributor
D.h. der Renderer malt die Objekte in eine Zelle und verwirft sie dann gleich wieder? Solang, bis er sie wieder malen muss, richtig?
Fast ;-) Die Objekte werden nicht verworfen, sondern einmalig erstellt, dann je nach Bedarf/Zeileninhalt im Aussehen angepasst und auf die JList gemalt. Was man in der JList sieht sind nicht die Objekte, sondern ein Bild der Objekte/ des Renderers - ein Fotokopie quasi.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Verständnis Problem bei Server/Client Java Basics - Anfänger-Themen 2
I WildFily - unterschiedliche Libs im Projekt verursachen Problem Java Basics - Anfänger-Themen 11
imocode Vererbung Problem mit Vererbung Java Basics - Anfänger-Themen 2
L Taschenrechner Problem Java Basics - Anfänger-Themen 4
I Applikationsserver (WildFly) - Zugriff auf Ressourcen.. Problem mit Pfade Java Basics - Anfänger-Themen 10
A ScheduledExecutorService problem Java Basics - Anfänger-Themen 7
marcelnedza Problem mit Weltzuweisung, JavaKarol Java Basics - Anfänger-Themen 13
XWing Methoden rückgabe Problem? Java Basics - Anfänger-Themen 6
M Erste Schritte Collatz Problem max int Java Basics - Anfänger-Themen 3
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
C GLOOP Problem beim Erstellen der Kamera Java Basics - Anfänger-Themen 9
nelsonmandela Problem bei Ausgabe einer Switch - Case Funktion Java Basics - Anfänger-Themen 5
frager2345 Problem mit Methode Java Basics - Anfänger-Themen 4
L Problem bei Rechnung mit Math.pow Java Basics - Anfänger-Themen 13
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
SUPERTJB return Problem Java Basics - Anfänger-Themen 3
sserio BigInteger Problem Java Basics - Anfänger-Themen 4
JordenJost Taschenrechner problem Java Basics - Anfänger-Themen 5
K Problem mit "Random" Java Basics - Anfänger-Themen 5
S Datei anlegen Problem! Groß- und Kleinschreibung wird nicht unterschieden Java Basics - Anfänger-Themen 4
sserio Problem beim Anzeigen Java Basics - Anfänger-Themen 5
xanxk Problem For-Schleife mit Charakter Java Basics - Anfänger-Themen 2
L Unbekanntes Problem mit 2d Array Java Basics - Anfänger-Themen 6
sserio Liste erstellt und ein Problem mit dem Index Java Basics - Anfänger-Themen 8
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Schleife Problem Java Basics - Anfänger-Themen 2
D Problem mit der Erkennung von \n Java Basics - Anfänger-Themen 2
milan123 das ist meine aufgabe ich hab das problem das bei mir Wenn ich die Richtung der Linien verändern will und drei davon sind richtig, verändere ich die 4 Java Basics - Anfänger-Themen 3
M Verständins Problem bei Aufgabe Java Basics - Anfänger-Themen 4
HeiTim Problem mit der Kommasetzung an der richtigen stelle Java Basics - Anfänger-Themen 59
Temsky34 Problem mit dem Code Java Basics - Anfänger-Themen 17
P Problem mit Calendar.getDisplayName() Java Basics - Anfänger-Themen 8
C Problem mit mehreren Methoden + Scanner Java Basics - Anfänger-Themen 5
P Datei einlesen, nach Begriff filtern und in Datei ausgeben. Problem Standardausgabe über Konsole Java Basics - Anfänger-Themen 19
M Problem mit Klassenverständnis und Button Java Basics - Anfänger-Themen 8
EchtKeineAhnungManchmal hallo habe ein Problem mit einer Datei -> (Zugriff verweigert) Java Basics - Anfänger-Themen 4
H Problem mit Verzweigungen Java Basics - Anfänger-Themen 6
H Problem mit Rückgabewert Java Basics - Anfänger-Themen 7
josfe1234 JAVA FX problem Java Basics - Anfänger-Themen 3
A Code Problem Java Basics - Anfänger-Themen 6
Henri Problem von Typen Java Basics - Anfänger-Themen 7
J Problem mit "ArrayIndexOutOfBoundsException" Java Basics - Anfänger-Themen 11
K jackson Mapping - Problem mit Zeitzonen Java Basics - Anfänger-Themen 10
B Threads Problem mit mehreren Threads Java Basics - Anfänger-Themen 38
I Output BigDecimal anstatt double / Problem beim Rechnen Java Basics - Anfänger-Themen 16
D Schleifen Problem Java Basics - Anfänger-Themen 2
H So viele Fehlermeldungen, dass ich nicht weiß wo das Problem ist. Java Basics - Anfänger-Themen 6
J JAVA-Problem blockiert MEDIATHEKVIEW Java Basics - Anfänger-Themen 13
T Problem mit Lehrzeichen und String bei einfacher Chiffre Java Basics - Anfänger-Themen 8
J extends Problem Java Basics - Anfänger-Themen 2
C Polymorphie-Problem Java Basics - Anfänger-Themen 3
Kalibru Problem bei Ausgabe von Objekt Java Basics - Anfänger-Themen 1
I Format Problem mit Wert - bekomme 0,10 anstatt 10,00 Java Basics - Anfänger-Themen 6
J Problem mit einer Methode die gewissen Inhalt einer Array löschen soll Java Basics - Anfänger-Themen 9
J Problem mit einer Methode, die beliebig viele Objekte in Array speichern soll Java Basics - Anfänger-Themen 6
J Allgemeines Problem mit Klassen Java Basics - Anfänger-Themen 5
U Problem mit dem initialisieren meines Strings in einer Schleife Java Basics - Anfänger-Themen 5
amgadalghabra algorithmisches Problem Java Basics - Anfänger-Themen 19
J Traveling Salesman Problem [Arrays] Java Basics - Anfänger-Themen 9
R ArrayList Problem Java Basics - Anfänger-Themen 6
InfinityDE Problem mit Datenübergabe an Konstruktor Java Basics - Anfänger-Themen 7
C RegEx Problem Java Basics - Anfänger-Themen 4
J Anfänger TicTacToe, Problem bei Gewinnoption, sowohl Unentschieden Java Basics - Anfänger-Themen 8
E Taschenrechner GUI Problem mit Fehlerhandling Java Basics - Anfänger-Themen 6
M Input/Output Fallunterscheidung Problem Java Basics - Anfänger-Themen 17
P Problem beim Überschreiben einer vererbten Methode Java Basics - Anfänger-Themen 4
M Problem bei Ausgabe Java Basics - Anfänger-Themen 7
Splayfer Java Array Problem... Java Basics - Anfänger-Themen 2
G Problem bei der Ausgabe einer Main Claase Java Basics - Anfänger-Themen 7
F Problem mit KeyListener in kombination mit dem ActionListener Java Basics - Anfänger-Themen 4
G Subset sum problem mit Backtracking Java Basics - Anfänger-Themen 18
N Problem mit Scanner Java Basics - Anfänger-Themen 2
J Klassen Problem Java Basics - Anfänger-Themen 8
A Out.format problem. Java Basics - Anfänger-Themen 3
J Problem bei der Programmierung eines Tannenbaums Java Basics - Anfänger-Themen 9
A Array problem Java Basics - Anfänger-Themen 16
2 Taschenrechner mit GUI Problem bei der Berechnung Java Basics - Anfänger-Themen 8
W Remote Method Invocation RMI - Problem Java Basics - Anfänger-Themen 0
I Ich habe ein Problem Java Basics - Anfänger-Themen 3
A Problem bei returnen eines Wertes Java Basics - Anfänger-Themen 6
M Regex Erstellung Problem Java Basics - Anfänger-Themen 2
D Input/Output Problem bei der Benutzereingabe eines Befehls Java Basics - Anfänger-Themen 14
M (Sehr großes Problem) Listen als static in anderen Klassen verwendet Java Basics - Anfänger-Themen 12
F Habe ein problem mit dem ActionListener Java Basics - Anfänger-Themen 3
C Regex-Problem Java Basics - Anfänger-Themen 4
J Problem beim vergleich von zwei Integer Java Basics - Anfänger-Themen 3
M Problem in der Modellierung Java Basics - Anfänger-Themen 20
W Wo ist das URL-Problem ? Java Basics - Anfänger-Themen 1
S Generics-Problem: Class, Class<?>, Class<Object> Java Basics - Anfänger-Themen 4
D FileWriter / FileReader Problem Java Basics - Anfänger-Themen 10
G Problem beim Speichern von Objekten in einer Datei Java Basics - Anfänger-Themen 7
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
J Problem mit Array: 2 Klassen Java Basics - Anfänger-Themen 2
S Collections funktionale Listen (ListNode<E>) review und problem beim clone Java Basics - Anfänger-Themen 0
W OOP Vererbung und Problem bei Zählschleife in einer Methode Java Basics - Anfänger-Themen 10
C Problem mit If Else If und Überprüfung eines Counters Java Basics - Anfänger-Themen 3
F Problem mit Listen Java Basics - Anfänger-Themen 5
I wieder mit einer Umwandelung habe ich Problem (diesmal von char Array zu char) Java Basics - Anfänger-Themen 1
J Problem bei Umrechnung von Hex in Bin Java Basics - Anfänger-Themen 4
W Problem bei Programmierung von Monte-Carlo-Integration Java Basics - Anfänger-Themen 12

Ähnliche Java Themen

Neue Themen


Oben