diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/apichanges.xml
--- a/spi.viewmodel/apichanges.xml Mon May 31 22:14:44 2010 +0200
+++ b/spi.viewmodel/apichanges.xml Mon May 31 22:59:21 2010 +0200
@@ -384,6 +384,21 @@
+
+
+ Custom table cell renderers and editors.
+
+
+
+
+
+ This API introduce TableRendererModel and TableRendererModelFilter
+ that can be used to provide custom table cell renderers and cell editors.
+
+
+
+
+
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/manifest.mf
--- a/spi.viewmodel/manifest.mf Mon May 31 22:14:44 2010 +0200
+++ b/spi.viewmodel/manifest.mf Mon May 31 22:59:21 2010 +0200
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.spi.viewmodel/2
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/viewmodel/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.27
+OpenIDE-Module-Specification-Version: 1.28
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/modules/viewmodel/DelegatingCellEditor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/DelegatingCellEditor.java Mon May 31 22:59:21 2010 +0200
@@ -0,0 +1,190 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+package org.netbeans.modules.viewmodel;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.util.EventObject;
+import javax.swing.JTable;
+import javax.swing.event.CellEditorListener;
+import javax.swing.table.TableCellEditor;
+import org.netbeans.spi.viewmodel.TableRendererModel;
+import org.netbeans.spi.viewmodel.UnknownTypeException;
+import org.netbeans.swing.outline.Outline;
+import org.netbeans.swing.outline.OutlineModel;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Martin Entlicher
+ */
+class DelegatingCellEditor implements TableCellEditor {
+
+ private String columnID;
+ private TableCellEditor defaultEditor;
+ private TableCellEditor currentEditor;
+
+ public DelegatingCellEditor(String columnID, TableCellEditor defaultEditor) {
+ this.columnID = columnID;
+ this.defaultEditor = defaultEditor;
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+ Outline outline = (Outline) table;
+ OutlineModel om = (OutlineModel) outline.getModel();
+ TreeModelNode tmn = (TreeModelNode) DelegatingCellRenderer.getNodeAt(om, row);
+ TableRendererModel trm = tmn.getModel();
+ try {
+ if (trm.canEditCell(tmn.getObject(), columnID)) {
+ TableCellEditor editor = trm.getCellEditor(tmn.getObject(), columnID);
+ if (editor != null) {
+ currentEditor = editor;
+ return editor.getTableCellEditorComponent(table, value, isSelected, row, column);
+ }
+ }
+ } catch (UnknownTypeException ex) {
+ }
+ // No specific editor
+ currentEditor = defaultEditor;
+ return defaultEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
+ }
+
+ @Override
+ public Object getCellEditorValue() {
+ if (currentEditor != null) {
+ return currentEditor.getCellEditorValue();
+ }
+ Exceptions.printStackTrace(new IllegalStateException("No current editor."));
+ return null;
+ }
+
+ @Override
+ public boolean isCellEditable(EventObject anEvent) {
+ if (!(anEvent.getSource() instanceof Outline)) {
+ return false;
+ }
+ Outline outline = (Outline) anEvent.getSource();
+ if (!(anEvent instanceof MouseEvent)) {
+ return false;
+ }
+ MouseEvent event = (MouseEvent) anEvent;
+ Point p = event.getPoint();
+
+ // Locate the editor under the event location
+ //int column = outline.columnAtPoint(p);
+ int row = outline.rowAtPoint(p);
+ OutlineModel om = (OutlineModel) outline.getModel();
+ TreeModelNode tmn = (TreeModelNode) DelegatingCellRenderer.getNodeAt(om, row);
+ TableRendererModel trm = tmn.getModel();
+ try {
+ return trm.canEditCell(tmn.getObject(), columnID);
+ } catch (UnknownTypeException ex) {
+ }
+ return defaultEditor.isCellEditable(anEvent);
+ }
+
+ @Override
+ public boolean shouldSelectCell(EventObject anEvent) {
+ if (!(anEvent.getSource() instanceof Outline)) {
+ return false;
+ }
+ Outline outline = (Outline) anEvent.getSource();
+ if (!(anEvent instanceof MouseEvent)) {
+ return false;
+ }
+ MouseEvent event = (MouseEvent) anEvent;
+ Point p = event.getPoint();
+
+ // Locate the editor under the event location
+ //int column = outline.columnAtPoint(p);
+ int row = outline.rowAtPoint(p);
+ OutlineModel om = (OutlineModel) outline.getModel();
+ TreeModelNode tmn = (TreeModelNode) DelegatingCellRenderer.getNodeAt(om, row);
+ TableRendererModel trm = tmn.getModel();
+ try {
+ if (trm.canEditCell(tmn.getObject(), columnID)) {
+ TableCellEditor editor = trm.getCellEditor(tmn.getObject(), columnID);
+ if (editor != null) {
+ return editor.shouldSelectCell(anEvent);
+ }
+ }
+ } catch (UnknownTypeException ex) {
+ }
+ return defaultEditor.shouldSelectCell(anEvent);
+ }
+
+ @Override
+ public boolean stopCellEditing() {
+ if (currentEditor != null) {
+ boolean status = currentEditor.stopCellEditing();
+ currentEditor = null;
+ return status;
+ }
+ Exceptions.printStackTrace(new IllegalStateException("No current editor."));
+ return true;
+ }
+
+ @Override
+ public void cancelCellEditing() {
+ if (currentEditor != null) {
+ currentEditor.cancelCellEditing();
+ currentEditor = null;
+ }
+ Exceptions.printStackTrace(new IllegalStateException("No current editor."));
+ }
+
+ @Override
+ public void addCellEditorListener(CellEditorListener l) {
+ currentEditor.addCellEditorListener(l);
+ }
+
+ @Override
+ public void removeCellEditorListener(CellEditorListener l) {
+ currentEditor.removeCellEditorListener(l);
+ }
+
+}
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/modules/viewmodel/DelegatingCellRenderer.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/DelegatingCellRenderer.java Mon May 31 22:59:21 2010 +0200
@@ -0,0 +1,100 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+package org.netbeans.modules.viewmodel;
+
+import java.awt.Component;
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.tree.TreePath;
+import org.netbeans.spi.viewmodel.TableRendererModel;
+import org.netbeans.spi.viewmodel.UnknownTypeException;
+import org.netbeans.swing.outline.Outline;
+import org.netbeans.swing.outline.OutlineModel;
+import org.openide.explorer.view.Visualizer;
+import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Martin Entlicher
+ */
+class DelegatingCellRenderer implements TableCellRenderer {
+
+ private String columnID;
+ private TableCellRenderer defaultRenderer;
+
+ public DelegatingCellRenderer(String columnID, TableCellRenderer defaultRenderer) {
+ this.columnID = columnID;
+ this.defaultRenderer = defaultRenderer;
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ Outline outline = (Outline) table;
+ OutlineModel om = (OutlineModel) outline.getModel();
+ TreeModelNode tmn = (TreeModelNode) getNodeAt(om, row);
+ TableRendererModel trm = tmn.getModel();
+ try {
+ if (trm.canRenderCell(tmn.getObject(), columnID)) {
+ TableCellRenderer renderer = trm.getCellRenderer(tmn.getObject(), columnID);
+ if (renderer != null) {
+ return renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ }
+ }
+ } catch (UnknownTypeException ex) {
+ }
+ // No specific renderer
+ return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ }
+
+ static final Node getNodeAt(OutlineModel om, int row) {
+ Node result = null;
+ TreePath path = om.getLayout().getPathForRow(row);
+ if (path != null) {
+ result = Visualizer.findNode(path.getLastPathComponent());
+ }
+ return result;
+ }
+}
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/modules/viewmodel/OutlineTable.java
--- a/spi.viewmodel/src/org/netbeans/modules/viewmodel/OutlineTable.java Mon May 31 22:14:44 2010 +0200
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/OutlineTable.java Mon May 31 22:59:21 2010 +0200
@@ -652,6 +652,14 @@
if (ci < columnsToSet.length && columns[i] == columnsToSet[ci]) {
TableColumn tc = tcm.getColumn(tci);
tableColumns[i] = tc;
+ if (columns[i] instanceof Column) {
+ tableColumns[i].setCellEditor(new DelegatingCellEditor(
+ ((Column) columns[i]).getName(),
+ treeTable.getTable().getCellEditor(0, tci)));
+ tableColumns[i].setCellRenderer(new DelegatingCellRenderer(
+ ((Column) columns[i]).getName(),
+ treeTable.getTable().getCellRenderer(0, tci)));
+ }
if (columns[i].isHidden()) {
ecm.setColumnHidden(tc, true);
} else {
@@ -662,6 +670,12 @@
tableColumns[i] = tcm.getColumn(0);
if (columns[i] instanceof Column) {
tableColumns[i].setCellEditor(((Column)columns[i]).getTableCellEditor());
+ tableColumns[i].setCellEditor(new DelegatingCellEditor(
+ ((Column) columns[i]).getName(),
+ treeTable.getTable().getCellEditor(0, 0)));
+ tableColumns[i].setCellRenderer(new DelegatingCellRenderer(
+ ((Column) columns[i]).getName(),
+ treeTable.getTable().getCellRenderer(0, 0)));
}
}
}
@@ -910,7 +924,7 @@
((DefaultOutlineModel) m).setNodesColumnLabel(name);
}
}
-
+
/*
public List getExpandedPaths () {
List result = new ArrayList ();
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java
--- a/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java Mon May 31 22:14:44 2010 +0200
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java Mon May 31 22:59:21 2010 +0200
@@ -44,6 +44,7 @@
package org.netbeans.modules.viewmodel;
+import java.awt.Component;
import java.awt.Image;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
@@ -70,11 +71,13 @@
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
+import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import org.netbeans.spi.viewmodel.AsynchronousModelFilter;
@@ -504,6 +507,10 @@
public Object getObject () {
return object;
+ }
+
+ Models.CompoundModel getModel() {
+ return model;
}
private Task refreshTask;
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java
--- a/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java Mon May 31 22:14:44 2010 +0200
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java Mon May 31 22:59:21 2010 +0200
@@ -69,6 +69,8 @@
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
import org.netbeans.modules.viewmodel.AsynchronousModel;
import org.netbeans.modules.viewmodel.DefaultTreeExpansionManager;
@@ -241,7 +243,7 @@
// ; or the models directly
boolean hasLists = false;
int modelsSize = models.size();
- if (11 <= modelsSize && modelsSize <= 14) {
+ if (11 <= modelsSize && modelsSize <= 15) {
Iterator it = models.iterator ();
boolean failure = false;
while (it.hasNext ()) {
@@ -277,26 +279,17 @@
// ml.asynchModels = (List) models.get(12);
if (modelsSize > 12) { // AsynchronousModelFilter
ml.asynchModelFilters = (List) models.get(12);
+ if (modelsSize > 13) {
+ ml.tableRendererModels = (List) models.get(13);
+ if (modelsSize > 14) {
+ ml.tableRendererModelFilters = (List) models.get(14);
+ }
+ }
}
//}
- } else {
- ml.treeExpansionModelFilters = Collections.emptyList();
}
//treeExpansionModelFilters = (models.size() > 11) ? (List) models.get(11) : (List) Collections.EMPTY_LIST;
} else { // We have the models, need to find out what they implement
- ml.treeModels = new LinkedList ();
- ml.treeModelFilters = new LinkedList ();
- ml.treeExpansionModels = new LinkedList ();
- ml.treeExpansionModelFilters = new LinkedList ();
- ml.nodeModels = new LinkedList ();
- ml.nodeModelFilters = new LinkedList ();
- ml.tableModels = new LinkedList ();
- ml.tableModelFilters = new LinkedList ();
- ml.nodeActionsProviders = new LinkedList ();
- ml.nodeActionsProviderFilters = new LinkedList ();
- //ml.asynchModels = new LinkedList ();
- ml.asynchModelFilters = new LinkedList ();
- ml.columnModels = new LinkedList ();
otherModels = (List extends Model>) models;
}
@@ -381,6 +374,10 @@
new DefaultAsynchronousModel(),//new DelegatingAsynchronousModel (ml.asynchModels),
ml.asynchModelFilters
),
+ createCompoundTableRendererModel (
+ new DelegatingTableRendererModel(ml.tableRendererModels),
+ ml.tableRendererModelFilters
+ ),
propertiesHelpID
);
if (defaultExpansionModel != null) {
@@ -515,6 +512,29 @@
return tm;
}
+ /**
+ * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
+ * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
+ *
+ * @param originalTableModel a original table model
+ * @param tableModelFilters a list of table model filters
+ *
+ * @returns compund table model
+ */
+ private static TableRendererModel createCompoundTableRendererModel (
+ TableRendererModel originalTableModel,
+ List tableModelFilters
+ ) {
+ TableRendererModel tm = originalTableModel;
+ int i, k = tableModelFilters.size ();
+ for (i = 0; i < k; i++)
+ tm = new CompoundTableRendererModel (
+ tm,
+ (TableRendererModelFilter) tableModelFilters.get (i)
+ );
+ return tm;
+ }
+
/**
* Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} for given NodeActionsProvider and
* {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
@@ -1312,6 +1332,116 @@
}
/**
+ * Creates {@link org.netbeans.spi.viewmodel.TableRendererModel} for given TableRendererModel and
+ * {@link org.netbeans.spi.viewmodel.TableRendererModelFilter}.
+ */
+ private final static class CompoundTableRendererModel implements TableRendererModel, ModelListener {
+
+
+ private TableRendererModel model;
+ private TableRendererModelFilter filter;
+
+ private final Collection modelListeners = new HashSet();
+
+
+ /**
+ * Creates {@link org.netbeans.spi.viewmodel.TableRendererModel} for given TableRendererModel and
+ * {@link org.netbeans.spi.viewmodel.TableRendererModelFilter}.
+ */
+ CompoundTableRendererModel (TableRendererModel model, TableRendererModelFilter filter) {
+ this.model = model;
+ this.filter = filter;
+ }
+
+ @Override
+ public boolean canRenderCell(Object node, String columnID) throws UnknownTypeException {
+ return filter.canRenderCell(model, node, columnID);
+ }
+
+ @Override
+ public TableCellRenderer getCellRenderer(Object node, String columnID) throws UnknownTypeException {
+ return filter.getCellRenderer(model, node, columnID);
+ }
+
+ @Override
+ public boolean canEditCell(Object node, String columnID) throws UnknownTypeException {
+ return filter.canEditCell(model, node, columnID);
+ }
+
+ @Override
+ public TableCellEditor getCellEditor(Object node, String columnID) throws UnknownTypeException {
+ return filter.getCellEditor(model, node, columnID);
+ }
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ public void addModelListener (ModelListener l) {
+ synchronized (modelListeners) {
+ if (modelListeners.size() == 0) {
+ filter.addModelListener (this);
+ model.addModelListener (this);
+ }
+ modelListeners.add(l);
+ }
+ }
+
+ /**
+ * Unregisters given listener.
+ *
+ * @param l the listener to remove
+ */
+ public void removeModelListener (ModelListener l) {
+ synchronized (modelListeners) {
+ modelListeners.remove(l);
+ if (modelListeners.size() == 0) {
+ filter.removeModelListener (this);
+ model.removeModelListener (this);
+ }
+ }
+ }
+
+ public void modelChanged(ModelEvent event) {
+ if (event instanceof ModelEvent.NodeChanged && (event.getSource() instanceof NodeModel || event.getSource() instanceof NodeModelFilter)) {
+ // CompoundNodeModel.modelChanged() takes this.
+ return ;
+ }
+ if (event instanceof ModelEvent.TreeChanged &&
+ (event.getSource() instanceof TreeModel || event.getSource() instanceof TreeModelFilter)) {
+ // CompoundTreeModel.modelChanged() takes this.
+ return ;
+ }
+ ModelEvent newEvent = translateEvent(event, this);
+ Collection listeners;
+ synchronized (modelListeners) {
+ listeners = new ArrayList(modelListeners);
+ }
+ for (Iterator it = listeners.iterator(); it.hasNext(); ) {
+ it.next().modelChanged(newEvent);
+ }
+ }
+
+ @Override
+ public String toString () {
+ return super.toString () + "\n" + toString (" ");
+ }
+
+ public String toString (String n) {
+ if (model instanceof CompoundTableRendererModel)
+ return n + filter + "\n" +
+ ((CompoundTableRendererModel) model).toString (n + " ");
+ if (model instanceof DelegatingTableRendererModel)
+ return n + filter + "\n" +
+ ((DelegatingTableRendererModel) model).toString (n + " ");
+ return n + filter + "\n" +
+ n + " " + model;
+ }
+
+ }
+
+ /**
* Creates one {@link org.netbeans.spi.viewmodel.TreeModel}
* from given list of TreeModels. DelegatingTreeModel asks all underlaying
* models for each concrete parameter, and returns first returned value.
@@ -1943,6 +2073,195 @@
sb.append (models [i]);
return new String (sb);
}
+ }
+
+ /**
+ * Creates one {@link org.netbeans.spi.viewmodel.TableRendererModel}
+ * from given list of TableRendererModel. DelegatingTableRendererModel asks all underlaying
+ * models for each concrete parameter, and returns first returned value.
+ */
+ private final static class DelegatingTableRendererModel implements TableRendererModel {
+
+ private TableRendererModel[] models;
+ private HashMap classNameToModel = new HashMap();
+
+
+ /**
+ * Creates new instance of DelegatingTableModel for given list of
+ * TableModels.
+ *
+ * @param models a list of TableModels
+ */
+ DelegatingTableRendererModel (List models) {
+ this (convert (models));
+ }
+
+ private static TableRendererModel[] convert (List l) {
+ TableRendererModel[] models = new TableRendererModel [l.size ()];
+ return l.toArray (models);
+ }
+
+ /**
+ * Creates new instance of DelegatingTableModel for given array of
+ * TableModels.
+ *
+ * @param models a array of TableModels
+ */
+ DelegatingTableRendererModel (TableRendererModel[] models) {
+ this.models = models;
+ }
+
+ @Override
+ public boolean canRenderCell(Object node, String columnID) throws UnknownTypeException {
+ TableRendererModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null)
+ try {
+ return model.canRenderCell (node, columnID);
+ } catch (UnknownTypeException e) {
+ }
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ try {
+ boolean cr = models [i].canRenderCell (node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return cr;
+ } catch (UnknownTypeException e) {
+ }
+ }
+ throw new UnknownTypeException (node);
+ }
+
+ @Override
+ public TableCellRenderer getCellRenderer(Object node, String columnID) throws UnknownTypeException {
+ TableRendererModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null)
+ try {
+ return model.getCellRenderer (node, columnID);
+ } catch (UnknownTypeException e) {
+ }
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ try {
+ TableCellRenderer cr = models [i].getCellRenderer (node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return cr;
+ } catch (UnknownTypeException e) {
+ }
+ }
+ throw new UnknownTypeException (node);
+ }
+
+ @Override
+ public boolean canEditCell(Object node, String columnID) throws UnknownTypeException {
+ TableRendererModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null)
+ try {
+ return model.canEditCell (node, columnID);
+ } catch (UnknownTypeException e) {
+ }
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ try {
+ boolean ce = models [i].canEditCell (node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return ce;
+ } catch (UnknownTypeException e) {
+ }
+ }
+ throw new UnknownTypeException (node);
+ }
+
+ @Override
+ public TableCellEditor getCellEditor(Object node, String columnID) throws UnknownTypeException {
+ TableRendererModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null)
+ try {
+ return model.getCellEditor (node, columnID);
+ } catch (UnknownTypeException e) {
+ }
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ try {
+ TableCellEditor ce = models [i].getCellEditor (node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return ce;
+ } catch (UnknownTypeException e) {
+ }
+ }
+ throw new UnknownTypeException (node);
+ }
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ @Override
+ public void addModelListener (ModelListener l) {
+ int i, k = models.length;
+ for (i = 0; i < k; i++)
+ models [i].addModelListener (l);
+ }
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ void addModelListener (ModelListener l, Set modelsListenersAddedTo) {
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ TableRendererModel m = models [i];
+ if (!modelsListenersAddedTo.add(m)) {
+ continue;
+ }
+ if (m instanceof DelegatingTableRendererModel) {
+ ((DelegatingTableRendererModel) m).addModelListener(l, modelsListenersAddedTo);
+ } else {
+ m.addModelListener (l);
+ }
+ }
+ }
+
+ /**
+ * Unregisters given listener.
+ *
+ * @param l the listener to remove
+ */
+ @Override
+ public void removeModelListener (ModelListener l) {
+ int i, k = models.length;
+ for (i = 0; i < k; i++)
+ models [i].removeModelListener (l);
+ }
+
+ @Override
+ public String toString () {
+ return super.toString () + "\n" + toString (" ");
+ }
+
+ public String toString (String n) {
+ int i, k = models.length - 1;
+ if (k == -1) return "";
+ StringBuffer sb = new StringBuffer ();
+ for (i = 0; i < k; i++) {
+ sb.append (n);
+ sb.append (models [i]);
+ sb.append ('\n');
+ }
+ sb.append (n);
+ sb.append (models [i]);
+ return new String (sb);
+ }
+
}
/**
@@ -3340,7 +3659,13 @@
* @author Jan Jancura
*/
public static final class CompoundModel implements ReorderableTreeModel,
- ExtendedNodeModel, CheckNodeModel, DnDNodeModel, NodeActionsProvider, TableModel, TreeExpansionModel {
+ ExtendedNodeModel,
+ CheckNodeModel,
+ DnDNodeModel,
+ NodeActionsProvider,
+ TableModel,
+ TreeExpansionModel,
+ TableRendererModel {
private ReorderableTreeModel treeModel;
private ExtendedNodeModel nodeModel;
@@ -3349,6 +3674,7 @@
private NodeActionsProvider nodeActionsProvider;
private ColumnModel[] columnModels;
private TableModel tableModel;
+ private TableRendererModel tableRendererModel;
private TreeExpansionModel treeExpansionModel;
private AsynchronousModel asynchModel;
@@ -3380,6 +3706,7 @@
List columnModels,
TableModel tableModel,
AsynchronousModel asynchModel,
+ TableRendererModel tableRendererModel,
String propertiesHelpID
) {
if (treeModel == null) throw new NullPointerException ();
@@ -3398,6 +3725,7 @@
this.dndNodeModel = (DnDNodeModel) nodeModel;
}
this.tableModel = tableModel;
+ this.tableRendererModel = tableRendererModel;
this.nodeActionsProvider = nodeActionsProvider;
this.columnModels = columnModels.toArray (
new ColumnModel [columnModels.size ()]
@@ -3860,6 +4188,44 @@
public Executor asynchronous(CALL asynchCall, Object node) throws UnknownTypeException {
return asynchModel.asynchronous(asynchCall, node);
+ }
+
+ // TableRendererModel
+
+ @Override
+ public boolean canRenderCell(Object node, String columnID) throws UnknownTypeException {
+ if (tableRendererModel != null) {
+ return tableRendererModel.canRenderCell(node, columnID);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public TableCellRenderer getCellRenderer(Object node, String columnID) throws UnknownTypeException {
+ if (tableRendererModel != null) {
+ return tableRendererModel.getCellRenderer(node, columnID);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean canEditCell(Object node, String columnID) throws UnknownTypeException {
+ if (tableRendererModel != null) {
+ return tableRendererModel.canEditCell(node, columnID);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public TableCellEditor getCellEditor(Object node, String columnID) throws UnknownTypeException {
+ if (tableRendererModel != null) {
+ return tableRendererModel.getCellEditor(node, columnID);
+ } else {
+ return null;
+ }
}
}
@@ -3879,6 +4245,8 @@
public List columnModels = Collections.emptyList();
//public List asynchModels = Collections.emptyList();
public List asynchModelFilters = Collections.emptyList();
+ public List tableRendererModels = Collections.emptyList();
+ public List tableRendererModelFilters = Collections.emptyList();
public void addOtherModels(List extends Model> otherModels) {
Iterator it = otherModels.iterator ();
@@ -3929,6 +4297,17 @@
else
tableModelFilters.add(0, (TableModelFilter) model);
}
+ if (model instanceof TableRendererModel && !tableRendererModels.contains((TableRendererModel) model)) {
+ tableRendererModels = new ArrayList(tableRendererModels);
+ tableRendererModels.add((TableRendererModel) model);
+ }
+ if (model instanceof TableRendererModelFilter && !tableRendererModelFilters.contains((TableRendererModelFilter) model)) {
+ tableRendererModelFilters = new ArrayList(tableRendererModelFilters);
+ if (first)
+ tableRendererModelFilters.add((TableRendererModelFilter) model);
+ else
+ tableRendererModelFilters.add(0, (TableRendererModelFilter) model);
+ }
if (model instanceof NodeActionsProvider && !nodeActionsProviders.contains((NodeActionsProvider) model)) {
nodeActionsProviders = new ArrayList(nodeActionsProviders);
nodeActionsProviders.add((NodeActionsProvider) model);
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/spi/viewmodel/TableRendererModel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableRendererModel.java Mon May 31 22:59:21 2010 +0200
@@ -0,0 +1,107 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+package org.netbeans.spi.viewmodel;
+
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+
+/**
+ * Model that provides custom cell renderer and cell editor for table cells.
+ *
+ * @author Martin Entlicher
+ * @since 1.28
+ */
+public interface TableRendererModel extends Model {
+
+ /**
+ * Test whether this renderer can render the given cell.
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return true
if the implementation can render the given cell, false
otherwise
+ * @throws UnknownTypeException If the implementation can not decide whether to render the given cell.
+ */
+ public boolean canRenderCell(Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Get the renderer of the given cell
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return The cell renderer
+ * @throws UnknownTypeException If the implementation can not render the given cell.
+ */
+ public TableCellRenderer getCellRenderer(Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Test whether this renderer can edit the given cell.
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return true
if the implementation can edit the given cell, false
otherwise
+ * @throws UnknownTypeException If the implementation can not decide whether to edit the given cell.
+ */
+ public boolean canEditCell(Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Get the editor of the given cell
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return The cell editor
+ * @throws UnknownTypeException If the implementation can not edit the given cell.
+ */
+ public TableCellEditor getCellEditor(Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ public abstract void addModelListener (ModelListener l);
+
+ /**
+ * Unregisters given listener.
+ *
+ * @param l the listener to remove
+ */
+ public abstract void removeModelListener (ModelListener l);
+}
diff -r 3659afb5fe5b -r f400de1faf47 spi.viewmodel/src/org/netbeans/spi/viewmodel/TableRendererModelFilter.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableRendererModelFilter.java Mon May 31 22:59:21 2010 +0200
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+package org.netbeans.spi.viewmodel;
+
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+
+/**
+ * Model filter that can override custom cell renderer and cell editor for table cells.
+ *
+ * @author Martin Entlicher
+ * @since 1.28
+ */
+public interface TableRendererModelFilter extends Model {
+
+ /**
+ * Test whether this renderer can render the given cell.
+ * @param original The original table cell renderer implementation
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return true
if the implementation can render the given cell, false
otherwise
+ * @throws UnknownTypeException If the implementation can not decide whether to render the given cell.
+ */
+ public boolean canRenderCell(TableRendererModel original, Object node, String columnID)
+ throws UnknownTypeException;
+
+ /**
+ * Get the renderer of the given cell
+ * @param original The original table cell renderer implementation
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return The cell renderer
+ * @throws UnknownTypeException If the implementation can not render the given cell.
+ */
+ public TableCellRenderer getCellRenderer(TableRendererModel original, Object node, String columnID)
+ throws UnknownTypeException;
+
+ /**
+ * Test whether this renderer can edit the given cell.
+ * @param original The original table cell renderer implementation
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return true
if the implementation can edit the given cell, false
otherwise
+ * @throws UnknownTypeException If the implementation can not decide whether to edit the given cell.
+ */
+ public boolean canEditCell(TableRendererModel original, Object node, String columnID)
+ throws UnknownTypeException;
+
+ /**
+ * Get the editor of the given cell
+ * @param original The original table cell renderer implementation
+ * @param node Tree node representing the row
+ * @param columnID The column name
+ * @return The cell editor
+ * @throws UnknownTypeException If the implementation can not edit the given cell.
+ */
+ public TableCellEditor getCellEditor(TableRendererModel original, Object node, String columnID)
+ throws UnknownTypeException;
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ public abstract void addModelListener (ModelListener l);
+
+ /**
+ * Unregisters given listener.
+ *
+ * @param l the listener to remove
+ */
+ public abstract void removeModelListener (ModelListener l);
+}