A Color-Rendered List
Home ] Up ] [ A Color-Rendered List ] A Font List ] A Font-Rendered List ]

 

 

All is not lost.  We can control what is displayed in a JList by the use of a ListCellRendererListCellRenderer is an interface which is declared as follows (stripped down to its essentials):

package javax.swing;

import java.awt.Component;

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

Once you've installed a cell renderer for a list, the renderer's getListCellRendererComponent() method is called for each cell in the list. It returns a component that paints the cell contents.

Here's how you can change the previous example to cause the JList to display more appropriately:

package swingExamples;

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JListColorSelector2 extends JFrame
{
  public JListColorSelector2()
  {
    setTitle("JListColorSelector2");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(400, 300);
    getContentPane().add( new JListPanel() );
  }
  
  private static Color[] COLORS =
  {
    Color.BLACK, Color.BLUE, 
    Color.CYAN, Color.DARK_GRAY,
    Color.GRAY, Color.GREEN, 
    Color.LIGHT_GRAY, Color.MAGENTA,
    Color.ORANGE, Color.PINK, 
    Color.RED, Color.WHITE,
    Color.YELLOW
  };
  
  //// Inner classes ////
  class JListPanel extends JPanel 
      implements ListSelectionListener
  {
    JListPanel()
    {
      setLayout( new BorderLayout() );
      
      JPanel listPanel = new JPanel();
      m_list.setSelectedIndex(0);
      m_list.setCellRenderer( new ColorRenderer() );
      m_list.addListSelectionListener(this);
      listPanel.add( new JScrollPane(m_list) );
      add(listPanel, BorderLayout.WEST);
      
      add(m_colorPanel, BorderLayout.CENTER);
      Color color = (Color) m_list.getSelectedValue();
      m_colorPanel.setBackground(color);
    }
    
    public void valueChanged(ListSelectionEvent e)
    {
      JList source = (JList) e.getSource();
      Color color = (Color) source.getSelectedValue();
      m_colorPanel.setBackground(color);
      m_colorPanel.repaint();
    }
    
    private JList  m_list = new JList(COLORS);
    private JPanel m_colorPanel = new JPanel();
  }
  
  /**
   * Main entry point for program
   */
  public static void main(String[] args)
  {
    JListColorSelector2 frame = 
        new JListColorSelector2();
    frame.setVisible(true);
  }
}
package swingExamples;

import java.awt.Color;
import java.awt.Component;

import java.util.HashMap;

import javax.swing.DefaultListCellRenderer;
import javax.swing.ListCellRenderer;
import javax.swing.JList;

public class ColorRenderer 
    extends DefaultListCellRenderer
{
  public Component getListCellRendererComponent(
      JList list,
      Object value,
      int index,
      boolean isSelected,
      boolean cellHasFocus
      )
  {
    // Call the superclass's version first
    super.getListCellRendererComponent(
        list, value, index, isSelected, cellHasFocus);
    
    // For this list cell, we expect a value of type Color
    if (value instanceof Color)
    {
      Color color = (Color) value;
      String colorName = (String) m_colorMap.get(color);
      if (colorName != null)
      {
        // Make the text be the color name text
        setText(colorName);
        // Make the text stand out against the background color
        Color foreground = new Color(255 - color.getRed(),
                                     255 - color.getGreen(),
                                     255 - color.getBlue()
                                    );
        // Avoid gray foreground on a gray background!
        if (color == Color.GRAY)
          foreground = Color.WHITE;
        setForeground(foreground);
      }
      // Set the background color of the list cell 
      // to match its color.
      setBackground(color);
    }
    
    return this;
  }
  
  /// Private data ///
  // This is a mapping of Color to color name text.
  private static final Object[][] COLOR_NAMES =
  {
    { Color.BLACK, "Black" },
    { Color.BLUE, "Blue" },
    { Color.CYAN, "Cyan" },
    { Color.DARK_GRAY, "Dark Gray" },
    { Color.GRAY, "Gray" },
    { Color.GREEN, "Green"},
    { Color.LIGHT_GRAY, "Light Gray" },
    { Color.MAGENTA, "Magenta" },
    { Color.ORANGE, "Orange" },
    { Color.PINK, "Pink" },
    { Color.RED, "Red" },
    { Color.WHITE, "White" },
    { Color.YELLOW, "Yellow" }
  };
  
  private static HashMap m_colorMap = new HashMap();
  
  static
  {
    for (int color =0; color < COLOR_NAMES.length; color++)
    {
      m_colorMap.put(COLOR_NAMES[color][0], 
                     COLOR_NAMES[color][1]);
    }
  }
}

This produces the following:

which is much more reasonable, in terms of a JList display (albeit a little garish!).

Note that the definition of DefaultListCellRenderer is:

public class DefaultListCellRenderer extends JLabel
    implements ListCellRenderer, Serializable

which indicates that it is is a JLabel -- a Component that can be used directly, and which can handle foreground and background colors, text displays, etc.

 

This page was last modified on 02 October, 2007