Avatar billede agent29 Nybegynder
10. december 2001 - 22:49 Der er 6 kommentarer og
1 løsning

DefaultListModel / ListCellRenderer

Hejsa,

Jeg har brug for at tilføje et billede eller ændre baggrundsfarven for et index[n]i en JList i runtime. Dvs. at på en button_event skal et givet index[n] ændre baggrundsfarve eller indsætte et ikon.

Jeg er i tvivl om det er CellRenderer eller ListModel jeg skal have fat i. Så vidt jeg kan forstå, er det ListModel der styrer indholdet af listen.

Er der en der ved dette, og som lige kan give et hurtigt eksempel.

Ændring af baggrundsfarven er at foretrække.

Mvh
Tonni Aagesen
Avatar billede logical Nybegynder
12. december 2001 - 23:45 #1
Din ListModel holder data, din Renderer viser dem.

Dvs. du skal have en listmodel, som ved hvilke elementer, som skal være anderledes, ala:

class MyData {
  public boolean selected;
  public String someText;
  public MyData(boolean selected, String text) {
    this.selected = selected;
    this.someText = text;
  }
}

class MyListModel extends AbstractTableModel {
  private MyData[] data = { new MyData(true, \"Hej\"), new MyData(false, \"Verden\") };
  public int getSize() { return data.length; }

  public int getElementAt(int index) { return data[index]  }
}

Eksemplet ovenover er selvfølgelig meget forsimplet, men jeg har en ListModel, som bruger objekter der indeholder de data, som jeg finder nødvendige i en sammenhæng.

Når en liste tegnes, bruges en ListCellRenderer til at repræsentere hvert element. Hvis du skal have noget ændret grafisk, skal du pille ved denne.

Et eksempel (Som sætter baggrundsfarven for de objekter af typen MyData hvor selected er true).

public class MyRenderer extends DefaultListCellRenderer {
  public MyRenderer() {
    setOpaque(true);
  }

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

  super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); // Do as we always do initially

if (value instanceof MyData) {
  // If we need to do it differently
  MyData d = (MyData) value;
  setText(d.someText);
  if (d.selected)
    setBackground(Color.cyan);
  else
    setBackground(Color.white);
  }
}
}


Add denne renderer til din list, og brug din nye listmodel, så skulle det virke.
Avatar billede agent29 Nybegynder
13. december 2001 - 00:15 #2
Hej Logical (og andre),

Jeg har udfra dit svar på mit tidligere spørgsmål om ListCellRenderer lavet følgende:

    class CustomListCellRenderer extends JTextArea implements ListCellRenderer {
       
        public CustomListCellRenderer() {

        }

        public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus){
               
                if (isSelected) {
                    setBackground(listMenu.getSelectionBackground());
                    setForeground(listMenu.getSelectionForeground());
                    setBorder(new EtchedBorder(1));
                }
                else {
                    setBackground(listMenu.getBackground());
                    setForeground(listMenu.getForeground());
                    setBorder(new EtchedBorder(0));

                }
                setEnabled(list.isEnabled());
                setFont(list.getFont());
                setText(value.toString());
            return this;
        }
    }


Listen og og Modellen laves:

listModel = new DefaultListModel();

// sætter parametre for JList - tilføjer vores listModel og vores hjemmelavede listCellRenderer
listMenu = new JList(listModel);
listMenu.setCellRenderer(new CustomListCellRenderer());

