|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form.editors2; import java.awt.*; import java.beans.*; import java.util.*; import java.io.*; import javax.swing.table.*; import org.openide.util.NbBundle; import org.openide.explorer.propertysheet.editors.XMLPropertyEditor; /** * A property editor for jjavax.swing.table.TableModel. * @author Ian Formanek, Tomas Pavek */ public class TableModelEditor implements PropertyEditor, XMLPropertyEditor { public TableModelEditor() { support = new PropertyChangeSupport (this); } public Object getValue () { return table; } public void setValue (Object value) { table = new NbTableModel ((TableModel) value); support.firePropertyChange ("", null, null); // NOI18N } public String getAsText () { return null; } public void setAsText (String string) { } public String getJavaInitializationString () { TableModel m = (TableModel) getValue (); StringBuffer titlesSB = new StringBuffer (); int i = m.getColumnCount (); int j = m.getRowCount (); titlesSB.append ("{\n\t\t"); // NOI18N if (i > 0) { String s = m.getColumnName (0); titlesSB.append ("\"").append (s != null ? s : "").append ('"'); // NOI18N for (int k = 1; k < i; k++) { String s1 = m.getColumnName (k); titlesSB.append (", \"").append (s1 != null ? s1 : "").append ('"'); // NOI18N } } titlesSB.append ("\n\t}"); // NOI18N boolean generateTypes = false; StringBuffer typesSB = new StringBuffer (); typesSB.append ("{\n\t\t"); // NOI18N if (i > 0) { typesSB.append (m.getColumnClass (0).getName ()).append (".class"); // NOI18N if (m.getColumnClass (0) != Object.class) generateTypes = true; for (int k = 1; k < i; k++) { if (m.getColumnClass (k) != Object.class) generateTypes = true; typesSB.append (", ").append (m.getColumnClass (k).getName ()).append (".class"); // NOI18N } } typesSB.append ("\n\t}"); // NOI18N boolean generateEditable = false; StringBuffer editableSB = new StringBuffer (); editableSB.append ("{\n\t\t"); // NOI18N if (i > 0) { editableSB.append (m.isCellEditable (0, 0)); if (!m.isCellEditable (0, 0)) generateEditable = true; for (int k = 1; k < i; k++) { if (!m.isCellEditable (0, k)) generateEditable = true; editableSB.append (", ").append (m.isCellEditable (0, k)); // NOI18N } } editableSB.append ("\n\t}"); // NOI18N StringBuffer dataSB = new StringBuffer (); dataSB.append ("{\n\t\t"); // NOI18N if (j > 0) { for (int l = 0; l < j; l++) { if (l != 0) dataSB.append (",\n\t\t"); // NOI18N if (i == 0) { dataSB.append ("{}"); // NOI18N } else { Object obj = m.getValueAt (l, 0); dataSB.append ('{').append (getAsString (obj)); for (int i1 = 1; i1 < i; i1++) { obj = m.getValueAt (l, i1); dataSB.append (", ").append (getAsString (obj)); // NOI18N } dataSB.append ('}'); } } } dataSB.append ("\n\t}"); // NOI18N if (generateEditable || generateTypes) { return "new javax.swing.table.DefaultTableModel(\n" + // NOI18N "\tnew Object [][] " + new String (dataSB) + ",\n" + // NOI18N "\tnew String [] " + new String (titlesSB) + "\n" + // NOI18N ") {\n" + // NOI18N (generateTypes ? ( "\tClass[] types = new Class [] " + new String (typesSB) + ";\n") : // NOI18N "") + // NOI18N (generateEditable ? ( "\tboolean[] canEdit = new boolean [] " + new String (editableSB) + ";\n") : // NOI18N "") + // NOI18N (generateTypes ? ( "\n" + // NOI18N "\tpublic Class getColumnClass(int columnIndex) {\n" + // NOI18N "\t\treturn types [columnIndex];\n" + // NOI18N "\t}\n") : // NOI18N "") + // NOI18N (generateEditable ? ( "\n" + // NOI18N "\tpublic boolean isCellEditable(int rowIndex, int columnIndex) {\n" + // NOI18N "\t\treturn canEdit [columnIndex];\n" + // NOI18N "\t}\n") : // NOI18N "") + // NOI18N "}"; // NOI18N } else { return "new javax.swing.table.DefaultTableModel(\n" + // NOI18N "\tnew Object [][] " + new String (dataSB) + ",\n" + // NOI18N "\tnew String [] " + new String (titlesSB) + "\n" + // NOI18N ")"; // NOI18N } } public String[] getTags () { return null; } public boolean isPaintable () { return false; } public void paintValue (Graphics g, Rectangle rectangle) { } public boolean supportsCustomEditor () { return true; } public Component getCustomEditor () { return new CustomTableModelEditor (this); } public void addPropertyChangeListener (PropertyChangeListener propertyChangeListener) { support.addPropertyChangeListener (propertyChangeListener); } public void removePropertyChangeListener (PropertyChangeListener propertyChangeListener) { support.removePropertyChangeListener (propertyChangeListener); } // ------------ // XMLPropertyEditor implementation private static final String XML_TABLE = "Table"; // NOI18N private static final String XML_COLUMN = "Column"; // NOI18N private static final String XML_DATA = "Data"; // NOI18N private static final String ATTR_COLUMN_COUNT = "columnCount"; // NOI18N private static final String ATTR_ROW_COUNT = "rowCount"; // NOI18N private static final String ATTR_TITLE = "title"; // NOI18N private static final String ATTR_TYPE = "type"; // NOI18N private static final String ATTR_EDITABLE = "editable"; // NOI18N private static final String ATTR_VALUE = "value"; // NOI18N public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) { org.w3c.dom.Element tableEl = doc.createElement(XML_TABLE); int colCount = table.getColumnCount(); int rowCount = table.getRowCount(); tableEl.setAttribute(ATTR_COLUMN_COUNT, Integer.toString(colCount)); tableEl.setAttribute(ATTR_ROW_COUNT, Integer.toString(rowCount)); for (int i=0; i < colCount; i++) { NbTableModel.ColumnItem column = table.getColumnItem(i); org.w3c.dom.Element columnEl = doc.createElement(XML_COLUMN); columnEl.setAttribute(ATTR_TITLE, column.title); columnEl.setAttribute(ATTR_TYPE, column.type.getName()); columnEl.setAttribute(ATTR_EDITABLE, column.editable ? "true":"false"); // NOI18N boolean anyData = false; for (int j=0; j < rowCount; j++) if (column.rows.get(j) != null) { anyData = true; break; } if (anyData) for (int j=0; j < rowCount; j++) { org.w3c.dom.Element dataEl = doc.createElement(XML_DATA); dataEl.setAttribute(ATTR_VALUE, valueToString(column.rows.get(j))); columnEl.appendChild(dataEl); } tableEl.appendChild(columnEl); } return tableEl; } public void readFromXML(org.w3c.dom.Node element) throws IOException { if (!XML_TABLE.equals(element.getNodeName())) throw new IOException(getReadingErrorMessage()); // NOI18N org.w3c.dom.NamedNodeMap tableAttr = element.getAttributes(); if (tableAttr == null) return; IOException ioex = null; org.w3c.dom.Node node; // first read columnCount and rowCount attributes int columnCount = -1; int rowCount = -1; node = tableAttr.getNamedItem(ATTR_COLUMN_COUNT); if (node != null) { try { columnCount = Integer.parseInt(node.getNodeValue()); } catch (java.lang.NumberFormatException e) { ioex = new IOException(getReadingErrorMessage()); org.openide.ErrorManager.getDefault().annotate(ioex, e); } } node = tableAttr.getNamedItem(ATTR_ROW_COUNT); if (node != null) { try { rowCount = Integer.parseInt(node.getNodeValue()); } catch (java.lang.NumberFormatException e) { if (ioex == null) ioex = new IOException(getReadingErrorMessage()); org.openide.ErrorManager.getDefault().annotate(ioex, e); } } if (columnCount < 0 || rowCount < 0) { if (ioex == null) ioex = new IOException(getReadingErrorMessage()); throw ioex; } java.util.List columns = new ArrayList(columnCount); // go through the column data nodes and read the columns org.w3c.dom.NodeList columnNodes = element.getChildNodes(); for (int i=0, cCount=columnNodes.getLength(); i < cCount; i++) { org.w3c.dom.Node cNode = columnNodes.item(i); if (!XML_COLUMN.equals(cNode.getNodeName())) continue; org.w3c.dom.NamedNodeMap columnAttr = cNode.getAttributes(); if (columnAttr == null) continue; // get title, type and editable attributes String title = null; Class type = null; Boolean editable = null; node = columnAttr.getNamedItem(ATTR_TITLE); if (node != null) title = node.getNodeValue(); node = columnAttr.getNamedItem(ATTR_TYPE); if (node != null) { try { type = Class.forName(node.getNodeValue()); } catch (Exception e) { ioex = new IOException(getReadingErrorMessage()); org.openide.ErrorManager.getDefault().annotate(ioex, e); } } node = columnAttr.getNamedItem(ATTR_EDITABLE); if (node != null) editable = Boolean.valueOf(node.getNodeValue()); if (title == null || type == null || editable == null) { if (ioex == null) ioex = new IOException(getReadingErrorMessage()); throw ioex; } java.util.List columnData = new ArrayList(rowCount); // read the column data org.w3c.dom.NodeList dataNodes = cNode.getChildNodes(); for (int j=0, dCount=dataNodes.getLength(); j < dCount; j++) { org.w3c.dom.Node dNode = dataNodes.item(j); if (!XML_DATA.equals(dNode.getNodeName())) continue; org.w3c.dom.NamedNodeMap dataAttr = dNode.getAttributes(); if (dataAttr == null) continue; // get the value attribute Object value = null; node = dataAttr.getNamedItem(ATTR_VALUE); if (node != null) { try { value = stringToValue(node.getNodeValue(), type); } catch (IllegalArgumentException e) { ioex = new IOException(getReadingErrorMessage()); org.openide.ErrorManager.getDefault().annotate(ioex, e); throw ioex; } } columnData.add(value); } // check the row count if (columnData.size() != rowCount) { if (columnData.size() == 0) for (int ii=0; ii < rowCount; ii++) columnData.add(null); else throw new IOException(getReadingErrorMessage()); } // create the column columns.add(new NbTableModel.ColumnItem(title, type, editable.booleanValue(), columnData)); } // check the column count if (columns.size() != columnCount) throw new IOException(getReadingErrorMessage()); // create the model instance table = new NbTableModel(columns, rowCount); } // ----------- private static ResourceBundle getBundle() { return NbBundle.getBundle(TableModelEditor.class); } private static String getReadingErrorMessage() { return getBundle().getString("ERR_InvalidXMLFormat"); // NOI18N } private static String valueToString(Object value) { if (value instanceof Integer || value instanceof Short || value instanceof Byte || value instanceof Long || value instanceof Float || value instanceof Double || value instanceof Boolean || value instanceof Character) return value.toString(); if (value instanceof String) return (String)value; if (value == null) return "null"; // NOI18N return null; // is not a primitive type } private static Object stringToValue(String encoded, Class type) { if ("null".equals(encoded)) // NOI18N return null; if (type == Object.class) return encoded; if (Integer.class.isAssignableFrom(type) || Integer.TYPE.equals(type)) return Integer.valueOf(encoded); if (Short.class.isAssignableFrom(type) || Short.TYPE.equals(type)) return Short.valueOf(encoded); if (Byte.class.isAssignableFrom(type) || Byte.TYPE.equals(type)) return Byte.valueOf(encoded); if (Long.class.isAssignableFrom(type) || Long.TYPE.equals(type)) return Long.valueOf(encoded); if (Float.class.isAssignableFrom(type) || Float.TYPE.equals(type)) return Float.valueOf(encoded); if (Double.class.isAssignableFrom(type) || Double.TYPE.equals(type)) return Double.valueOf(encoded); if (Boolean.class.isAssignableFrom(type) || Boolean.TYPE.equals(type)) return Boolean.valueOf(encoded); if (Character.class.isAssignableFrom(type) || Character.TYPE.equals(type)) return new Character(encoded.charAt(0)); if (String.class.isAssignableFrom(type)) return encoded; throw new IllegalArgumentException(); } static String getAsString (Object o) { if (o == null) return "null"; // NOI18N if (o instanceof String) if (o == null) return "\"\""; // NOI18N else return "\"" + o + "\""; // NOI18N String s = o.getClass ().getName (); int g = s.lastIndexOf ('.'); if (g >= 0) s = s.substring (g + 1, s.length ()); String cast = ""; // NOI18N if (o instanceof Byte) cast = "(byte) "; // NOI18N else if (o instanceof Short) cast = "(short) "; // NOI18N return "new " + s + "(" + cast + o + ")"; // NOI18N } static Object getDefaultValue (Class c) { return null; } // ----------------------------------------------------------------------------- // NbTableModel public static class NbTableModel extends AbstractTableModel implements Externalizable { /** generated Serialized Version UID */ static final long serialVersionUID = -6843008677521167210L; java.util.List columns; int rowCount; transient boolean alwaysEditable = false; /** For externalization only */ public NbTableModel() { } public NbTableModel(String[] titles, Class[] types, boolean[] editable) { this(titles,types,editable,4); } public NbTableModel(String[] titles, Class[] types, boolean[] editable, int rowCount) { this.rowCount = rowCount; columns = new ArrayList(titles.length); for (int i=0; i < titles.length; i++) columns.add(new ColumnItem(titles[i],types[i],editable[i],rowCount)); } public NbTableModel(TableModel createFrom) { ResourceBundle bundle = getBundle(); if (createFrom == null) { rowCount = 4; // 4 rows and 4 columns by default columns = new ArrayList(20); for (int i=0; i < 4; i++) columns.add(new ColumnItem(bundle.getString("CTL_Title")+" "+Integer.toString(i+1), Object.class, true, rowCount)); } else { rowCount = createFrom.getRowCount(); int colCount = createFrom.getColumnCount(); columns = new ArrayList(colCount); if (createFrom instanceof NbTableModel) { NbTableModel model = (NbTableModel) createFrom; for (int i=0; i < colCount; i++) { ColumnItem ci = (ColumnItem) model.columns.get(i); columns.add(new ColumnItem(ci)); } } else { for (int i=0; i < colCount; i++) { ColumnItem ci = new ColumnItem(createFrom.getColumnName(i), createFrom.getColumnClass(i), true, rowCount); for (int j=0; j < rowCount; j++) ci.rows.set(j, createFrom.getValueAt(j,i)); columns.add(ci); } } } } NbTableModel(java.util.List columns, int rowCount) { this.columns = columns; this.rowCount = rowCount; } // from AbstractTableModel public Class getColumnClass(int i) { ColumnItem ci = (ColumnItem) columns.get(i); return ci.type; } public void setColumnClass(int i, Class type) { ColumnItem ci = (ColumnItem) columns.get(i); ci.type = type; } // from AbstractTableModel public String getColumnName(int i) { ColumnItem ci = (ColumnItem) columns.get(i); return ci.title; } public void setColumnName(int i, String title) { ColumnItem ci = (ColumnItem) columns.get(i); ci.title = title; } // from TableModel public int getRowCount() { return rowCount; } // from TableModel public int getColumnCount() { return columns.size(); } public boolean isColumnEditable(int i) { // this method returns design time settings - doesn't reflect alwaysEditable ColumnItem ci = (ColumnItem) columns.get(i); return ci.editable; } // from AbstractTableModel public boolean isCellEditable(int i, int j) { // this is used by a real table - alwaysEditable true means that table // is fully editable (no matter the design settings) if (alwaysEditable) return true; ColumnItem ci = (ColumnItem) columns.get(j); return ci.editable; } public void setColumnEditable(int i, boolean editable) { ColumnItem ci = (ColumnItem) columns.get(i); ci.editable = editable; } // from TableModel public Object getValueAt(int row, int column) { ColumnItem ci = (ColumnItem) columns.get(column); return ci.rows.get(row); } // from AbstractTableModel public void setValueAt(Object obj, int row, int column) { ColumnItem ci = (ColumnItem) columns.get(column); ci.rows.set(row, obj); fireTableCellUpdated(row, column); } private ColumnItem getColumnItem(int i) { return (ColumnItem) columns.get(i); } void setRowCount(int newRowCount) { if (newRowCount == rowCount) return; for (int i=0, n=columns.size(); i < n; i++) { java.util.List rows = ((ColumnItem)columns.get(i)).rows; if (newRowCount > rowCount) { for (int nr = newRowCount-rowCount; nr > 0; nr--) rows.add(null); } else { // newRowCount < rowCount for (int rn = rowCount - newRowCount; rn > 0; rn--) rows.remove(newRowCount + rn - 1); } } int rc = rowCount; rowCount = newRowCount; if (newRowCount > rc) fireTableRowsInserted(rc, newRowCount - 1); else // newRowCount < rc fireTableRowsDeleted(newRowCount, rc - 1); } // adds one row at the index void addRow(int index) { if (index >= 0 && index <= rowCount) { for (int i=0, n=columns.size(); i < n; i++) ((ColumnItem)columns.get(i)).rows.add(index, null); rowCount++; fireTableRowsInserted(index, index); } } // removes one row from index void removeRow(int index) { if (index >= 0 && index < rowCount) { for (int i=0, n=columns.size(); i < n; i++) ((ColumnItem)columns.get(i)).rows.remove(index); rowCount--; fireTableRowsDeleted(index, index); } } void moveRow(int fromIndex, int toIndex) { if (columns.size() > 0 && fromIndex >= 0 && fromIndex < rowCount && toIndex >= 0 && toIndex < rowCount && fromIndex != toIndex) { for (int i=0, n=columns.size(); i < n; i++) { java.util.List rows = ((ColumnItem)columns.get(i)).rows; Object obj = rows.get(toIndex); rows.set(toIndex, rows.get(fromIndex)); rows.set(fromIndex, obj); } fireTableStructureChanged(); } } void setColumnCount(int newColumnCount) { ResourceBundle bundle = getBundle(); int colCount = columns.size(); if (newColumnCount == colCount) return; if (newColumnCount > colCount) { for (int nc=newColumnCount-colCount; nc > 0; nc--) columns.add(new ColumnItem(bundle.getString("CTL_Title")+" "+Integer.toString(newColumnCount-nc+1), Object.class, true, rowCount)); } else { // newColumnCount < colCount for (int cn=colCount-newColumnCount; cn > 0; cn--) columns.remove(newColumnCount + cn - 1); } fireTableStructureChanged(); } // adds one column at index void addColumn(int index) { if (index >=0 && index <= columns.size()) { columns.add(index, new ColumnItem(getBundle().getString("CTL_Title")+" "+Integer.toString(index+1), Object.class, true, rowCount)); // rename default titles for (int i=index+1, n=columns.size(); i < n; i++) { ColumnItem ci = (ColumnItem) columns.get(i); renameDefaultColumnTitle(ci, i, i+1); } fireTableStructureChanged(); } } // removes one column at index void removeColumn(int index) { if (index >=0 && index < columns.size()) { columns.remove(index); // rename default titles for (int i=index, n=columns.size(); i < n; i++) { ColumnItem ci = (ColumnItem) columns.get(i); renameDefaultColumnTitle(ci, i+2, i+1); } fireTableStructureChanged(); } } void moveColumn(int fromIndex,int toIndex) { if (fromIndex >= 0 && fromIndex < columns.size() && toIndex >= 0 && toIndex < columns.size() && fromIndex != toIndex) { ColumnItem ciFrom = (ColumnItem) columns.get(fromIndex); ColumnItem ciTo = (ColumnItem) columns.get(toIndex); // also rename default titles renameDefaultColumnTitle(ciFrom, fromIndex+1, toIndex+1); renameDefaultColumnTitle(ciTo, toIndex+1, fromIndex+1); columns.set(toIndex, ciFrom); columns.set(fromIndex, ciTo); fireTableStructureChanged(); } } // renames default column title according to new column's position // e.g. with params 2 and 3 - "Title 2" is renamed to "Title 3" private static void renameDefaultColumnTitle(ColumnItem ci, int fromIndex, int toIndex) { String fromStr = getBundle().getString("CTL_Title")+" "+Integer.toString(fromIndex); if (fromStr.equals(ci.title)) ci.title = getBundle().getString("CTL_Title")+" "+Integer.toString(toIndex); } public void writeExternal(ObjectOutput oo) throws IOException { // backward compatibility must be ensured... (table model was implemented using arrays sooner) oo.writeInt(rowCount); int colCount = columns.size(); oo.writeInt(colCount); String[] titles = new String[colCount]; boolean[] editable = new boolean[colCount]; for (int i=0; i < colCount; i++) { ColumnItem ci = (ColumnItem) columns.get(i); titles[i] = ci.title; editable[i] = ci.editable; } oo.writeObject(titles); oo.writeObject(editable); for (int i=0; i < colCount; i++) { ColumnItem ci = (ColumnItem) columns.get(i); oo.writeObject(ci.type.getName()); } for (int i=0; i < rowCount; i++) for (int j=0; j < colCount; j++) { ColumnItem ci = (ColumnItem) columns.get(j); if (ci.rows.get(i) instanceof Serializable) oo.writeObject(ci.rows.get(i)); else oo.writeObject(null); } } public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException { // reading is in the previous format (when table model was implemented using arrays) rowCount = oi.readInt(); int colCount = oi.readInt(); columns = new ArrayList(colCount); String[] titles = (String[]) oi.readObject(); boolean[] editable = (boolean[]) oi.readObject(); for (int i=0; i < colCount; i++) columns.add(new ColumnItem(titles[i],Class.forName((String)oi.readObject()), editable[i], rowCount)); for (int i=0; i < rowCount; i++) for (int j=0; j < colCount; j++) { ColumnItem ci = (ColumnItem) columns.get(j); ci.rows.set(i, oi.readObject()); } } // helper class for holding data of a column private static class ColumnItem { String title; Class type; boolean editable; java.util.List rows; // values in the column ColumnItem(String title, Class type, boolean editable, int rowCount) { this.title = title; this.type = type; this.editable = editable; rows = new ArrayList(rowCount); for (int i=0; i < rowCount; i++) rows.add(null); } ColumnItem(String title, Class type, boolean editable, java.util.List data) { this.title = title; this.type = type; this.editable = editable; rows = data; } ColumnItem(ColumnItem ci) { this.title = ci.title; this.type = ci.type; this.editable = ci.editable; int rowCount = ci.rows.size(); rows = new ArrayList(rowCount); for (int i=0; i < rowCount; i++) rows.add(ci.rows.get(i)); } } // Class ColumnItem } // Class NbTableModel // ----------------------------------------------------------------------------- // private variables private NbTableModel table; private PropertyChangeSupport support; } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.