Package DisplayProject.swingdisplayer

Source Code of DisplayProject.swingdisplayer.TestWin$PropertyColumnModel

package DisplayProject.swingdisplayer;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractCellEditor;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

@SuppressWarnings("serial")
public class TestWin extends JFrame {

  private static class ArrayDisplayer implements TableCellRenderer {
    private boolean isExpanded = true;
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {

      if (value == null) {
        return null;
      }
      else if (value.getClass().isArray()) {
        Class<?> type = value.getClass().getComponentType();
        int length = Array.getLength(value);
        String rootNodeText = type.getSimpleName() + "[" + length + "]";
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(rootNodeText);
        for (int i = 0; i < length; i++) {
          DefaultMutableTreeNode aNode = new DefaultMutableTreeNode("[" + i + "] " + Array.get(value, i));
          rootNode.add(aNode);
        }
        JTree tree = new JTree(rootNode);
        tree.setShowsRootHandles(false);
        tree.setEditable(false);
        tree.setRootVisible(true);
        if (isExpanded) {
          tree.expandRow(0);
        }
        else {
          tree.collapseRow(0);
        }
        tree.setOpaque(false);
        tree.setRowHeight(table.getRowHeight());
        tree.setCellRenderer(new DefaultTreeCellRenderer() {
          @Override
          public Color getBackground() {
            return null;
          }
          @Override
          public Color getBackgroundNonSelectionColor() {
            return null;
          }
          @Override
          public Icon getOpenIcon() {
            return null;
          }
          @Override
          public Icon getLeafIcon() {
            return null;
          }
        });
        int minHeight = (1 + (isExpanded ? Math.min(length, 5): 0)) * tree.getRowHeight();
        if (minHeight != table.getRowHeight(row)) {
          table.setRowHeight(row, minHeight);
        }
        if (minHeight == table.getRowHeight()) {
          return tree;
        }
        JScrollPane sp = new JScrollPane(tree);
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        sp.setOpaque(true);
        sp.setBorder(null);
        return sp;
      }
      //      if (value instanceof Array) {}
      // TODO Auto-generated method stub
      return new JLabel(value.toString());
    }
  }

  private static class NullableProperty {
    private PropertyDescriptor property;
    private PropertyDescriptor isSet;
   
    public NullableProperty(PropertyDescriptor property) {
      this.property = property;
      this.isSet = null;
    }
   
    public void setIsSetProperty(PropertyDescriptor property) {
      this.isSet = property;
    }
   
    public PropertyDescriptor getProperty() {
      return this.property;
    }
   
    public boolean isNull(Component comp) {
      if (isSet != null) {
        try {
          Boolean result = (Boolean)isSet.getReadMethod().invoke(comp);
          return result.booleanValue() == false;
        }
        catch (Exception e) {}
      }
      return false;
    }
   
    /**
     * This method sees if the passed property descriptor is in the correct format to be an isXXXSet()
     * method (eg isForegroundSet(), isFontSet(), etc). To be in this format, it must be boolean, be
     * readonly and have a name matching is<XXX>Set(). In this case, XXX, corrected to match the bean
     * spec, will be returned. Otherwise, null will be returned.
     * @param pd
     * @return
     */
    public static String getIsSetPropertyName(PropertyDescriptor pd) {
      if (pd != null && pd.getWriteMethod() == null && pd.getPropertyType() != null && pd.getPropertyType().equals(Boolean.class)) {
        Method m = pd.getReadMethod();
        if (m != null && m.getName().startsWith("is") && m.getName().endsWith("Set") && m.getName().length() >= 6) {
          String result = m.getName().substring(2, m.getName().length() - 3);
          StringBuilder res = new StringBuilder(result);
          if (result.length() == 1) {
            res.setCharAt(0, Character.toLowerCase(res.charAt(0)));
          }
          else if (Character.isUpperCase(result.charAt(1))) {
            res.setCharAt(0, Character.toUpperCase(res.charAt(0)));
          }
          else {
            res.setCharAt(0, Character.toLowerCase(res.charAt(0)));
          }
          return res.toString();
        }
      }
      return null;
    }
  }
 
  private class PropertyModel extends AbstractTableModel {

    @SuppressWarnings("unused")
    private Component component;
    private List<NullableProperty> properties = null;
    public PropertyModel(Component component, PropertyDescriptor[] properties) {
      super();
     
      this.setProperties(properties);
      this.component = component;
    }

    public PropertyModel() {
      super();
    }

