001/* 002 * $Id: DefaultListRenderer.java 3779 2010-09-07 18:01:55Z kschaefe $ 003 * 004 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021package org.jdesktop.swingx.renderer; 022 023import java.awt.Component; 024 025import javax.swing.JList; 026import javax.swing.ListCellRenderer; 027 028/** 029 * Adapter to glue SwingX renderer support to core API. It has convenience 030 * constructors to create a LabelProvider, optionally configured with a 031 * StringValue and horizontal alignment. Typically, client code does not 032 * interact with this class except at instantiation time. 033 * <p> 034 * 035 * Note: core DefaultListCellRenderer shows either an icon or the element's 036 * toString representation, depending on whether or not the given value 037 * is of type icon or implementors. This renderer's empty/null provider 038 * constructor takes care of configuring the default provider with a converter 039 * which mimics that behaviour. When instantiating this renderer with 040 * any of the constructors which have converters as parameters, 041 * it's up to the client code to supply the appropriate converter, if needed: 042 * 043 * 044 * <pre><code> 045 * StringValue sv = new StringValue() { 046 * 047 * public String getString(Object value) { 048 * if (value instanceof Icon) { 049 * return ""; 050 * } 051 * return StringValue.TO_STRING.getString(value); 052 * } 053 * 054 * }; 055 * StringValue lv = new MappedValue(sv, IconValue.ICON); 056 * listRenderer = new DefaultListRenderer(lv, alignment); 057 * 058 * </code></pre> 059 * 060 * <p> 061 * 062 * 063 * @author Jeanette Winzenburg 064 * 065 * @see ComponentProvider 066 * @see StringValue 067 * @see IconValue 068 * @see MappedValue 069 * 070 * 071 */ 072public class DefaultListRenderer extends AbstractRenderer 073 implements ListCellRenderer { 074 075 protected ListCellContext cellContext; 076 077 /** 078 * Instantiates a default list renderer with the default component 079 * provider. 080 * 081 */ 082 public DefaultListRenderer() { 083 this((ComponentProvider<?>) null); 084 } 085 086 /** 087 * Instantiates a ListCellRenderer with the given ComponentProvider. 088 * If the provider is null, creates and uses a default. The default 089 * provider is of type <code>LabelProvider</code><p> 090 * 091 * Note: the default provider is configured with a custom StringValue 092 * which behaves exactly as core DefaultListCellRenderer: depending on 093 * whether or not given value is of type icon or implementors, it shows 094 * either the icon or the element's toString. 095 * 096 * @param componentProvider the provider of the configured component to 097 * use for cell rendering 098 */ 099 public DefaultListRenderer(ComponentProvider<?> componentProvider) { 100 super(componentProvider); 101 this.cellContext = new ListCellContext(); 102 } 103 104 /** 105 * Instantiates a default table renderer with a default component controller 106 * using the given converter.<p> 107 * 108 * PENDING JW: how to guarantee core consistent icon handling? Leave to 109 * client code? 110 * 111 * @param converter the converter to use for mapping the content value to a 112 * String representation. 113 * 114 */ 115 public DefaultListRenderer(StringValue converter) { 116 this(new LabelProvider(converter)); 117 } 118 119 /** 120 * Instantiates a default list renderer with a default component 121 * controller using the given converter and horizontal 122 * alignment. 123 * 124 * PENDING JW: how to guarantee core consistent icon handling? Leave to 125 * client code? 126 * 127 * 128 * @param converter the converter to use for mapping the 129 * content value to a String representation. 130 * @param alignment the horizontal alignment. 131 */ 132 public DefaultListRenderer(StringValue converter, int alignment) { 133 this(new LabelProvider(converter, alignment)); 134 } 135 136 137 /** 138 * Instantiates a default list renderer with default component provider 139 * using both converters. 140 * 141 * @param stringValue the converter to use for the string representation 142 * @param iconValue the converter to use for the icon representation 143 */ 144 public DefaultListRenderer(StringValue stringValue, IconValue iconValue) { 145 this(new MappedValue(stringValue, iconValue)); 146 } 147 148 /** 149 * Instantiates a default list renderer with default component provider 150 * using both converters and the given alignment. 151 * 152 * @param stringValue the converter to use for the string representation 153 * @param iconValue the converter to use for the icon representation 154 * @param alignment the rendering component's horizontal alignment 155 */ 156 public DefaultListRenderer(StringValue stringValue, IconValue iconValue, 157 int alignment) { 158 this(new MappedValue(stringValue, iconValue), alignment); 159 } 160 161 // -------------- implements javax.swing.table.ListCellRenderer 162 /** 163 * 164 * Returns a configured component, appropriate to render the given 165 * list cell. <p> 166 * 167 * Note: The component's name is set to "List.cellRenderer" for the sake 168 * of Synth-based LAFs. 169 * 170 * @param list the <code>JList</code> to render on 171 * @param value the value to assign to the cell 172 * @param isSelected true if cell is selected 173 * @param cellHasFocus true if cell has focus 174 * @param index the row index (in view coordinates) of the cell to render 175 * @return a component to render the given list cell. 176 */ 177 @Override 178 public Component getListCellRendererComponent(JList list, Object value, 179 int index, boolean isSelected, boolean cellHasFocus) { 180 cellContext.installContext(list, value, index, 0, isSelected, 181 cellHasFocus, true, true); 182 Component comp = componentController.getRendererComponent(cellContext); 183 // fix issue #1040-swingx: memory leak if value not released 184 cellContext.replaceValue(null); 185 return comp; 186 } 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override 192 protected ComponentProvider<?> createDefaultComponentProvider() { 193 return new LabelProvider(createDefaultStringValue()); 194 } 195 196 /** 197 * Creates and returns the default StringValue for a JList.<p> 198 * This is added to keep consistent with core list rendering which 199 * shows either the Icon (for Icon value types) or the default 200 * to-string for non-icon types. 201 * 202 * @return the StringValue to use by default. 203 */ 204 private StringValue createDefaultStringValue() { 205 return MappedValues.STRING_OR_ICON_ONLY; 206 } 207}