JList/DefaultListModel: Wie kann ich ein Panel hinzufügen?

Soloeco

Aktives Mitglied
Hi, ich habe eine JList und dieser möchte ich in jeder Zeile ein Bild und dahinter einen Text einfügen. Wie dem Code zu entnehmen ist, mache ich das bisher untereinander und es funktioniert. Das Problem ist, wenn ich das über ein JPanel/JLabel/JTextField realisieren möchte, also dem listMod eines der drei genannten hinzufüge, damit es nebeneinander ist, wird nur sowas angezeigt:

"javax.swing.JTextField[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@1d5e53ab,flags=288,maximumSize=,minimumSize=,preferredSize=,caretColor=,disabledTextColor=DerivedColor(color=142,143,145 parent=nimbusDisabledText offsets=0.0,0.0,0.0,0 pColor=142,143,145,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=DerivedColor(color=255,255,255 parent=nimbusSelectedText offsets=0.0,0.0,0.0,0 pColor=255,255,255,selectionColor=DerivedColor(color=57,105,138 parent=nimbusSelectionBackground offsets=0.0,0.0,0.0,0 pColor=57,105,138,columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]"

[CODE lang="java" title="Relevanter Code"] private void initModel() throws IOException {
DefaultListModel listMod = new DefaultListModel();
for (int i=0; i<18; i++) {
String bildName = (i+1) + ".jpg";

ImageIcon image = new ImageIcon(this.getClass().getResource("bilder/"+bildName));

listMod.addElement (image);
listMod.addElement (getName(i));
}
auswahlListe.setModel(listMod);
}[/CODE]

Recherchen haben ergeben, dass ich dafür einen ListCellRenderer an die Liste übergeben muss (https://www.java-forum.org/thema/jlist-mit-jpanels.107291/).
Wie mache ich das?
 
Renderer werden von gewissen Komponenten wie eine Art Stempel verwendet, um Objekte aus einem Model am Bildschirm darzustellen. Hier wird das Flyweight-Pattern verfolgt: statt für jedes Objekt aus dem Model eine komplexe UI-Komponente zu erzeugen, wird mit möglichst einer Komponente alles erschlagen, indem einfach Daten ausgetauscht werden (wie beim Stempel ein Wechsel des Stempelkissens).

Das nur mal kurz zu Erklärung. Ein Renderer ist einfach ein Objekt, das mit einer Methode eine Komponente entsprechend der überergebenen Parameter zurückgibt. Der DefaultListCellRenderer ist von JLabel abgeleitet, erbt also alles von JLabel. Damit kann man den Spaß durchaus wiederverwenden.

Jetzt ist die Frage, wie Du die Objekte im Model am besten modellierst. Nett wäre eine Klasse, die Text und ein Icon als Attribut besitzt. Mangels genauerer Kenntnis nenne ich die Klasse mal IconResource.

Java:
class IconResource {
    public final String text;
    public final Icon icon;

    public IconResource(String text, String icon) {
        this.text = text;
        this.icon = icon;
    }
}

Du füllst also Dein Model mit IconResource-Objekten. Zur Darstellung brauchst Du jetzt noch einen Renderer:
Java:
ListCellRenderer renderer = new DefaultListCellRenderer() {
    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        Icon icon = null;
        Object realValue = value;
        if (value instanceof IconResource) {
            IconResource resource = (IconResource) value;
            icon = resource.icon;
            realValue = resource.text;
        }
         
        super.getListCellRendererComponent(list, realValue, index, isSelected, cellHasFocus);
        setIcon(icon);
        return this;
    }
};

Und den setzt Du dann als Renderer der JList (Achtung: ungetestet).
 

Neue Themen


Zurück
Oben