Package DisplayProject.swingdisplayer

Source Code of DisplayProject.swingdisplayer.TestWin$PropertyColumnModel

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
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.