// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea // Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ package graphtea.ui.components.gpropertyeditor; import graphtea.ui.AttributeSetView; import javax.swing.*; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * this class is a part of gpropertyeditor, which creates a property editor with a jtable * so it is implementation os TableCellRenderer. it returns a renderer for a cell by the * "type of Object" that is stored in that cell. * u can register for each class a renderer by the method registerRenderer. * * @see graphtea.ui.components.gpropertyeditor.GPropertyEditor * * @author azin azadi */ public class GCellRenderer implements TableCellRenderer, ListCellRenderer { public static HashMap<Class, GBasicCellRenderer> knownRenderers = new HashMap<>(); private AttributeSetView attributes; //private int lastRow,lastColumn; private HashMap<Integer, Component> lastRenderers = new HashMap<>(); public static final Color SELECTED_COLOR = Color.red; /** * returns the last generated renderer by this object for the given row, * note that this is not a very safe method, It may return a generated renderer for another table, * so use it carefully */ public Component getLastCreatedRenderer(int row) { return lastRenderers.get(row); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { String name = attributes.getNameAt(row); GBasicCellRenderer ren = attributes.getrenderer(name); Component rend = (ren != null ? ren.getRendererComponent(value) : getRendererFor(value)); lastRenderers.put(row, rend); if (rend == null) { return null; } int h = (int) rend.getPreferredSize().getHeight(); if (h > 5) setRowHeight(table, row, h); if (isSelected) { rend.setForeground(SELECTED_COLOR); } return rend; } private void setRowHeight(JTable table, int row, int h) { if (table.getRowHeight(row) != h) table.setRowHeight(row, h); } /** * return a renderer for he object from previously registered renderers */ public static Component getRendererFor(Object value) { //todo: value=null => bug // lastRow=row;lastColumn=column; if (value == null) return null; //try to find the best renderer for value GBasicCellRenderer renderer = null; Class<?> valueClass = value.getClass(); Class c = valueClass; //search super classes while (renderer == null && c != Object.class) { renderer = knownRenderers.get(c); c = c.getSuperclass(); } if (renderer == null) for (Class cc : c.getInterfaces()) if ((renderer = knownRenderers.get(cc)) != null) break; if (renderer == null) { //search implementing interfaces Set<Class> keys = knownRenderers.keySet(); // Class cc[] = value.getClass().getInterfaces(); for (Class cc : keys) { if (cc.isAssignableFrom(valueClass)) { renderer = knownRenderers.get(cc); break; } } } if (renderer == null) return new JLabel(value + ""); else return renderer.getRendererComponent(value); } /** * register the "renderer" for the "clazz". so after this, calls to getTableCellRendererComponent method will * return this renderer if the value passed to that method has the same class with "clazz" */ public static void registerRenderer(Class clazz, GBasicCellRenderer renderer) { // renderers.put(clazz, renderer); knownRenderers.put(clazz, renderer); } public void setAtrView(AttributeSetView attributes) { this.attributes = attributes; } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component rendererFor = getRendererFor(value); if (isSelected) { rendererFor.setForeground(Color.red); rendererFor.setBackground(Color.blue); } lastRenderers.put(index, rendererFor); return rendererFor; } /** * @return known editors as an unmodifiable map */ public static Map<Class, GBasicCellRenderer> getKnownRenderers(){ return Collections.unmodifiableMap(knownRenderers); } }