    public void setProperties(PropertyDescriptor[] properties) {
      // Sort these properties, strip out any invalid ones, and merge in the setters.
      this.properties = new ArrayList<NullableProperty>();
      Map<String, NullableProperty> map = new HashMap<String, NullableProperty>(properties.length);
      List<PropertyDescriptor> nulls = new ArrayList<PropertyDescriptor>();
      for (PropertyDescriptor pd : properties) {
        if (pd.getReadMethod() != null && pd.getPropertyType() != null) {
          // Ok, it seems valid at this point, see if it's a null property
          String propertyName = NullableProperty.getIsSetPropertyName(pd);
          if (propertyName != null) {
            // Yes, don't list it as a property in it's own right.
            nulls.add(pd);
          }
          else {
            // It's a property in it's own right.
            NullableProperty np = new NullableProperty(pd);
            this.properties.add(np);
            map.put(pd.getName(), np);
          }
        }
      }
     
      // Iterate through the nulls and mark their properties as being nullable
      for (PropertyDescriptor pd : nulls) {
        String propertyName = NullableProperty.getIsSetPropertyName(pd);
        NullableProperty np = map.get(propertyName);
        if (np != null) {
          np.setIsSetProperty(pd);
        }
      }
    }

    public Class<?> getColumnClass(int columnIndex) {
      switch (columnIndex) {
      case 0:    return Object.class;
      case 1:    return String.class;
      case 2:    return Object.class;
      defaultreturn null;
      }
    }

    public int getColumnCount() {
      return 3;
    }

    public String getColumnName(int columnIndex) {
      switch (columnIndex) {
      case 0:    return "";
      case 1:    return "Name";
      case 2:    return "Value";
      defaultreturn null;
      }
    }

    public int getRowCount() {
      return properties == null ? 0 : properties.size();
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
      if (rowIndex >= 0 && rowIndex < getRowCount()) {
        switch (columnIndex) {
        case 0return null;
        case 1return properties.get(rowIndex).getProperty().getName();
        case 2: return properties.get(rowIndex).getProperty();
        default:
          break;
        }
      }
      return null;
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
      if (rowIndex >= 0 && rowIndex < properties.size() && columnIndex == 2) {
        Method readMethod = properties.get(rowIndex).getProperty().getReadMethod();
        if (readMethod != null) {
          if (displayerMap.get(readMethod.getReturnType()) != null) {
            return properties.get(rowIndex).getProperty().getWriteMethod() != null;
          }
        }
      }
      return false;
    }

    public void setValueAt(Object value, int rowIndex, int columnIndex) {
      // TODO Auto-generated method stub
    }
  }

  private Color alternatingRowColor = new Color(255, 255, 210);
 
  private final Map<Class<?>, PropertyDisplayer> displayerMap = new HashMap<Class<?>, PropertyDisplayer>();
 
  private void setup() {
    this.displayerMap.put(Boolean.TYPE, new BooleanDisplayer());
    this.displayerMap.put(Color.class, new ColorDisplayer());
    this.displayerMap.put(Dimension.class, new DimensionDisplayer());
    this.displayerMap.put(Integer.TYPE, new NumberDisplayer());
    this.displayerMap.put(Short.TYPE, new NumberDisplayer());
    this.displayerMap.put(Long.TYPE, new NumberDisplayer());
    this.displayerMap.put(Byte.TYPE, new NumberDisplayer());
    this.displayerMap.put(Float.TYPE, new NumberDisplayer());
    this.displayerMap.put(Double.TYPE, new NumberDisplayer());
    this.displayerMap.put(Font.class, new FontDisplayer());
  }
 
  private class PropertyCellRenderer implements TableCellRenderer {
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {

      Component result;
      if (value instanceof PropertyDescriptor) {
        PropertyDescriptor pd = (PropertyDescriptor)value;
        Method reader = pd.getReadMethod();
        if (reader != null) {
          try {
            Class<?> returnType = reader.getReturnType();
            if (returnType != null) {
              Object val = reader.invoke(component);
              PropertyDisplayer displayer = displayerMap.get(returnType);
              if (displayer != null) {
                displayer.preSelect(pd, component, table);
                result = displayer.getTableCellRendererComponent(table, val, isSelected, hasFocus, pd.getWriteMethod() == null, component, row, column);
                result.setForeground(displayer.getForegroundColor(table, isSelected, hasFocus, hasFocus));
              }
              else if (val != null && val.getClass().isArray()) {
                result = new ArrayDisplayer().getTableCellRendererComponent(table, val, isSelected, hasFocus, row, column);
              }
              else {
                result = new JLabel(val == null ? "" : val.toString());
                ((JLabel)result).setOpaque(true);
              }
            }
            else {
              result = new JLabel("<html><i>Null getter</i></html>");
            }
          }
          catch (Exception e) {
            result = new JLabel("<html><i>Not readable</i></html>");
          }
        }
        else {
          result = new JLabel("<html><i>Not readable</i></html>");
        }
      }
      else {
        result = new JLabel(value == null ? "" : value.toString());
        ((JLabel)result).setOpaque(true);
      }
      if (isSelected) {
        result.setBackground(table.getSelectionBackground());
        result.setForeground(table.getSelectionForeground());
      }
      else if (row % 2 == 1) {
        result.setBackground(alternatingRowColor);
        result.setForeground(Color.black);
      }
      else {
        result.setBackground(Color.white);
        result.setForeground(Color.black);
      }
      return result;
    }
  }

