1

How can I change the colour of a specific index using JList, I manage to change the colour, but it changes the colour of the whole list and I need to be able to change a specific index to one colour, and another index to another.

I've tried quite a lot of combinations and they seem to only change the whole list colour instead of the index. I understand why because it's referring to the whole list, I just don't know how to change it for a specific index.

    m.aList.setCellRenderer(new MyCellRender());

  private class MyCellRender extends DefaultListCellRenderer  
{    

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

        ArrayList<Object> values = new ArrayList<>();
        ArrayList<String> complete = new ArrayList<>();
        ArrayList<String> incomplete = new ArrayList<>();

        for (int i = 0; i < list.getModel().getSize(); i++) {
            values.add(list.getModel().getElementAt(i));
        }

        for (Object o : values) {
           if (o.toString().contains("COMPLETED")) {
               complete.add(o.toString());
           }
           if (o.toString().contains("INCOMPLETE")) {
               incomplete.add(o.toString());
           }
        }

        for (String s : complete) {
            setForeground(Color.green);
        }
        for (String s1 : incomplete) {
            setForeground(Color.red);
        }

        return( this );  
    }  
}

The values in the list contain either COMPLETED, or INCOMPLETE, and I would like to change their colour according to their value.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
user1848712
  • 105
  • 2
  • 9

2 Answers2

6

The values in the list contain either COMPLETED, or INCOMPLETE, and I would like to change their colour according to their value.

First off there's no need to keep these three lists:

ArrayList<Object> values = new ArrayList<>();
ArrayList<String> complete = new ArrayList<>();
ArrayList<String> incomplete = new ArrayList<>();

The ListCellRenderer component is evaluated for each element in the JList so these lists are pointless. You can implement your requirement easily doing as follows:

private class MyCellRender extends DefaultListCellRenderer {
   @Override
   public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
       super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
       if(value.toString().contains("INCOMPLETE") ||  value.toString().contains("COMPLETED")) {
           Color fg = value.toString().contains("COMPLETED") ? Color.green : Color.red;
           setForeground(fg);
       } else {
           setForeground(list.getForeground());
       }
       return this;
   }
}

Take a look to Writing a Custom Cell Renderer section in How to Use Lists trail for further details.

dic19
  • 17,821
  • 6
  • 40
  • 69
  • Thankyou very much, don't have much understanding as to how cell renderers work so I'll read up on it – user1848712 Jan 03 '14 at 16:56
  • @user1848712 you're welcome! Take a look to [this topic](http://stackoverflow.com/a/13673083/1795530) for a better understaing about how Swing renderers work. – dic19 Jan 03 '14 at 17:03
1

Youre setting the foreground color for every list component but getListCellRendererComponent is called when rendering every individual cell. In that case you need to do something like

if (value.toString().contains("COMPLETED")) {
    setForeground(Color.GREEN);
} else if (value.toString().contains("INCOMPLETE")) {
    setForeground(Color.RED);           
} else {   // handle default case
   ...
}   

This is the only user code needed in the ListRenderer

Reimeus
  • 158,255
  • 15
  • 216
  • 276