001/* 002 * $Id$ 003 * 004 * Copyright 2009 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 * 021 */ 022package org.jdesktop.swingx.sort; 023 024import java.util.HashMap; 025import java.util.Map; 026import java.util.logging.Logger; 027 028import org.jdesktop.swingx.renderer.StringValue; 029import org.jdesktop.swingx.renderer.StringValues; 030 031/** 032 * A writable implemenation of StringValueProvider. Typically, this is created and 033 * maintained by a collection view and then passed over to interested parties. It is 034 * modeled/implemented after the default renderer maintenance in a JTable.<p> 035 * 036 * PENDING JW: for safety - better not implement but return a provider. We probably don't want 037 * readers to frickle around here?. 038 * 039 * @author Jeanette Winzenburg 040 */ 041public final class StringValueRegistry implements StringValueProvider { 042 043 @SuppressWarnings("unused") 044 private static final Logger LOG = Logger 045 .getLogger(StringValueRegistry.class.getName()); 046 047 private Map<Class<?>, StringValue> perClass; 048 private HashMap<Integer, StringValue> perColumn; 049 private HashMap<Integer, Class<?>> classPerColumn; 050 051 /** 052 * {@inheritDoc} <p> 053 */ 054 @Override 055 public StringValue getStringValue(int row, int column) { 056 StringValue sv = getPerColumnMap().get(column); 057 if (sv == null) { 058 sv = getStringValueByClass(getClass(row, column)); 059 } 060 if (sv == null) { 061 sv = getStringValueByClass(Object.class); 062 } 063 return sv != null ? sv : StringValues.TO_STRING; 064 } 065 066//-------------------- manage 067 /** 068 * Sets a StringValue to use for the given column. If the converter is null, 069 * the mapping is removed. 070 * 071 * @param sv the StringValue to use for the given column. 072 * @param column the column index in model coordinates. 073 * 074 */ 075 public void setStringValue(StringValue sv, int column) { 076 // PENDING really remove mapping if sv null 077 getPerColumnMap().put(column, sv); 078 } 079 080 /** 081 * Removes all per-column mappings of StringValues. 082 * 083 */ 084 public void clearColumnStringValues() { 085 getPerColumnMap().clear(); 086 } 087 088 /** 089 * Sets the StringValue to use for the given class. If the converter is null, 090 * the mapping is removed. 091 * 092 * @param sv the StringValue to use for the given column. 093 * @param clazz the class 094 */ 095 public void setStringValue(StringValue sv, Class<?> clazz) { 096 // PENDING really remove mapping if sv null 097 getPerClassMap().put(clazz, sv); 098 } 099 100 /** 101 * Returns the StringValue registered for the given class. <p> 102 * 103 * <b>This is temporarily exposed for testing only - do not use, it will 104 * be removed very soon!</b> 105 * 106 * @param clazz the class to find the registered StringValue for 107 * @return the StringValue registered for the class, or null if not directly 108 * registered. 109 */ 110 public StringValue getStringValue(Class<?> clazz) { 111 return getPerClassMap().get(clazz); 112 } 113 /** 114 * Sets the column class. 115 * 116 * @param clazz 117 * @param column index in model coordinates 118 */ 119 public void setColumnClass(Class<?> clazz, int column) { 120 getColumnClassMap().put(column, clazz); 121 } 122 123 /** 124 * @param classPerColumn 125 */ 126 public void setColumnClasses(Map<Integer, Class<?>> classPerColumn) { 127 this.classPerColumn = classPerColumn != null ? 128 new HashMap<Integer, Class<?>>(classPerColumn) : null; 129 } 130 131 /** 132 * 133 * @param clazz 134 * @return 135 */ 136 private StringValue getStringValueByClass(Class<?> clazz) { 137 if (clazz == null) return null; 138 StringValue sv = getPerClassMap().get(clazz); 139 if (sv != null) return sv; 140 return getStringValueByClass(clazz.getSuperclass()); 141 } 142 143 /** 144 * Returns the Class of the column. 145 * 146 * @param row 147 * @param column 148 * @return 149 */ 150 private Class<?> getClass(int row, int column) { 151 Class<?> clazz = getColumnClassMap().get(column); 152 return clazz != null ? clazz : Object.class; 153 } 154 155 /** 156 * Returns the Map which stores the per-column Class, lazily 157 * creates one if null. 158 * 159 * @return the per-column storage map of Class 160 */ 161 private Map<Integer, Class<?>> getColumnClassMap() { 162 if (classPerColumn == null) { 163 classPerColumn = new HashMap<Integer, Class<?>>(); 164 } 165 return classPerColumn; 166 } 167 168 /** 169 * Returns the Map which stores the per-class StringValues, lazily 170 * creates one if null. 171 * 172 * @return the per-class storage map of StringValues 173 */ 174 private Map<Class<?>, StringValue> getPerClassMap() { 175 if (perClass == null) { 176 perClass = new HashMap<Class<?>, StringValue>(); 177 } 178 return perClass; 179 } 180 181 /** 182 * Returns the Map which stores the per-column StringValues, lazily 183 * creates one if null. 184 * 185 * @return the per-column storage map of StringValues 186 */ 187 private Map<Integer, StringValue> getPerColumnMap() { 188 if (perColumn == null) { 189 perColumn = new HashMap<Integer, StringValue>(); 190 } 191 return perColumn; 192 } 193}