001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 package graphlab.ui.components.gpropertyeditor; 005 006 import graphlab.ui.AttributeSetView; 007 008 import javax.swing.*; 009 import javax.swing.table.TableCellRenderer; 010 import java.awt.*; 011 import java.util.HashMap; 012 import java.util.Set; 013 import java.util.Map; 014 import java.util.Collections; 015 016 /** 017 * this class is a part of gpropertyeditor, which creates a property editor with a jtable 018 * so it is implementation os TableCellRenderer. it returns a renderer for a cell by the 019 * "type of Object" that is stored in that cell. 020 * u can register for each class a renderer by the method registerRenderer. 021 * 022 * @see graphlab.ui.components.gpropertyeditor.GPropertyEditor 023 * 024 * @author azin azadi 025 */ 026 public class GCellRenderer implements TableCellRenderer, ListCellRenderer { 027 028 public static HashMap<Class, GBasicCellRenderer> knownRenderers = new HashMap<Class, GBasicCellRenderer>(); 029 private AttributeSetView attributes; 030 //private int lastRow,lastColumn; 031 private HashMap<Integer, Component> lastRenderers = new HashMap<Integer, Component>(); 032 033 public static final Color SELECTED_COLOR = Color.red; 034 /** 035 * returns the last generated renderer by this object for the given row, 036 * note that this is not a very safe method, It may return a generated renderer for another table, 037 * so use it carefully 038 */ 039 public Component getLastCreatedRenderer(int row) { 040 return lastRenderers.get(row); 041 } 042 043 044 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 045 String name = attributes.getNameAt(row); 046 GBasicCellRenderer ren = attributes.getrenderer(name); 047 Component rend = (ren != null ? ren.getRendererComponent(value) : getRendererFor(value)); 048 lastRenderers.put(row, rend); 049 if (rend == null) { 050 return null; 051 } 052 int h = (int) rend.getPreferredSize().getHeight(); 053 if (h > 5) 054 setRowHeight(table, row, h); 055 if (isSelected) { 056 rend.setForeground(SELECTED_COLOR); 057 } 058 return rend; 059 } 060 061 private void setRowHeight(JTable table, int row, int h) { 062 if (table.getRowHeight(row) != h) 063 table.setRowHeight(row, h); 064 } 065 066 /** 067 * return a renderer for he object from previously registered renderers 068 */ 069 public static Component getRendererFor(Object value) { 070 //todo: value=null => bug 071 // lastRow=row;lastColumn=column; 072 if (value == null) 073 return null; 074 075 //try to find the best renderer for value 076 GBasicCellRenderer renderer = null; 077 Class<? extends Object> valueClass = value.getClass(); 078 Class c = valueClass; 079 //search super classes 080 while (renderer == null && c != Object.class) { 081 renderer = knownRenderers.get(c); 082 c = c.getSuperclass(); 083 } 084 if (renderer == null) 085 for (Class cc : c.getInterfaces()) 086 if ((renderer = knownRenderers.get(cc)) != null) break; 087 if (renderer == null) { 088 //search implementing interfaces 089 Set<Class> keys = knownRenderers.keySet(); 090 // Class cc[] = value.getClass().getInterfaces(); 091 for (Class cc : keys) { 092 if (cc.isAssignableFrom(valueClass)) { 093 renderer = knownRenderers.get(cc); 094 break; 095 } 096 } 097 } 098 if (renderer == null) 099 return new JLabel(value + ""); 100 else return renderer.getRendererComponent(value); 101 } 102 103 /** 104 * register the "renderer" for the "clazz". so after this, calls to getTableCellRendererComponent method will 105 * return this renderer if the value passed to that method has the same class with "clazz" 106 */ 107 public static void registerRenderer(Class clazz, GBasicCellRenderer renderer) { 108 // renderers.put(clazz, renderer); 109 knownRenderers.put(clazz, renderer); 110 } 111 112 public void setAtrView(AttributeSetView attributes) { 113 114 this.attributes = attributes; 115 } 116 117 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 118 Component rendererFor = getRendererFor(value); 119 if (isSelected) { 120 rendererFor.setForeground(Color.red); 121 rendererFor.setBackground(Color.blue); 122 } 123 lastRenderers.put(index, rendererFor); 124 return rendererFor; 125 } 126 127 /** 128 * @return known editors as an unmodifiable map 129 */ 130 public static Map<Class, GBasicCellRenderer> getKnownRenderers(){ 131 return Collections.unmodifiableMap(knownRenderers); 132 } 133 134 }