  private class PropertyCellEditor extends AbstractCellEditor implements TableCellEditor {

    private TableCellEditor editor = null;
    public Component getTableCellEditorComponent(JTable table,
        Object value, boolean isSelected, int row, int column) {

      editor = null;
      Component result = null;
      if (value instanceof PropertyDescriptor) {
        PropertyDescriptor pd = (PropertyDescriptor)value;
        Method reader = pd.getReadMethod();
        if (reader != null) {
          try {
            Object val = reader.invoke(component);
           
            PropertyDisplayer displayer = displayerMap.get(reader.getReturnType());
            if (displayer != null) {
              editor = displayer;
              displayer.setEditingInformation(component, pd);
              result = editor.getTableCellEditorComponent(table, val, isSelected, row, column);
            }
          }
          catch (Exception e) {
            System.out.println(e);
          }
        }
      }
      return result;
    }

    public void cancelCellEditing() {
      if (editor != null) {
        editor.cancelCellEditing();
        editor = null;
        super.cancelCellEditing();
      }
    }

    public Object getCellEditorValue() {
      if (editor != null) {
        return editor.getCellEditorValue();
      }
      return null;
    }

    public boolean isCellEditable(EventObject anEvent) {
      if (editor != null) {
        return editor.isCellEditable(anEvent);
      }
      return true;
    }

    public boolean shouldSelectCell(EventObject anEvent) {
      if (editor != null) {
        return editor.shouldSelectCell(anEvent);
      }
      return true;
    }

    public boolean stopCellEditing() {
      if (editor != null) {
        boolean result = editor.stopCellEditing();
        if (result) {
          super.stopCellEditing();
          editor = null;
        }
        return result;
      }
      return true;
    }
  }

  private class PropertyColumnModel extends DefaultTableColumnModel {
    public PropertyColumnModel() {
      TableColumn col = new TableColumn();
      col.setResizable(false);
      col.setPreferredWidth(32);
      col.setMinWidth(col.getPreferredWidth());
      col.setMaxWidth(col.getPreferredWidth());
      col.setModelIndex(0);
      col.setHeaderValue(" ");
      this.addColumn(col);

      col = new TableColumn();
      col.setResizable(true);
      col.setPreferredWidth(100);
      col.setModelIndex(1);
      col.setHeaderValue("Name");
      this.addColumn(col);

      col = new TableColumn();
      col.setResizable(true);
      col.setPreferredWidth(100);
      col.setModelIndex(2);
      col.setHeaderValue("Value");
      col.setCellRenderer(new PropertyCellRenderer());
      col.setCellEditor(new PropertyCellEditor());
      this.addColumn(col);
    }
  }
  private JTable table;
  private PropertyModel model;
  private Component component;

  public TestWin() {
    this.setup();
    table = new JTable() {
      @Override
      public Component prepareRenderer(TableCellRenderer renderer,
          int row, int column) {
        Component result =  super.prepareRenderer(renderer, row, column);
        //        if (result instanceof JComponent) {
        //          ((JComponent)result).setOpaque(true);
        //          if (row % 2 == 1) {
        //            result.setBackground(alternatingRowColor);
        //          }
        //          else {
        //            result.setBackground(Color.white);
        //          }
        //        }
        return result;
      }
      @Override
      public void changeSelection(int rowIndex, int columnIndex,
          boolean toggle, boolean extend) {
        // TODO Auto-generated method stub
        super.changeSelection(rowIndex, columnIndex, toggle, extend);
      }
    };

    this.model = new PropertyModel();
    table.setModel(model);
    table.setColumnModel(new PropertyColumnModel());
    this.getContentPane().add(new JScrollPane(table));
    this.setSize(400, 400);
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  }
  public void display(Component component, PropertyDescriptor[] properties) {
    this.component = component;
    this.model.setProperties(properties);
    this.setVisible(true);
  }
}
TOP

Related Classes of DisplayProject.swingdisplayer.TestWin$PropertyColumnModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.