// tilføjer data til modellen
listModel.addElement(\"hello,\\nJeg lærer Java.\");
listModel.addElement(\"hello,\\nJeg kører bil.\");

Senere (i dag torsdag) skal det sættes sammen med andre dele af en app.

Min oprindelige ide bestod i at downcaste et element til et JTextArea og så ændre baggrundsfarven der.

JTextArea item = (JTextArea)listModel.getElementAt(listMenu.getSelectedIndex());

men det giver en casterror :-( Kan jeg på nogn måde få ovenstående til at fungerer eller hvad?

Mvh
Tonni Aagesen
Avatar billede logical Nybegynder
13. december 2001 - 00:44 #3
Din model indeholder ikke nogen oplysninger om at noget er \"valgt\", der er nærmest bare en ombrudt String.

Din Renderer ser fin nok ud. Det du skal huske på er, at den ikke eksisterer på grænsefladen som sådan, den bliver kaldt af din liste når den skal tegne nogle ting.

Når du siger
listModel.getElementAt(listMenu.getSelectedIndex());
Får du et af dine elementer (Som du har added, og som er Strings) fra modellen, og det er derfor ikke JTextArea komponenter.

Det er et spørgsmål om at din list model er for \"tynd\", og ikke kan indeholde oplysninger om hvilke elementer der skal have en særlig baggrund.

Jeg ville personligt gøre Lave en lidt \"bedre\" model, og bruge i stedet, og så rette rendereren lidt til.

Følgende virker!!!:

En Ny ListModel:
class MyDefaultModel extends DefaultListModel {
    class MyData {
        public boolean selected;
        public String value;
        public MyData(String value) { this.value = value; }
        public String toString() {return value;}
    }
   
    public void addElement(String data) {
        super.addElement(new MyData(data));
    }
   
    public boolean isSelected(int index) {
        return ((MyData) super.getElementAt(index)).selected;
    }
    public void setSelected(int index, boolean select) {
        ((MyData) super.getElementAt(index)).selected = select;
        fireContentsChanged(this, index, index);
    }
}

Rettelser i din renderer ( 3 linier ca ved bunden):
class CustomListCellRenderer extends JTextArea implements ListCellRenderer {
       
        public CustomListCellRenderer() {

        }

        public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus){
               
                if (isSelected) {
                    setBackground(listMenu.getSelectionBackground());
                    setForeground(listMenu.getSelectionForeground());
                    setBorder(new EtchedBorder(1));
                }
                else {
                    setBackground(listMenu.getBackground());
                    setForeground(listMenu.getForeground());
                    setBorder(new EtchedBorder(0));

                }
                setEnabled(list.isEnabled());
                setFont(list.getFont());
                setText(value.toString());
                if (value instanceof MyDefaultModel.MyData) {
                    MyDefaultModel.MyData data = (MyDefaultModel.MyData) value;
                    if (data.selected) setBackground(Color.cyan);
                }
            return this;
        }
    }


Og brugen:
MyDefaultModel listModel = new MyDefaultModel();

// sætter parametre for JList - tilføjer vores listModel og vores hjemmelavede listCellRenderer
listMenu = new JList(listModel);
listMenu.setCellRenderer(new CustomListCellRenderer());

// tilføjer data til modellen
listModel.addElement(\"hello,\\nJeg lærer Java.\");
listModel.addElement(\"hello,\\nJeg kører bil1.\");
listModel.addElement(\"hello,\\nJeg kører bil2.\");
listModel.addElement(\"hello,\\nJeg kører bil3.\");
listModel.addElement(\"hello,\\nJeg kører bil4.\");

Så kan du kalde listModel.setSelected(index, boolean) når du absolut vil have en ændret baggrundsfarve, ala:


listModel.setSelected(3, true);


class MyDefaultModel extends DefaultListModel
Avatar billede logical Nybegynder
13. december 2001 - 00:46 #4
Hvor er jeg dog frygelig velformuleret og klar i min tale midt om natten :-)))

Undskyld stavefejl, halve kodesektioner etc :-)
Avatar billede agent29 Nybegynder
13. december 2001 - 00:50 #5
Natten er til at kode i!! (hvis man ikke lige har besøg :-)

Tak for svarene- jeg kigger lige lidt på dem.

Mvh
Tonni
Avatar billede logical Nybegynder
13. december 2001 - 00:59 #6
Med småbørn i huset er natten bedst brugt til at sove i  :-)

Jeg når nok ikke at komme med flere guldkorn før du har flettet det sammen med andres, så held og lykke.
Avatar billede agent29 Nybegynder
13. december 2001 - 01:05 #7
Enig

Tak for hjælpen, de 60 point er dine - du har fortjent dem :-)

Mvh
Tonni
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester