0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.spi.viewmodel;
0043:
0044: import java.awt.datatransfer.Transferable;
0045: import java.awt.event.ActionEvent;
0046: import java.io.IOException;
0047: import java.lang.StringBuffer;
0048: import java.util.ArrayList;
0049: import java.util.Collection;
0050: import java.util.Collections;
0051: import java.util.HashMap;
0052: import java.util.HashSet;
0053: import java.util.IdentityHashMap;
0054: import java.util.Iterator;
0055: import java.util.LinkedList;
0056: import java.util.List;
0057: import java.util.Set;
0058: import java.util.Vector;
0059: import java.util.WeakHashMap;
0060: import javax.swing.AbstractAction;
0061: import javax.swing.Action;
0062: import javax.swing.JComponent;
0063: import javax.swing.SwingUtilities;
0064:
0065: import org.netbeans.modules.viewmodel.TreeTable;
0066:
0067: import org.netbeans.spi.viewmodel.ColumnModel;
0068: import org.netbeans.spi.viewmodel.NodeActionsProvider;
0069: import org.netbeans.spi.viewmodel.NodeActionsProviderFilter;
0070: import org.netbeans.spi.viewmodel.NodeModel;
0071: import org.netbeans.spi.viewmodel.ExtendedNodeModel;
0072: import org.netbeans.spi.viewmodel.ExtendedNodeModelFilter;
0073: import org.netbeans.spi.viewmodel.NodeModelFilter;
0074: import org.netbeans.spi.viewmodel.TableModel;
0075: import org.netbeans.spi.viewmodel.TableModelFilter;
0076: import org.netbeans.spi.viewmodel.TreeModel;
0077: import org.netbeans.spi.viewmodel.TreeModelFilter;
0078: import org.netbeans.spi.viewmodel.ModelListener;
0079: import org.netbeans.spi.viewmodel.UnknownTypeException;
0080: import org.openide.ErrorManager;
0081:
0082: import org.openide.nodes.Node;
0083: import org.openide.util.Exceptions;
0084: import org.openide.util.WeakSet;
0085: import org.openide.util.datatransfer.PasteType;
0086: import org.openide.windows.TopComponent;
0087:
0088: /**
0089: * Contains various utility methods for various models.
0090: *
0091: * @author Jan Jancura
0092: */
0093: public final class Models {
0094:
0095: /** Cached default implementations of expansion models. */
0096: private static WeakHashMap<Object, TreeExpansionModel> defaultExpansionModels = new WeakHashMap<Object, TreeExpansionModel>();
0097: /**
0098: * Empty model - returns default root node with no children.
0099: */
0100: public static CompoundModel EMPTY_MODEL = createCompoundModel(new ArrayList());
0101:
0102: public static int MULTISELECTION_TYPE_EXACTLY_ONE = 1;
0103: public static int MULTISELECTION_TYPE_ALL = 2;
0104: public static int MULTISELECTION_TYPE_ANY = 3;
0105:
0106: private static boolean verbose = System
0107: .getProperty("netbeans.debugger.models") != null;
0108:
0109: /**
0110: * Creates a new instance of TreeTableView
0111: * for given {@link org.netbeans.spi.viewmodel.Models.CompoundModel}.
0112: *
0113: * @param compoundModel a compound model instance
0114: *
0115: * @return new instance of complete model view
0116: */
0117: public static JComponent createView(CompoundModel compoundModel) {
0118: TreeTable tt = new TreeTable();
0119: tt.setModel(compoundModel);
0120: return tt;
0121: }
0122:
0123: /**
0124: * Set given models to given view instance.
0125: *
0126: * @param view a view instance - must be an instance created by {@link #createView} method.
0127: * @param compoundModel a compound model instance
0128: */
0129: public static void setModelsToView(final JComponent view,
0130: final CompoundModel compoundModel) {
0131: if (!(view instanceof TreeTable)) {
0132: throw new IllegalArgumentException(
0133: "Expecting an instance of "
0134: + TreeTable.class.getName()
0135: + ", which can be obtained from Models.createView().");
0136: }
0137: if (verbose)
0138: System.out.println(compoundModel);
0139: SwingUtilities.invokeLater(new Runnable() {
0140: public void run() {
0141: ((TreeTable) view).setModel(compoundModel);
0142: }
0143: });
0144: }
0145:
0146: /**
0147: * Creates one {@link CompoundModel} from given list of models.
0148: * <p>
0149: * If this list does not include any instance of TreeModel or
0150: * TreeExpansionModel, a default implementation of these models is created
0151: * based on the instance of this list. Thus you get one implementation
0152: * per provided instance of the models list.
0153: *
0154: * @param models a list of models
0155: * @return {@link CompoundModel} encapsulating given list of models
0156: */
0157: public static CompoundModel createCompoundModel(List models) {
0158: return createCompoundModel(models, null);
0159: }
0160:
0161: /**
0162: * Creates one {@link CompoundModel} from given list of models.
0163: * <p>
0164: * If this list does not include any instance of TreeModel or
0165: * TreeExpansionModel, a default implementation of these models is created
0166: * based on the instance of this list. Thus you get one implementation
0167: * per provided instance of the models list.
0168: *
0169: * @param models a list of models
0170: * @param propertiesHelpID The help ID, which is set for the properties
0171: * sheets created from this model.
0172: * @return {@link CompoundModel} encapsulating given list of models
0173: * @since 1.7
0174: */
0175: public static CompoundModel createCompoundModel(List models,
0176: String propertiesHelpID) {
0177: List<TreeModel> treeModels;
0178: List<TreeModelFilter> treeModelFilters;
0179: List<TreeExpansionModel> treeExpansionModels;
0180: List<NodeModel> nodeModels;
0181: List<NodeModelFilter> nodeModelFilters;
0182: List<TableModel> tableModels;
0183: List<TableModelFilter> tableModelFilters;
0184: List<NodeActionsProvider> nodeActionsProviders;
0185: List<NodeActionsProviderFilter> nodeActionsProviderFilters;
0186: List<ColumnModel> columnModels;
0187: List<? extends Model> otherModels;
0188:
0189: // Either the list contains 10 lists of individual models + one list of mixed models; or the models directly
0190: boolean hasLists = false;
0191: if (models.size() == 11) {
0192: Iterator it = models.iterator();
0193: while (it.hasNext()) {
0194: if (!(it.next() instanceof List))
0195: break;
0196: }
0197: if (!it.hasNext()) { // All elements are lists
0198: hasLists = true;
0199: }
0200: }
0201: if (hasLists) { // We have 11 lists of individual models
0202: treeModels = (List<TreeModel>) models.get(0);
0203: treeModelFilters = (List<TreeModelFilter>) models.get(1);
0204: revertOrder(treeModelFilters);
0205: treeExpansionModels = (List<TreeExpansionModel>) models
0206: .get(2);
0207: nodeModels = (List<NodeModel>) models.get(3);
0208: nodeModelFilters = (List<NodeModelFilter>) models.get(4);
0209: revertOrder(nodeModelFilters);
0210: tableModels = (List<TableModel>) models.get(5);
0211: tableModelFilters = (List<TableModelFilter>) models.get(6);
0212: revertOrder(tableModelFilters);
0213: nodeActionsProviders = (List<NodeActionsProvider>) models
0214: .get(7);
0215: nodeActionsProviderFilters = (List<NodeActionsProviderFilter>) models
0216: .get(8);
0217: revertOrder(nodeActionsProviderFilters);
0218: columnModels = (List<ColumnModel>) models.get(9);
0219: otherModels = (List<? extends Model>) models.get(10);
0220: } else { // We have the models, need to find out what they implement
0221: treeModels = new LinkedList<TreeModel>();
0222: treeModelFilters = new LinkedList<TreeModelFilter>();
0223: treeExpansionModels = new LinkedList<TreeExpansionModel>();
0224: nodeModels = new LinkedList<NodeModel>();
0225: nodeModelFilters = new LinkedList<NodeModelFilter>();
0226: tableModels = new LinkedList<TableModel>();
0227: tableModelFilters = new LinkedList<TableModelFilter>();
0228: nodeActionsProviders = new LinkedList<NodeActionsProvider>();
0229: nodeActionsProviderFilters = new LinkedList<NodeActionsProviderFilter>();
0230: columnModels = new LinkedList<ColumnModel>();
0231: otherModels = (List<? extends Model>) models;
0232: }
0233:
0234: Iterator it = otherModels.iterator();
0235: while (it.hasNext()) {
0236: Object model = it.next();
0237: boolean first = model.getClass().getName()
0238: .endsWith("First");
0239: if (model instanceof TreeModel)
0240: treeModels.add((TreeModel) model);
0241: if (model instanceof TreeModelFilter)
0242: if (first)
0243: treeModelFilters.add((TreeModelFilter) model);
0244: else
0245: treeModelFilters.add(0, (TreeModelFilter) model);
0246: if (model instanceof TreeExpansionModel)
0247: treeExpansionModels.add((TreeExpansionModel) model);
0248: if (model instanceof NodeModel)
0249: nodeModels.add((NodeModel) model);
0250: if (model instanceof NodeModelFilter)
0251: if (first)
0252: nodeModelFilters.add((NodeModelFilter) model);
0253: else
0254: nodeModelFilters.add(0, (NodeModelFilter) model);
0255: if (model instanceof TableModel)
0256: tableModels.add((TableModel) model);
0257: if (model instanceof TableModelFilter)
0258: if (first)
0259: tableModelFilters.add((TableModelFilter) model);
0260: else
0261: tableModelFilters.add(0, (TableModelFilter) model);
0262: if (model instanceof NodeActionsProvider)
0263: nodeActionsProviders.add((NodeActionsProvider) model);
0264: if (model instanceof NodeActionsProviderFilter)
0265: if (first)
0266: nodeActionsProviderFilters
0267: .add((NodeActionsProviderFilter) model);
0268: else
0269: nodeActionsProviderFilters.add(0,
0270: (NodeActionsProviderFilter) model);
0271: if (model instanceof ColumnModel)
0272: columnModels.add((ColumnModel) model);
0273: }
0274: /*
0275: System.out.println("Tree Models = "+treeModels);
0276: System.out.println("Tree Model Filters = "+treeModelFilters);
0277: System.out.println("Tree Expans Models = "+treeExpansionModels);
0278: System.out.println("Node Models = "+nodeModels);
0279: System.out.println("Node Model Filters = "+nodeModelFilters);
0280: System.out.println("Table Models = "+tableModels);
0281: System.out.println("Table Model Filters = "+tableModelFilters);
0282: System.out.println("Node Action Providers = "+nodeActionsProviders);
0283: System.out.println("Node Action Provider Filters = "+nodeActionsProviderFilters);
0284: System.out.println("Column Models = "+columnModels);
0285: */
0286: if (treeModels.isEmpty()) {
0287: TreeModel etm = new EmptyTreeModel();
0288: treeModels = Collections.singletonList(etm);
0289: }
0290: if (treeExpansionModels.isEmpty()) {
0291: TreeExpansionModel tem = defaultExpansionModels.get(models);
0292: if (tem == null) {
0293: tem = new DefaultTreeExpansionModel();
0294: defaultExpansionModels.put(models, tem);
0295: }
0296: treeExpansionModels = Collections.singletonList(tem);
0297: }
0298:
0299: return new CompoundModel(createCompoundTreeModel(
0300: new DelegatingTreeModel(treeModels), treeModelFilters),
0301: new DelegatingTreeExpansionModel(treeExpansionModels),
0302: createCompoundNodeModel(new DelegatingNodeModel(
0303: nodeModels), nodeModelFilters),
0304: createCompoundNodeActionsProvider(
0305: new DelegatingNodeActionsProvider(
0306: nodeActionsProviders),
0307: nodeActionsProviderFilters), columnModels,
0308: createCompoundTableModel(new DelegatingTableModel(
0309: tableModels), tableModelFilters),
0310: propertiesHelpID);
0311: }
0312:
0313: private static <T> void revertOrder(List<T> filters) {
0314: int n = filters.size();
0315: for (int i = 0; i < n;) {
0316: T filter = filters.remove(i);
0317: boolean first = filter.getClass().getName().endsWith(
0318: "First");
0319: if (first) { // The "First" should be the last one in this list
0320: filters.add(filter);
0321: n--;
0322: } else {
0323: filters.add(0, filter);
0324: i++;
0325: }
0326: }
0327: }
0328:
0329: /**
0330: * Returns {@link javax.swing.Action} for given parameters.
0331: *
0332: * @param displayName a display name for action
0333: * @param performer a performer for action
0334: * @param multiselectionType The type of the multiselection - one of the
0335: * MULTISELECTION_TYPE_* constants.
0336: *
0337: * @return a new instance of {@link javax.swing.Action} for given parameters
0338: */
0339: public static Action createAction(String displayName,
0340: ActionPerformer performer, int multiselectionType) {
0341: return new ActionSupport(displayName, performer,
0342: multiselectionType);
0343: }
0344:
0345: /**
0346: * Returns implementation of tree view features for given view.
0347: *
0348: * @param view a view created by this Models class
0349: * @throws UnsupportedOperationException in the case that given
0350: * view is not tree view
0351: * @return implementation of tree view features
0352: */
0353: public static TreeFeatures treeFeatures(JComponent view)
0354: throws UnsupportedOperationException {
0355: return new TreeFeatures(view);
0356: }
0357:
0358: // private methods .........................................................
0359:
0360: /**
0361: * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0362: * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0363: *
0364: * @param originalTreeModel a original tree model
0365: * @param treeModelFilter a list of tree model filters
0366: *
0367: * @returns compund tree model
0368: */
0369: private static TreeModel createCompoundTreeModel(
0370: TreeModel originalTreeModel, List treeModelFilters) {
0371: TreeModel tm = originalTreeModel;
0372: int i, k = treeModelFilters.size();
0373: for (i = 0; i < k; i++)
0374: tm = new CompoundTreeModel(tm,
0375: (TreeModelFilter) treeModelFilters.get(i));
0376: return tm;
0377: }
0378:
0379: /**
0380: * Creates {@link org.netbeans.spi.viewmodel.NodeModel} for given NodeModel and
0381: * {@link org.netbeans.spi.viewmodel.NodeModelFilter}.
0382: *
0383: * @param originalNodeModel a original node model
0384: * @param nodeModelFilters a list of node model filters
0385: *
0386: * @returns compund tree model
0387: */
0388: private static ExtendedNodeModel createCompoundNodeModel(
0389: ExtendedNodeModel originalNodeModel,
0390: List treeNodeModelFilters) {
0391: ExtendedNodeModel nm = originalNodeModel;
0392: int i, k = treeNodeModelFilters.size();
0393: for (i = 0; i < k; i++)
0394: nm = new CompoundNodeModel(nm,
0395: (NodeModelFilter) treeNodeModelFilters.get(i));
0396: return nm;
0397: }
0398:
0399: /**
0400: * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0401: * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0402: *
0403: * @param originalTableModel a original table model
0404: * @param tableModelFilters a list of table model filters
0405: *
0406: * @returns compund table model
0407: */
0408: private static TableModel createCompoundTableModel(
0409: TableModel originalTableModel, List tableModelFilters) {
0410: TableModel tm = originalTableModel;
0411: int i, k = tableModelFilters.size();
0412: for (i = 0; i < k; i++)
0413: tm = new CompoundTableModel(tm,
0414: (TableModelFilter) tableModelFilters.get(i));
0415: return tm;
0416: }
0417:
0418: /**
0419: * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} for given NodeActionsProvider and
0420: * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
0421: *
0422: * @param originalNodeActionsProvider a original node actions provider
0423: * @param nodeActionsProviderFilters a list of node actions provider filters
0424: *
0425: * @returns compund node actions provider
0426: */
0427: private static NodeActionsProvider createCompoundNodeActionsProvider(
0428: NodeActionsProvider originalNodeActionsProvider,
0429: List nodeActionsProviderFilters) {
0430: NodeActionsProvider nap = originalNodeActionsProvider;
0431: int i, k = nodeActionsProviderFilters.size();
0432: for (i = 0; i < k; i++)
0433: nap = new CompoundNodeActionsProvider(
0434: nap,
0435: (NodeActionsProviderFilter) nodeActionsProviderFilters
0436: .get(i));
0437: return nap;
0438: }
0439:
0440: // innerclasses ............................................................
0441:
0442: /**
0443: * @author Jan Jancura
0444: */
0445: private static class ActionSupport extends AbstractAction {
0446:
0447: private ActionPerformer performer;
0448: private int multiselectionType;
0449: private String displayName;
0450:
0451: ActionSupport(String displayName, ActionPerformer performer,
0452: int multiselectionType) {
0453: super (displayName);
0454: this .performer = performer;
0455: this .displayName = displayName;
0456: this .multiselectionType = multiselectionType;
0457: }
0458:
0459: public boolean isEnabled() {
0460: if (multiselectionType == MULTISELECTION_TYPE_ANY)
0461: return true;
0462: Node[] ns = TopComponent.getRegistry().getActivatedNodes();
0463: if (multiselectionType == MULTISELECTION_TYPE_EXACTLY_ONE) {
0464: if (ns.length != 1)
0465: return false;
0466: return performer.isEnabled(ns[0].getLookup().lookup(
0467: Object.class));
0468: }
0469: int i, k = ns.length;
0470: for (i = 0; i < k; i++)
0471: if (!performer.isEnabled(ns[i].getLookup().lookup(
0472: Object.class)))
0473: return false;
0474: return true;
0475: }
0476:
0477: public void actionPerformed(ActionEvent e) {
0478: Node[] ns = TopComponent.getRegistry().getActivatedNodes();
0479: int i, k = ns.length;
0480: IdentityHashMap<Action, ArrayList<Object>> h = new IdentityHashMap<Action, ArrayList<Object>>();
0481: for (i = 0; i < k; i++) {
0482: Object node = ns[i].getLookup().lookup(Object.class);
0483: Action[] as = ns[i].getActions(false);
0484: int j, jj = as.length;
0485: for (j = 0; j < jj; j++)
0486: if (equals(as[j])) {
0487: ArrayList<Object> l = h.get(as[j]);
0488: if (l == null) {
0489: l = new ArrayList<Object>();
0490: h.put(as[j], l);
0491: }
0492: l.add(node);
0493: }
0494: }
0495: Iterator<Action> it = h.keySet().iterator();
0496: while (it.hasNext()) {
0497: ActionSupport a = (ActionSupport) it.next();
0498: a.performer.perform(((ArrayList) h.get(a)).toArray());
0499: }
0500: }
0501:
0502: public int hashCode() {
0503: return displayName.hashCode();
0504: }
0505:
0506: public boolean equals(Object o) {
0507: return (o instanceof ActionSupport)
0508: && displayName
0509: .equals(((ActionSupport) o).displayName);
0510: }
0511: }
0512:
0513: /**
0514: * Support interface for
0515: * {@link #createAction(String,Models.ActionPerformer,int)} method.
0516: */
0517: public static interface ActionPerformer {
0518:
0519: /**
0520: * Returns enabled property state for given node.
0521: *
0522: * @param node the node the action shouuld be applied to
0523: * @return enabled property state for given node
0524: *
0525: * @see #createAction(String,Models.ActionPerformer,int)
0526: */
0527: public boolean isEnabled(Object node);
0528:
0529: /**
0530: * Called when action <code>action</code> is performed for
0531: * nodes.
0532: *
0533: * @param nodes nodes the action shouuld be applied to
0534: *
0535: * @see #createAction(String,Models.ActionPerformer,int)
0536: */
0537: public void perform(Object[] nodes);
0538: }
0539:
0540: /**
0541: * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0542: * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0543: *
0544: * @author Jan Jancura
0545: */
0546: final static class CompoundTreeModel implements TreeModel,
0547: ModelListener {
0548:
0549: private TreeModel model;
0550: private TreeModelFilter filter;
0551:
0552: private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0553:
0554: /**
0555: * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0556: * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0557: */
0558: CompoundTreeModel(TreeModel model, TreeModelFilter filter) {
0559: this .model = model;
0560: this .filter = filter;
0561: }
0562:
0563: /**
0564: * Returns the root node of the tree or null, if the tree is empty.
0565: *
0566: * @return the root node of the tree or null
0567: */
0568: public Object getRoot() {
0569: return filter.getRoot(model);
0570: }
0571:
0572: /**
0573: * Returns children for given parent on given indexes.
0574: *
0575: * @param parent a parent of returned nodes
0576: * @throws NoInformationException if the set of children can not be
0577: * resolved
0578: * @throws UnknownTypeException if this TreeModel implementation is not
0579: * able to resolve dchildren for given node type
0580: *
0581: * @return children for given parent on given indexes
0582: */
0583: public Object[] getChildren(Object parent, int from, int to)
0584: throws UnknownTypeException {
0585:
0586: return filter.getChildren(model, parent, from, to);
0587: }
0588:
0589: /**
0590: * Returns number of children for given node.
0591: *
0592: * @param node the parent node
0593: * @throws NoInformationException if the set of children can not be
0594: * resolved
0595: * @throws UnknownTypeException if this TreeModel implementation is not
0596: * able to resolve children for given node type
0597: *
0598: * @return true if node is leaf
0599: */
0600: public int getChildrenCount(Object node)
0601: throws UnknownTypeException {
0602: return filter.getChildrenCount(model, node);
0603: }
0604:
0605: /**
0606: * Returns true if node is leaf.
0607: *
0608: * @throws UnknownTypeException if this TreeModel implementation is not
0609: * able to resolve dchildren for given node type
0610: * @return true if node is leaf
0611: */
0612: public boolean isLeaf(Object node) throws UnknownTypeException {
0613: return filter.isLeaf(model, node);
0614: }
0615:
0616: /**
0617: * Registers given listener.
0618: *
0619: * @param l the listener to add
0620: */
0621: public void addModelListener(ModelListener l) {
0622: synchronized (modelListeners) {
0623: if (modelListeners.size() == 0) {
0624: filter.addModelListener(this );
0625: model.addModelListener(this );
0626: }
0627: modelListeners.add(l);
0628: }
0629: }
0630:
0631: /**
0632: * Unregisters given listener.
0633: *
0634: * @param l the listener to remove
0635: */
0636: public void removeModelListener(ModelListener l) {
0637: synchronized (modelListeners) {
0638: modelListeners.remove(l);
0639: if (modelListeners.size() == 0) {
0640: filter.removeModelListener(this );
0641: model.removeModelListener(this );
0642: }
0643: }
0644: }
0645:
0646: public void modelChanged(ModelEvent event) {
0647: ModelEvent newEvent = translateEvent(event, this );
0648: Collection<ModelListener> listeners;
0649: synchronized (modelListeners) {
0650: listeners = new ArrayList<ModelListener>(modelListeners);
0651: }
0652: for (Iterator<ModelListener> it = listeners.iterator(); it
0653: .hasNext();) {
0654: it.next().modelChanged(newEvent);
0655: }
0656: }
0657:
0658: public String toString() {
0659: return super .toString() + "\n" + toString(" ");
0660: }
0661:
0662: public String toString(String n) {
0663: if (model instanceof CompoundTreeModel)
0664: return n
0665: + filter
0666: + "\n"
0667: + ((CompoundTreeModel) model)
0668: .toString(n + " ");
0669: return n + filter + "\n" + n + " " + model;
0670: }
0671:
0672: }
0673:
0674: private static ModelEvent translateEvent(ModelEvent event,
0675: Object newSource) {
0676: ModelEvent newEvent;
0677: if (event instanceof ModelEvent.NodeChanged) {
0678: newEvent = new ModelEvent.NodeChanged(newSource,
0679: ((ModelEvent.NodeChanged) event).getNode(),
0680: ((ModelEvent.NodeChanged) event).getChange());
0681: } else if (event instanceof ModelEvent.TableValueChanged) {
0682: newEvent = new ModelEvent.TableValueChanged(newSource,
0683: ((ModelEvent.TableValueChanged) event).getNode(),
0684: ((ModelEvent.TableValueChanged) event)
0685: .getColumnID());
0686: } else if (event instanceof ModelEvent.TreeChanged) {
0687: newEvent = new ModelEvent.TreeChanged(newSource);
0688: } else {
0689: newEvent = event;
0690: }
0691: return newEvent;
0692: }
0693:
0694: /**
0695: * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0696: * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0697: *
0698: * @author Jan Jancura
0699: */
0700: final static class CompoundNodeModel implements ExtendedNodeModel,
0701: ModelListener {
0702:
0703: private ExtendedNodeModel model;
0704: private NodeModelFilter filter;
0705:
0706: private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0707:
0708: /**
0709: * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0710: * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0711: */
0712: CompoundNodeModel(ExtendedNodeModel model,
0713: NodeModelFilter filter) {
0714: this .model = model;
0715: this .filter = filter;
0716: }
0717:
0718: /**
0719: * Returns display name for given node.
0720: *
0721: * @throws UnknownTypeException if this NodeModel implementation is not
0722: * able to resolve display name for given node type
0723: * @return display name for given node
0724: */
0725: public String getDisplayName(Object node)
0726: throws UnknownTypeException {
0727: return filter.getDisplayName(model, node);
0728: }
0729:
0730: /**
0731: * Returns icon for given node.
0732: *
0733: * @throws UnknownTypeException if this NodeModel implementation is not
0734: * able to resolve icon for given node type
0735: * @return icon for given node
0736: */
0737: public String getIconBase(Object node)
0738: throws UnknownTypeException {
0739: return filter.getIconBase(model, node);
0740: }
0741:
0742: /**
0743: * Returns tooltip for given node.
0744: *
0745: * @throws UnknownTypeException if this NodeModel implementation is not
0746: * able to resolve tooltip for given node type
0747: * @return tooltip for given node
0748: */
0749: public String getShortDescription(Object node)
0750: throws UnknownTypeException {
0751: return filter.getShortDescription(model, node);
0752: }
0753:
0754: /**
0755: * Registers given listener.
0756: *
0757: * @param l the listener to add
0758: */
0759: public void addModelListener(ModelListener l) {
0760: synchronized (modelListeners) {
0761: if (modelListeners.size() == 0) {
0762: filter.addModelListener(this );
0763: model.addModelListener(this );
0764: }
0765: modelListeners.add(l);
0766: }
0767: }
0768:
0769: /**
0770: * Unregisters given listener.
0771: *
0772: * @param l the listener to remove
0773: */
0774: public void removeModelListener(ModelListener l) {
0775: synchronized (modelListeners) {
0776: modelListeners.remove(l);
0777: if (modelListeners.size() == 0) {
0778: filter.removeModelListener(this );
0779: model.removeModelListener(this );
0780: }
0781: }
0782: }
0783:
0784: public void modelChanged(ModelEvent event) {
0785: ModelEvent newEvent = translateEvent(event, this );
0786: Collection<ModelListener> listeners;
0787: synchronized (modelListeners) {
0788: listeners = new ArrayList<ModelListener>(modelListeners);
0789: }
0790: for (Iterator<ModelListener> it = listeners.iterator(); it
0791: .hasNext();) {
0792: it.next().modelChanged(newEvent);
0793: }
0794: }
0795:
0796: public String toString() {
0797: return super .toString() + "\n" + toString(" ");
0798: }
0799:
0800: public String toString(String n) {
0801: if (model instanceof CompoundNodeModel)
0802: return n
0803: + filter
0804: + "\n"
0805: + ((CompoundNodeModel) model)
0806: .toString(n + " ");
0807: if (model instanceof DelegatingNodeModel)
0808: return n
0809: + filter
0810: + "\n"
0811: + ((DelegatingNodeModel) model).toString(n
0812: + " ");
0813: return n + filter + "\n" + n + " " + model;
0814: }
0815:
0816: public boolean canRename(Object node)
0817: throws UnknownTypeException {
0818: if (filter instanceof ExtendedNodeModelFilter) {
0819: return ((ExtendedNodeModelFilter) filter).canRename(
0820: model, node);
0821: } else {
0822: return model.canRename(node);
0823: }
0824: }
0825:
0826: public boolean canCopy(Object node) throws UnknownTypeException {
0827: if (filter instanceof ExtendedNodeModelFilter) {
0828: return ((ExtendedNodeModelFilter) filter).canCopy(
0829: model, node);
0830: } else {
0831: return model.canCopy(node);
0832: }
0833: }
0834:
0835: public boolean canCut(Object node) throws UnknownTypeException {
0836: if (filter instanceof ExtendedNodeModelFilter) {
0837: return ((ExtendedNodeModelFilter) filter).canCut(model,
0838: node);
0839: } else {
0840: return model.canCut(node);
0841: }
0842: }
0843:
0844: public Transferable clipboardCopy(Object node)
0845: throws IOException, UnknownTypeException {
0846: if (filter instanceof ExtendedNodeModelFilter) {
0847: return ((ExtendedNodeModelFilter) filter)
0848: .clipboardCopy(model, node);
0849: } else {
0850: return model.clipboardCopy(node);
0851: }
0852: }
0853:
0854: public Transferable clipboardCut(Object node)
0855: throws IOException, UnknownTypeException {
0856: if (filter instanceof ExtendedNodeModelFilter) {
0857: return ((ExtendedNodeModelFilter) filter).clipboardCut(
0858: model, node);
0859: } else {
0860: return model.clipboardCut(node);
0861: }
0862: }
0863:
0864: /*public Transferable drag(Object node) throws IOException,
0865: UnknownTypeException {
0866: if (filter instanceof ExtendedNodeModelFilter) {
0867: return ((ExtendedNodeModelFilter) filter).drag(model, node);
0868: } else {
0869: return model.drag(node);
0870: }
0871: }*/
0872:
0873: public PasteType[] getPasteTypes(Object node, Transferable t)
0874: throws UnknownTypeException {
0875: if (filter instanceof ExtendedNodeModelFilter) {
0876: return ((ExtendedNodeModelFilter) filter)
0877: .getPasteTypes(model, node, t);
0878: } else {
0879: return model.getPasteTypes(node, t);
0880: }
0881: }
0882:
0883: /*public PasteType getDropType(Object node, Transferable t, int action,
0884: int index) throws UnknownTypeException {
0885: if (filter instanceof ExtendedNodeModelFilter) {
0886: return ((ExtendedNodeModelFilter) filter).getDropType(model, node, t, action, index);
0887: } else {
0888: return model.getDropType(node, t, action, index);
0889: }
0890: }*/
0891:
0892: public void setName(Object node, String name)
0893: throws UnknownTypeException {
0894: if (filter instanceof ExtendedNodeModelFilter) {
0895: ((ExtendedNodeModelFilter) filter).setName(model, node,
0896: name);
0897: } else {
0898: model.setName(node, name);
0899: }
0900: }
0901:
0902: public String getIconBaseWithExtension(Object node)
0903: throws UnknownTypeException {
0904: if (filter instanceof ExtendedNodeModelFilter) {
0905: return ((ExtendedNodeModelFilter) filter)
0906: .getIconBaseWithExtension(model, node);
0907: } else {
0908: String base;
0909: try {
0910: base = filter.getIconBase(model, node);
0911: if (base != null) {
0912: base += ".gif";
0913: }
0914: } catch (Exception utex) {
0915: // The filter can not process the icon base filtering
0916: // Perhaps it needs to be upgraded to ExtendedNodeModelFilter
0917: ErrorManager
0918: .getDefault()
0919: .notify(
0920: ErrorManager.INFORMATIONAL,
0921: ErrorManager
0922: .getDefault()
0923: .annotate(
0924: utex,
0925: "The filter "
0926: + filter
0927: + " does not perform icon base filtering for "
0928: + node
0929: + ".\n"
0930: + "If this is a problem, it should be upgraded to "
0931: + "ExtendedNodeModelFilter and getIconBaseWithExtension() implemented."));
0932: base = model.getIconBaseWithExtension(node);
0933: }
0934: return base;
0935: }
0936: }
0937: }
0938:
0939: /**
0940: * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0941: * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0942: *
0943: * @author Jan Jancura
0944: */
0945: final static class CompoundTableModel implements TableModel,
0946: ModelListener {
0947:
0948: private TableModel model;
0949: private TableModelFilter filter;
0950:
0951: private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0952:
0953: /**
0954: * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0955: * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0956: */
0957: CompoundTableModel(TableModel model, TableModelFilter filter) {
0958: this .model = model;
0959: this .filter = filter;
0960: }
0961:
0962: /**
0963: * Returns value to be displayed in column <code>columnID</code>
0964: * and row <code>node</code>. Column ID is defined in by
0965: * {@link ColumnModel#getID}, and rows are defined by values returned from
0966: * {@TreeModel#getChildren}.
0967: *
0968: * @param node a object returned from {@TreeModel#getChildren} for this row
0969: * @param columnID a id of column defined by {@link ColumnModel#getID}
0970: * @throws UnknownTypeException if there is no TableModel defined for given
0971: * parameter type
0972: *
0973: * @return value of variable representing given position in tree table.
0974: */
0975: public Object getValueAt(Object node, String columnID)
0976: throws UnknownTypeException {
0977: return filter.getValueAt(model, node, columnID);
0978: }
0979:
0980: /**
0981: * Returns true if value displayed in column <code>columnID</code>
0982: * and row <code>node</code> is read only. Column ID is defined in by
0983: * {@link ColumnModel#getID}, and rows are defined by values returned from
0984: * {@TreeModel#getChildren}.
0985: *
0986: * @param node a object returned from {@TreeModel#getChildren} for this row
0987: * @param columnID a id of column defined by {@link ColumnModel#getID}
0988: * @throws UnknownTypeException if there is no TableModel defined for given
0989: * parameter type
0990: *
0991: * @return true if variable on given position is read only
0992: */
0993: public boolean isReadOnly(Object node, String columnID)
0994: throws UnknownTypeException {
0995: return filter.isReadOnly(model, node, columnID);
0996: }
0997:
0998: /**
0999: * Changes a value displayed in column <code>columnID</code>
1000: * and row <code>node</code>. Column ID is defined in by
1001: * {@link ColumnModel#getID}, and rows are defined by values returned from
1002: * {@TreeModel#getChildren}.
1003: *
1004: * @param node a object returned from {@TreeModel#getChildren} for this row
1005: * @param columnID a id of column defined by {@link ColumnModel#getID}
1006: * @param value a new value of variable on given position
1007: * @throws UnknownTypeException if there is no TableModel defined for given
1008: * parameter type
1009: */
1010: public void setValueAt(Object node, String columnID,
1011: Object value) throws UnknownTypeException {
1012: filter.setValueAt(model, node, columnID, value);
1013: }
1014:
1015: /**
1016: * Registers given listener.
1017: *
1018: * @param l the listener to add
1019: */
1020: public void addModelListener(ModelListener l) {
1021: synchronized (modelListeners) {
1022: if (modelListeners.size() == 0) {
1023: filter.addModelListener(this );
1024: model.addModelListener(this );
1025: }
1026: modelListeners.add(l);
1027: }
1028: }
1029:
1030: /**
1031: * Unregisters given listener.
1032: *
1033: * @param l the listener to remove
1034: */
1035: public void removeModelListener(ModelListener l) {
1036: synchronized (modelListeners) {
1037: modelListeners.remove(l);
1038: if (modelListeners.size() == 0) {
1039: filter.removeModelListener(this );
1040: model.removeModelListener(this );
1041: }
1042: }
1043: }
1044:
1045: public void modelChanged(ModelEvent event) {
1046: ModelEvent newEvent = translateEvent(event, this );
1047: Collection<ModelListener> listeners;
1048: synchronized (modelListeners) {
1049: listeners = new ArrayList<ModelListener>(modelListeners);
1050: }
1051: for (Iterator<ModelListener> it = listeners.iterator(); it
1052: .hasNext();) {
1053: it.next().modelChanged(newEvent);
1054: }
1055: }
1056:
1057: public String toString() {
1058: return super .toString() + "\n" + toString(" ");
1059: }
1060:
1061: public String toString(String n) {
1062: if (model instanceof CompoundTableModel)
1063: return n
1064: + filter
1065: + "\n"
1066: + ((CompoundTableModel) model).toString(n
1067: + " ");
1068: if (model instanceof DelegatingTableModel)
1069: return n
1070: + filter
1071: + "\n"
1072: + ((DelegatingTableModel) model).toString(n
1073: + " ");
1074: return n + filter + "\n" + n + " " + model;
1075: }
1076: }
1077:
1078: /**
1079: * Creates one {@link org.netbeans.spi.viewmodel.TreeModel}
1080: * from given list of TreeModels. DelegatingTreeModel asks all underlaying
1081: * models for each concrete parameter, and returns first returned value.
1082: *
1083: * @author Jan Jancura
1084: */
1085: final static class DelegatingTreeModel implements TreeModel {
1086:
1087: private TreeModel[] models;
1088: private HashMap<String, TreeModel> classNameToModel = new HashMap<String, TreeModel>();
1089:
1090: /**
1091: * Creates new instance of DelegatingTreeModel for given list of
1092: * TableModels.
1093: *
1094: * @param models a list of TableModels
1095: */
1096: DelegatingTreeModel(List<TreeModel> models) {
1097: this (convert(models));
1098: }
1099:
1100: private static TreeModel[] convert(List<TreeModel> l) {
1101: TreeModel[] models = new TreeModel[l.size()];
1102: return l.toArray(models);
1103: }
1104:
1105: /**
1106: * Creates new instance of DelegatingTreeModel for given array of
1107: * TableModels.
1108: *
1109: * @param models a array of TreeModel
1110: */
1111: DelegatingTreeModel(TreeModel[] models) {
1112: this .models = models;
1113: }
1114:
1115: /**
1116: * Returns the root node of the tree or null, if the tree is empty.
1117: *
1118: * @return the root node of the tree or null
1119: */
1120: public Object getRoot() {
1121: return models[0].getRoot();
1122: }
1123:
1124: /**
1125: * Returns children for given parent on given indexes.
1126: *
1127: * @param parent a parent of returned nodes
1128: * @param from a start index
1129: * @param to a end index
1130: *
1131: * @throws UnknownTypeException if this TreeModel implementation is not
1132: * able to resolve children for given node type
1133: *
1134: * @return children for given parent on given indexes
1135: */
1136: public Object[] getChildren(Object node, int from, int to)
1137: throws UnknownTypeException {
1138: TreeModel model = classNameToModel.get(node.getClass()
1139: .getName());
1140: if (model != null)
1141: try {
1142: return model.getChildren(node, from, to);
1143: } catch (UnknownTypeException e) {
1144: }
1145: int i, k = models.length;
1146: for (i = 0; i < k; i++) {
1147: try {
1148: Object[] v = models[i].getChildren(node, from, to);
1149: classNameToModel.put(node.getClass().getName(),
1150: models[i]);
1151: return v;
1152: } catch (UnknownTypeException e) {
1153: }
1154: }
1155: throw new UnknownTypeException(node);
1156: }
1157:
1158: /**
1159: * Returns number of children for given node.
1160: *
1161: * @param node the parent node
1162: * @throws UnknownTypeException if this TreeModel implementation is not
1163: * able to resolve children for given node type
1164: *
1165: * @return true if node is leaf
1166: * @since 1.1
1167: */
1168: public int getChildrenCount(Object node)
1169: throws UnknownTypeException {
1170: TreeModel model = (TreeModel) classNameToModel.get(node
1171: .getClass().getName());
1172: if (model != null)
1173: try {
1174: return model.getChildrenCount(node);
1175: } catch (UnknownTypeException e) {
1176: }
1177: int i, k = models.length;
1178: for (i = 0; i < k; i++) {
1179: try {
1180: int result = models[i].getChildrenCount(node);
1181: classNameToModel.put(node.getClass().getName(),
1182: models[i]);
1183: return result;
1184: } catch (UnknownTypeException e) {
1185: }
1186: }
1187: throw new UnknownTypeException(node);
1188: }
1189:
1190: /**
1191: * Returns true if node is leaf.
1192: *
1193: * @throws UnknownTypeException if this TreeModel implementation is not
1194: * able to resolve dchildren for given node type
1195: * @return true if node is leaf
1196: */
1197: public boolean isLeaf(Object node) throws UnknownTypeException {
1198: TreeModel model = classNameToModel.get(node.getClass()
1199: .getName());
1200: if (model != null)
1201: try {
1202: return model.isLeaf(node);
1203: } catch (UnknownTypeException e) {
1204: }
1205: int i, k = models.length;
1206: for (i = 0; i < k; i++) {
1207: try {
1208: boolean result = models[i].isLeaf(node);
1209: classNameToModel.put(node.getClass().getName(),
1210: models[i]);
1211: return result;
1212: } catch (UnknownTypeException e) {
1213: }
1214: }
1215: throw new UnknownTypeException(node);
1216: }
1217:
1218: /**
1219: * Registers given listener.
1220: *
1221: * @param l the listener to add
1222: */
1223: public void addModelListener(ModelListener l) {
1224: int i, k = models.length;
1225: for (i = 0; i < k; i++)
1226: models[i].addModelListener(l);
1227: }
1228:
1229: /**
1230: * Unregisters given listener.
1231: *
1232: * @param l the listener to remove
1233: */
1234: public void removeModelListener(ModelListener l) {
1235: int i, k = models.length;
1236: for (i = 0; i < k; i++)
1237: models[i].removeModelListener(l);
1238: }
1239:
1240: public String toString() {
1241: return super .toString() + "\n" + toString(" ");
1242: }
1243:
1244: public String toString(String n) {
1245: int i, k = models.length - 1;
1246: if (k == -1)
1247: return "";
1248: StringBuffer sb = new StringBuffer();
1249: for (i = 0; i < k; i++) {
1250: sb.append(n);
1251: sb.append(models[i]);
1252: sb.append('\n');
1253: }
1254: sb.append(n);
1255: sb.append(models[i]);
1256: return new String(sb);
1257: }
1258: }
1259:
1260: /**
1261: * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
1262: * for given NodeActionsProvider and
1263: * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1264: *
1265: * @author Jan Jancura
1266: */
1267: final static class CompoundNodeActionsProvider implements
1268: NodeActionsProvider {
1269:
1270: private NodeActionsProvider model;
1271: private NodeActionsProviderFilter filter;
1272:
1273: /**
1274: * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
1275: * for given NodeActionsProvider and
1276: * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1277: */
1278: CompoundNodeActionsProvider(NodeActionsProvider model,
1279: NodeActionsProviderFilter filter) {
1280: this .model = model;
1281: this .filter = filter;
1282: }
1283:
1284: /**
1285: * Performs default action for given node.
1286: *
1287: * @throws UnknownTypeException if this NodeActionsProvider
1288: * implementation is not able to resolve actions
1289: * for given node type
1290: * @return display name for given node
1291: */
1292: public void performDefaultAction(Object node)
1293: throws UnknownTypeException {
1294: filter.performDefaultAction(model, node);
1295: }
1296:
1297: /**
1298: * Returns set of actions for given node.
1299: *
1300: * @throws UnknownTypeException if this NodeActionsProvider implementation
1301: * is not able to resolve actions for given node type
1302: * @return display name for given node
1303: */
1304: public Action[] getActions(Object node)
1305: throws UnknownTypeException {
1306: return filter.getActions(model, node);
1307: }
1308:
1309: public String toString() {
1310: return super .toString() + "\n" + toString(" ");
1311: }
1312:
1313: public String toString(String n) {
1314: if (model instanceof CompoundNodeActionsProvider)
1315: return n
1316: + filter
1317: + "\n"
1318: + ((CompoundNodeActionsProvider) model)
1319: .toString(n + " ");
1320: if (model instanceof DelegatingNodeActionsProvider)
1321: return n
1322: + filter
1323: + "\n"
1324: + ((DelegatingNodeActionsProvider) model)
1325: .toString(n + " ");
1326: return n + filter + "\n" + n + " " + model;
1327: }
1328: }
1329:
1330: /**
1331: * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1332: * from given list of TableModels. DelegatingTableModel asks all underlaying
1333: * models for each concrete parameter, and returns first returned value.
1334: *
1335: * @author Jan Jancura
1336: */
1337: final static class DelegatingTableModel implements TableModel {
1338:
1339: private TableModel[] models;
1340: private HashMap<String, TableModel> classNameToModel = new HashMap<String, TableModel>();
1341:
1342: /**
1343: * Creates new instance of DelegatingTableModel for given list of
1344: * TableModels.
1345: *
1346: * @param models a list of TableModels
1347: */
1348: DelegatingTableModel(List<TableModel> models) {
1349: this (convert(models));
1350: }
1351:
1352: private static TableModel[] convert(List<TableModel> l) {
1353: TableModel[] models = new TableModel[l.size()];
1354: return l.toArray(models);
1355: }
1356:
1357: /**
1358: * Creates new instance of DelegatingTableModel for given array of
1359: * TableModels.
1360: *
1361: * @param models a array of TableModels
1362: */
1363: DelegatingTableModel(TableModel[] models) {
1364: this .models = models;
1365: }
1366:
1367: /**
1368: * Returns value to be displayed in column <code>columnID</code>
1369: * and row <code>node</code>. Column ID is defined in by
1370: * {@link ColumnModel#getID}, and rows are defined by values returned from
1371: * {@TreeModel#getChildren}.
1372: *
1373: * @param node a object returned from {@TreeModel#getChildren} for this row
1374: * @param columnID a id of column defined by {@link ColumnModel#getID}
1375: * @throws UnknownTypeException if there is no TableModel defined for given
1376: * parameter type
1377: *
1378: * @return value of variable representing given position in tree table.
1379: */
1380: public Object getValueAt(Object node, String columnID)
1381: throws UnknownTypeException {
1382: TableModel model = classNameToModel.get(node.getClass()
1383: .getName());
1384: if (model != null)
1385: try {
1386: return model.getValueAt(node, columnID);
1387: } catch (UnknownTypeException e) {
1388: }
1389: int i, k = models.length;
1390: for (i = 0; i < k; i++) {
1391: try {
1392: Object v = models[i].getValueAt(node, columnID);
1393: classNameToModel.put(node.getClass().getName(),
1394: models[i]);
1395: return v;
1396: } catch (UnknownTypeException e) {
1397: }
1398: }
1399: throw new UnknownTypeException(node);
1400: }
1401:
1402: /**
1403: * Returns true if value displayed in column <code>columnID</code>
1404: * and row <code>node</code> is read only. Column ID is defined in by
1405: * {@link ColumnModel#getID}, and rows are defined by values returned from
1406: * {@TreeModel#getChildren}.
1407: *
1408: * @param node a object returned from {@TreeModel#getChildren} for this row
1409: * @param columnID a id of column defined by {@link ColumnModel#getID}
1410: * @throws UnknownTypeException if there is no TableModel defined for given
1411: * parameter type
1412: *
1413: * @return true if variable on given position is read only
1414: */
1415: public boolean isReadOnly(Object node, String columnID)
1416: throws UnknownTypeException {
1417: TableModel model = classNameToModel.get(node.getClass()
1418: .getName());
1419: if (model != null)
1420: try {
1421: return model.isReadOnly(node, columnID);
1422: } catch (UnknownTypeException e) {
1423: }
1424: int i, k = models.length;
1425: for (i = 0; i < k; i++) {
1426: try {
1427: boolean ro = models[i].isReadOnly(node, columnID);
1428: classNameToModel.put(node.getClass().getName(),
1429: models[i]);
1430: return ro;
1431: } catch (UnknownTypeException e) {
1432: }
1433: }
1434: throw new UnknownTypeException(node);
1435: }
1436:
1437: /**
1438: * Changes a value displayed in column <code>columnID</code>
1439: * and row <code>node</code>. Column ID is defined in by
1440: * {@link ColumnModel#getID}, and rows are defined by values returned from
1441: * {@TreeModel#getChildren}.
1442: *
1443: * @param node a object returned from {@TreeModel#getChildren} for this row
1444: * @param columnID a id of column defined by {@link ColumnModel#getID}
1445: * @param value a new value of variable on given position
1446: * @throws UnknownTypeException if there is no TableModel defined for given
1447: * parameter type
1448: */
1449: public void setValueAt(Object node, String columnID,
1450: Object value) throws UnknownTypeException {
1451: TableModel model = classNameToModel.get(node.getClass()
1452: .getName());
1453: if (model != null)
1454: try {
1455: model.setValueAt(node, columnID, value);
1456: return;
1457: } catch (UnknownTypeException e) {
1458: }
1459: int i, k = models.length;
1460: for (i = 0; i < k; i++) {
1461: try {
1462: models[i].setValueAt(node, columnID, value);
1463: classNameToModel.put(node.getClass().getName(),
1464: models[i]);
1465: return;
1466: } catch (UnknownTypeException e) {
1467: }
1468: }
1469: throw new UnknownTypeException(node);
1470: }
1471:
1472: /**
1473: * Registers given listener.
1474: *
1475: * @param l the listener to add
1476: */
1477: public void addModelListener(ModelListener l) {
1478: int i, k = models.length;
1479: for (i = 0; i < k; i++)
1480: models[i].addModelListener(l);
1481: }
1482:
1483: /**
1484: * Unregisters given listener.
1485: *
1486: * @param l the listener to remove
1487: */
1488: public void removeModelListener(ModelListener l) {
1489: int i, k = models.length;
1490: for (i = 0; i < k; i++)
1491: models[i].removeModelListener(l);
1492: }
1493:
1494: public String toString() {
1495: return super .toString() + "\n" + toString(" ");
1496: }
1497:
1498: public String toString(String n) {
1499: int i, k = models.length - 1;
1500: if (k == -1)
1501: return "";
1502: StringBuffer sb = new StringBuffer();
1503: for (i = 0; i < k; i++) {
1504: sb.append(n);
1505: sb.append(models[i]);
1506: sb.append('\n');
1507: }
1508: sb.append(n);
1509: sb.append(models[i]);
1510: return new String(sb);
1511: }
1512: }
1513:
1514: /**
1515: * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1516: * from given list of TableModels. DelegatingTableModel asks all underlaying
1517: * models for each concrete parameter, and returns first returned value.
1518: *
1519: * @author Jan Jancura
1520: */
1521: final static class DelegatingTreeExpansionModel implements
1522: TreeExpansionModel {
1523:
1524: private TreeExpansionModel[] models;
1525: private HashMap<String, TreeExpansionModel> classNameToModel = new HashMap<String, TreeExpansionModel>();
1526:
1527: /**
1528: * Creates new instance of DelegatingTableModel for given list of
1529: * TableModels.
1530: *
1531: * @param models a list of TableModels
1532: */
1533: DelegatingTreeExpansionModel(List<TreeExpansionModel> models) {
1534: this (convert(models));
1535: }
1536:
1537: private static TreeExpansionModel[] convert(
1538: List<TreeExpansionModel> l) {
1539: TreeExpansionModel[] models = new TreeExpansionModel[l
1540: .size()];
1541: return l.toArray(models);
1542: }
1543:
1544: /**
1545: * Creates new instance of DelegatingTableModel for given array of
1546: * TableModels.
1547: *
1548: * @param models a array of TableModels
1549: */
1550: private DelegatingTreeExpansionModel(TreeExpansionModel[] models) {
1551: this .models = models;
1552: }
1553:
1554: /**
1555: * Defines default state (collapsed, expanded) of given node.
1556: *
1557: * @param node a node
1558: * @return default state (collapsed, expanded) of given node
1559: */
1560: public boolean isExpanded(Object node)
1561: throws UnknownTypeException {
1562: TreeExpansionModel model = classNameToModel.get(node
1563: .getClass().getName());
1564: if (model != null)
1565: try {
1566: return model.isExpanded(node);
1567: } catch (UnknownTypeException e) {
1568: }
1569: int i, k = models.length;
1570: for (i = 0; i < k; i++) {
1571: try {
1572: boolean result = models[i].isExpanded(node);
1573: classNameToModel.put(node.getClass().getName(),
1574: models[i]);
1575: return result;
1576: } catch (UnknownTypeException e) {
1577: }
1578: }
1579: throw new UnknownTypeException(node);
1580: }
1581:
1582: /**
1583: * Called when given node is expanded.
1584: *
1585: * @param node a expanded node
1586: */
1587: public void nodeExpanded(Object node) {
1588: int i, k = models.length;
1589: for (i = 0; i < k; i++) {
1590: models[i].nodeExpanded(node);
1591: }
1592: }
1593:
1594: /**
1595: * Called when given node is collapsed.
1596: *
1597: * @param node a collapsed node
1598: */
1599: public void nodeCollapsed(Object node) {
1600: int i, k = models.length;
1601: for (i = 0; i < k; i++) {
1602: models[i].nodeCollapsed(node);
1603: }
1604: }
1605:
1606: public String toString() {
1607: return super .toString() + "\n" + toString(" ");
1608: }
1609:
1610: public String toString(String n) {
1611: int i, k = models.length - 1;
1612: if (k == -1)
1613: return "";
1614: StringBuffer sb = new StringBuffer();
1615: for (i = 0; i < k; i++) {
1616: sb.append(n);
1617: sb.append(models[i]);
1618: sb.append('\n');
1619: }
1620: sb.append(n);
1621: sb.append(models[i]);
1622: return new String(sb);
1623: }
1624: }
1625:
1626: private static class DefaultTreeExpansionModel implements
1627: TreeExpansionModel {
1628:
1629: private Set<Object> expandedNodes = new WeakSet<Object>();
1630: private Set<Object> collapsedNodes = new WeakSet<Object>();
1631:
1632: /**
1633: * Defines default state (collapsed, expanded) of given node.
1634: *
1635: * @param node a node
1636: * @return default state (collapsed, expanded) of given node
1637: */
1638: public boolean isExpanded(Object node)
1639: throws UnknownTypeException {
1640: synchronized (this ) {
1641: if (expandedNodes.contains(node)) {
1642: return true;
1643: }
1644: if (collapsedNodes.contains(node)) {
1645: return false;
1646: }
1647: }
1648: // Default behavior follows:
1649: return false;
1650: }
1651:
1652: /**
1653: * Called when given node is expanded.
1654: *
1655: * @param node a expanded node
1656: */
1657: public void nodeExpanded(Object node) {
1658: synchronized (this ) {
1659: expandedNodes.add(node);
1660: collapsedNodes.remove(node);
1661: }
1662: }
1663:
1664: /**
1665: * Called when given node is collapsed.
1666: *
1667: * @param node a collapsed node
1668: */
1669: public void nodeCollapsed(Object node) {
1670: synchronized (this ) {
1671: collapsedNodes.add(node);
1672: expandedNodes.remove(node);
1673: }
1674: }
1675:
1676: }
1677:
1678: /**
1679: * Creates one {@link org.netbeans.spi.viewmodel.NodeModel}
1680: * from given list of NodeModels. DelegatingNodeModel asks all underlaying
1681: * models for each concrete parameter, and returns first returned value.
1682: *
1683: * @author Jan Jancura
1684: */
1685: static final class DelegatingNodeModel implements ExtendedNodeModel {
1686:
1687: private NodeModel[] models;
1688: private HashMap<String, NodeModel> classNameToModel = new HashMap<String, NodeModel>();
1689:
1690: /**
1691: * Creates new instance of DelegatingNodeModel for given list of
1692: * NodeModels.
1693: *
1694: * @param models a list of NodeModels
1695: */
1696: DelegatingNodeModel(List<NodeModel> models) {
1697: this (convert(models));
1698: }
1699:
1700: private static NodeModel[] convert(List<NodeModel> l) {
1701: NodeModel[] models = new NodeModel[l.size()];
1702: return l.toArray(models);
1703: }
1704:
1705: /**
1706: * Creates new instance of DelegatingNodeModel for given array of
1707: * NodeModels.
1708: *
1709: * @param models a array of NodeModels
1710: */
1711: DelegatingNodeModel(NodeModel[] models) {
1712: this .models = models;
1713:
1714: }
1715:
1716: NodeModel[] getModels() {
1717: return models;
1718: }
1719:
1720: /**
1721: * Returns display name for given node.
1722: *
1723: * @throws UnknownTypeException if this NodeModel implementation is not
1724: * able to resolve display name for given node type
1725: * @return display name for given node
1726: */
1727: public String getDisplayName(Object node)
1728: throws UnknownTypeException {
1729: NodeModel model = classNameToModel.get(node.getClass()
1730: .getName());
1731: if (model != null)
1732: try {
1733: return model.getDisplayName(node);
1734: } catch (UnknownTypeException e) {
1735: }
1736: int i, k = models.length;
1737: for (i = 0; i < k; i++) {
1738: try {
1739: String dn = models[i].getDisplayName(node);
1740: classNameToModel.put(node.getClass().getName(),
1741: models[i]);
1742: return dn;
1743: } catch (UnknownTypeException e) {
1744: }
1745: }
1746: throw new UnknownTypeException(node);
1747: }
1748:
1749: /**
1750: * Returns tooltip for given node.
1751: *
1752: * @throws UnknownTypeException if this NodeModel implementation is not
1753: * able to resolve tooltip for given node type
1754: * @return tooltip for given node
1755: */
1756: public String getShortDescription(Object node)
1757: throws UnknownTypeException {
1758: NodeModel model = classNameToModel.get(node.getClass()
1759: .getName());
1760: if (model != null)
1761: try {
1762: return model.getShortDescription(node);
1763: } catch (UnknownTypeException e) {
1764: }
1765: int i, k = models.length;
1766: for (i = 0; i < k; i++) {
1767: try {
1768: String dn = models[i].getShortDescription(node);
1769: classNameToModel.put(node.getClass().getName(),
1770: models[i]);
1771: return dn;
1772: } catch (UnknownTypeException e) {
1773: }
1774: }
1775: throw new UnknownTypeException(node);
1776: }
1777:
1778: /**
1779: * Returns icon for given node.
1780: *
1781: * @throws UnknownTypeException if this NodeModel implementation is not
1782: * able to resolve icon for given node type
1783: * @return icon for given node
1784: */
1785: public String getIconBase(Object node)
1786: throws UnknownTypeException {
1787: NodeModel model = classNameToModel.get(node.getClass()
1788: .getName());
1789: if (model != null)
1790: try {
1791: return model.getIconBase(node);
1792: } catch (UnknownTypeException e) {
1793: }
1794: int i, k = models.length;
1795: for (i = 0; i < k; i++) {
1796: try {
1797: String dn = models[i].getIconBase(node);
1798: classNameToModel.put(node.getClass().getName(),
1799: models[i]);
1800: return dn;
1801: } catch (UnknownTypeException e) {
1802: }
1803: }
1804: throw new UnknownTypeException(node);
1805: }
1806:
1807: /**
1808: * Registers given listener.
1809: *
1810: * @param l the listener to add
1811: */
1812: public void addModelListener(ModelListener l) {
1813: int i, k = models.length;
1814: for (i = 0; i < k; i++)
1815: models[i].addModelListener(l);
1816: }
1817:
1818: /**
1819: * Unregisters given listener.
1820: *
1821: * @param l the listener to remove
1822: */
1823: public void removeModelListener(ModelListener l) {
1824: int i, k = models.length;
1825: for (i = 0; i < k; i++)
1826: models[i].removeModelListener(l);
1827: }
1828:
1829: public String toString() {
1830: return toString(" ");
1831: }
1832:
1833: public String toString(String n) {
1834: int i, k = models.length - 1;
1835: if (k == -1)
1836: return "";
1837: StringBuffer sb = new StringBuffer();
1838: for (i = 0; i < k; i++) {
1839: sb.append(n);
1840: sb.append(models[i]);
1841: sb.append('\n');
1842: }
1843: sb.append(n);
1844: sb.append(models[i]);
1845: return new String(sb);
1846: }
1847:
1848: // Extensions:
1849:
1850: private boolean defaultCanRename() {
1851: return false;
1852: }
1853:
1854: private boolean defaultCanCopy() {
1855: return false;
1856: }
1857:
1858: private boolean defaultCanCut() {
1859: return false;
1860: }
1861:
1862: private Transferable defaultClipboardCopy() throws IOException {
1863: return null;
1864: }
1865:
1866: private Transferable defaultClipboardCut() throws IOException {
1867: return null;
1868: }
1869:
1870: /*
1871: private Transferable defaultDrag() throws IOException {
1872: return null;
1873: }
1874: */
1875:
1876: private PasteType[] defaultGetPasteTypes(Transferable t) {
1877: return null;
1878: }
1879:
1880: /*
1881: private PasteType defaultGetDropType(Transferable t, int action,
1882: int index) {
1883: return null;
1884: }
1885: */
1886:
1887: private void defaultSetName(String name) {
1888: // nothing
1889: }
1890:
1891: public boolean canRename(Object node)
1892: throws UnknownTypeException {
1893: UnknownTypeException uex = null;
1894: NodeModel model = classNameToModel.get(node.getClass()
1895: .getName());
1896: if (model != null) {
1897: if (model instanceof ExtendedNodeModel) {
1898: try {
1899: return ((ExtendedNodeModel) model)
1900: .canRename(node);
1901: } catch (UnknownTypeException e) {
1902: uex = e;
1903: }
1904: } else {
1905: return defaultCanRename();
1906: }
1907: }
1908: int i, k = models.length;
1909: boolean isExtended = false;
1910: for (i = 0; i < k; i++) {
1911: if (models[i] instanceof ExtendedNodeModel) {
1912: try {
1913: boolean cr = ((ExtendedNodeModel) models[i])
1914: .canRename(node);
1915: classNameToModel.put(node.getClass().getName(),
1916: models[i]);
1917: return cr;
1918: } catch (UnknownTypeException e) {
1919: uex = e;
1920: }
1921: isExtended = true;
1922: }
1923: }
1924: if (!isExtended) {
1925: return defaultCanRename();
1926: }
1927: if (uex != null) {
1928: throw uex;
1929: } else {
1930: throw new UnknownTypeException(node);
1931: }
1932: }
1933:
1934: public boolean canCopy(Object node) throws UnknownTypeException {
1935: UnknownTypeException uex = null;
1936: NodeModel model = classNameToModel.get(node.getClass()
1937: .getName());
1938: if (model != null) {
1939: if (model instanceof ExtendedNodeModel) {
1940: try {
1941: return ((ExtendedNodeModel) model)
1942: .canCopy(node);
1943: } catch (UnknownTypeException e) {
1944: uex = e;
1945: }
1946: } else {
1947: return defaultCanCopy();
1948: }
1949: }
1950: int i, k = models.length;
1951: boolean isExtended = false;
1952: for (i = 0; i < k; i++) {
1953: if (models[i] instanceof ExtendedNodeModel) {
1954: try {
1955: boolean cr = ((ExtendedNodeModel) models[i])
1956: .canCopy(node);
1957: classNameToModel.put(node.getClass().getName(),
1958: models[i]);
1959: return cr;
1960: } catch (UnknownTypeException e) {
1961: uex = e;
1962: }
1963: isExtended = true;
1964: }
1965: }
1966: if (!isExtended) {
1967: return defaultCanCopy();
1968: }
1969: if (uex != null) {
1970: throw uex;
1971: } else {
1972: throw new UnknownTypeException(node);
1973: }
1974: }
1975:
1976: public boolean canCut(Object node) throws UnknownTypeException {
1977: UnknownTypeException uex = null;
1978: NodeModel model = classNameToModel.get(node.getClass()
1979: .getName());
1980: if (model != null) {
1981: if (model instanceof ExtendedNodeModel) {
1982: try {
1983: return ((ExtendedNodeModel) model).canCut(node);
1984: } catch (UnknownTypeException e) {
1985: uex = e;
1986: }
1987: } else {
1988: return defaultCanCut();
1989: }
1990: }
1991: int i, k = models.length;
1992: boolean isExtended = false;
1993: for (i = 0; i < k; i++) {
1994: if (models[i] instanceof ExtendedNodeModel) {
1995: try {
1996: boolean cr = ((ExtendedNodeModel) models[i])
1997: .canCut(node);
1998: classNameToModel.put(node.getClass().getName(),
1999: models[i]);
2000: return cr;
2001: } catch (UnknownTypeException e) {
2002: uex = e;
2003: }
2004: isExtended = true;
2005: }
2006: }
2007: if (!isExtended) {
2008: return defaultCanCut();
2009: }
2010: if (uex != null) {
2011: throw uex;
2012: } else {
2013: throw new UnknownTypeException(node);
2014: }
2015: }
2016:
2017: public Transferable clipboardCopy(Object node)
2018: throws IOException, UnknownTypeException {
2019: UnknownTypeException uex = null;
2020: NodeModel model = classNameToModel.get(node.getClass()
2021: .getName());
2022: if (model != null) {
2023: if (model instanceof ExtendedNodeModel) {
2024: try {
2025: return ((ExtendedNodeModel) model)
2026: .clipboardCopy(node);
2027: } catch (UnknownTypeException e) {
2028: uex = e;
2029: }
2030: } else {
2031: return defaultClipboardCopy();
2032: }
2033: }
2034: int i, k = models.length;
2035: boolean isExtended = false;
2036: for (i = 0; i < k; i++) {
2037: if (models[i] instanceof ExtendedNodeModel) {
2038: try {
2039: Transferable t = ((ExtendedNodeModel) models[i])
2040: .clipboardCopy(node);
2041: classNameToModel.put(node.getClass().getName(),
2042: models[i]);
2043: return t;
2044: } catch (UnknownTypeException e) {
2045: uex = e;
2046: }
2047: isExtended = true;
2048: }
2049: }
2050: if (!isExtended) {
2051: return defaultClipboardCopy();
2052: }
2053: if (uex != null) {
2054: throw uex;
2055: } else {
2056: throw new UnknownTypeException(node);
2057: }
2058: }
2059:
2060: public Transferable clipboardCut(Object node)
2061: throws IOException, UnknownTypeException {
2062: UnknownTypeException uex = null;
2063: NodeModel model = classNameToModel.get(node.getClass()
2064: .getName());
2065: if (model != null) {
2066: if (model instanceof ExtendedNodeModel) {
2067: try {
2068: return ((ExtendedNodeModel) model)
2069: .clipboardCut(node);
2070: } catch (UnknownTypeException e) {
2071: uex = e;
2072: }
2073: } else {
2074: return defaultClipboardCut();
2075: }
2076: }
2077: int i, k = models.length;
2078: boolean isExtended = false;
2079: for (i = 0; i < k; i++) {
2080: if (models[i] instanceof ExtendedNodeModel) {
2081: try {
2082: Transferable t = ((ExtendedNodeModel) models[i])
2083: .clipboardCut(node);
2084: classNameToModel.put(node.getClass().getName(),
2085: models[i]);
2086: return t;
2087: } catch (UnknownTypeException e) {
2088: uex = e;
2089: }
2090: isExtended = true;
2091: }
2092: }
2093: if (!isExtended) {
2094: return defaultClipboardCut();
2095: }
2096: if (uex != null) {
2097: throw uex;
2098: } else {
2099: throw new UnknownTypeException(node);
2100: }
2101: }
2102:
2103: /*
2104: public Transferable drag(Object node) throws IOException,
2105: UnknownTypeException {
2106: UnknownTypeException uex = null;
2107: NodeModel model = (NodeModel) classNameToModel.get (
2108: node.getClass ().getName ()
2109: );
2110: if (model != null) {
2111: if (model instanceof ExtendedNodeModel) {
2112: try {
2113: return ((ExtendedNodeModel) model).drag (node);
2114: } catch (UnknownTypeException e) {
2115: uex = e;
2116: }
2117: } else {
2118: return defaultDrag();
2119: }
2120: }
2121: int i, k = models.length;
2122: boolean isExtended = false;
2123: for (i = 0; i < k; i++) {
2124: if (models[i] instanceof ExtendedNodeModel) {
2125: try {
2126: Transferable t = ((ExtendedNodeModel) models [i]).drag (node);
2127: classNameToModel.put (node.getClass ().getName (), models [i]);
2128: return t;
2129: } catch (UnknownTypeException e) {
2130: uex = e;
2131: }
2132: isExtended = true;
2133: }
2134: }
2135: if (!isExtended) {
2136: return defaultDrag();
2137: }
2138: if (uex != null) {
2139: throw uex;
2140: } else {
2141: throw new UnknownTypeException (node);
2142: }
2143: }
2144: */
2145:
2146: public PasteType[] getPasteTypes(Object node, Transferable t)
2147: throws UnknownTypeException {
2148: UnknownTypeException uex = null;
2149: NodeModel model = classNameToModel.get(node.getClass()
2150: .getName());
2151: if (model != null) {
2152: if (model instanceof ExtendedNodeModel) {
2153: try {
2154: return ((ExtendedNodeModel) model)
2155: .getPasteTypes(node, t);
2156: } catch (UnknownTypeException e) {
2157: uex = e;
2158: }
2159: } else {
2160: return defaultGetPasteTypes(t);
2161: }
2162: }
2163: int i, k = models.length;
2164: boolean isExtended = false;
2165: for (i = 0; i < k; i++) {
2166: if (models[i] instanceof ExtendedNodeModel) {
2167: try {
2168: PasteType[] p = ((ExtendedNodeModel) models[i])
2169: .getPasteTypes(node, t);
2170: classNameToModel.put(node.getClass().getName(),
2171: models[i]);
2172: return p;
2173: } catch (UnknownTypeException e) {
2174: uex = e;
2175: }
2176: isExtended = true;
2177: }
2178: }
2179: if (!isExtended) {
2180: return defaultGetPasteTypes(t);
2181: }
2182: if (uex != null) {
2183: throw uex;
2184: } else {
2185: throw new UnknownTypeException(node);
2186: }
2187: }
2188:
2189: /*
2190: public PasteType getDropType(Object node, Transferable t, int action,
2191: int index) throws UnknownTypeException {
2192: UnknownTypeException uex = null;
2193: NodeModel model = (NodeModel) classNameToModel.get (
2194: node.getClass ().getName ()
2195: );
2196: if (model != null) {
2197: if (model instanceof ExtendedNodeModel) {
2198: try {
2199: return ((ExtendedNodeModel) model).getDropType (node, t, action, index);
2200: } catch (UnknownTypeException e) {
2201: uex = e;
2202: }
2203: } else {
2204: return defaultGetDropType(t, action, index);
2205: }
2206: }
2207: int i, k = models.length;
2208: boolean isExtended = false;
2209: for (i = 0; i < k; i++) {
2210: if (models[i] instanceof ExtendedNodeModel) {
2211: try {
2212: PasteType p = ((ExtendedNodeModel) models [i]).getDropType (node, t, action, index);
2213: classNameToModel.put (node.getClass ().getName (), models [i]);
2214: return p;
2215: } catch (UnknownTypeException e) {
2216: uex = e;
2217: }
2218: isExtended = true;
2219: }
2220: }
2221: if (!isExtended) {
2222: return defaultGetDropType(t, action, index);
2223: }
2224: if (uex != null) {
2225: throw uex;
2226: } else {
2227: throw new UnknownTypeException (node);
2228: }
2229: }
2230: */
2231:
2232: public void setName(Object node, String name)
2233: throws UnknownTypeException {
2234: UnknownTypeException uex = null;
2235: NodeModel model = classNameToModel.get(node.getClass()
2236: .getName());
2237: if (model != null) {
2238: if (model instanceof ExtendedNodeModel) {
2239: try {
2240: ((ExtendedNodeModel) model).setName(node, name);
2241: return;
2242: } catch (UnknownTypeException e) {
2243: uex = e;
2244: }
2245: } else {
2246: defaultSetName(name);
2247: return;
2248: }
2249: }
2250: int i, k = models.length;
2251: boolean isExtended = false;
2252: for (i = 0; i < k; i++) {
2253: if (models[i] instanceof ExtendedNodeModel) {
2254: try {
2255: ((ExtendedNodeModel) models[i]).setName(node,
2256: name);
2257: classNameToModel.put(node.getClass().getName(),
2258: models[i]);
2259: return;
2260: } catch (UnknownTypeException e) {
2261: uex = e;
2262: }
2263: isExtended = true;
2264: }
2265: }
2266: if (!isExtended) {
2267: defaultSetName(name);
2268: return;
2269: }
2270: if (uex != null) {
2271: throw uex;
2272: } else {
2273: throw new UnknownTypeException(node);
2274: }
2275: }
2276:
2277: public String getIconBaseWithExtension(Object node)
2278: throws UnknownTypeException {
2279: UnknownTypeException uex = null;
2280: NodeModel model = classNameToModel.get(node.getClass()
2281: .getName());
2282: if (model != null) {
2283: try {
2284: if (model instanceof ExtendedNodeModel) {
2285: return ((ExtendedNodeModel) model)
2286: .getIconBaseWithExtension(node);
2287: } else {
2288: String base = model.getIconBase(node);
2289: if (base != null) {
2290: return base + ".gif";
2291: } else {
2292: return null;
2293: }
2294: }
2295: } catch (UnknownTypeException e) {
2296: uex = e;
2297: }
2298: }
2299: int i, k = models.length;
2300: for (i = 0; i < k; i++) {
2301: try {
2302: String ib;
2303: if (models[i] instanceof ExtendedNodeModel) {
2304: ib = ((ExtendedNodeModel) models[i])
2305: .getIconBaseWithExtension(node);
2306: } else {
2307: String base = models[i].getIconBase(node);
2308: if (base != null) {
2309: ib = base + ".gif";
2310: } else {
2311: ib = null;
2312: }
2313: }
2314: classNameToModel.put(node.getClass().getName(),
2315: models[i]);
2316: return ib;
2317: } catch (UnknownTypeException e) {
2318: uex = e;
2319: }
2320: }
2321: if (uex != null) {
2322: throw uex;
2323: } else {
2324: throw new UnknownTypeException(node);
2325: }
2326:
2327: }
2328: }
2329:
2330: /**
2331: * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TreeModel}.
2332: *
2333: * @author Jan Jancura
2334: */
2335: private static final class EmptyTreeModel implements TreeModel {
2336:
2337: /**
2338: * Returns {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}.
2339: *
2340: * @return {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}
2341: */
2342: public Object getRoot() {
2343: return ROOT;
2344: }
2345:
2346: /**
2347: * Returns empty array.
2348: *
2349: * @return empty array
2350: */
2351: public Object[] getChildren(Object parent, int from, int to) {
2352: return new Object[0];
2353: }
2354:
2355: /**
2356: * Returns number of children for given node.
2357: *
2358: * @param node the parent node
2359: * @throws UnknownTypeException if this TreeModel implementation is not
2360: * able to resolve children for given node type
2361: *
2362: * @return true if node is leaf
2363: */
2364: public int getChildrenCount(Object node) {
2365: return 0;
2366: }
2367:
2368: /**
2369: * Returns false.
2370: *
2371: * @return false
2372: */
2373: public boolean isLeaf(Object node) {
2374: return false;
2375: }
2376:
2377: /**
2378: * Do nothing.
2379: *
2380: * @param l the listener to be added
2381: */
2382: public void addModelListener(ModelListener l) {
2383: }
2384:
2385: /**
2386: * Do nothing.
2387: *
2388: * @param l the listener to be removed
2389: */
2390: public void removeModelListener(ModelListener l) {
2391: }
2392: }
2393:
2394: /**
2395: * Empty impleemntation of {@link org.netbeans.spi.viewmodel.NodeModel}.
2396: *
2397: * @author Jan Jancura
2398: */
2399: private static final class EmptyNodeModel implements NodeModel {
2400:
2401: /**
2402: * Returns display name for given node.
2403: *
2404: * @throws UnknownTypeException if this NodeModel implementation is not
2405: * able to resolve display name for given node type
2406: * @return display name for given node
2407: */
2408: public String getDisplayName(Object node)
2409: throws UnknownTypeException {
2410: throw new UnknownTypeException(node);
2411: }
2412:
2413: /**
2414: * Returns icon for given node.
2415: *
2416: * @throws UnknownTypeException if this NodeModel implementation is not
2417: * able to resolve icon for given node type
2418: * @return icon for given node
2419: */
2420: public String getIconBase(Object node)
2421: throws UnknownTypeException {
2422: throw new UnknownTypeException(node);
2423: }
2424:
2425: /**
2426: * Returns tooltip for given node.
2427: *
2428: * @throws UnknownTypeException if this NodeModel implementation is not
2429: * able to resolve tooltip for given node type
2430: * @return tooltip for given node
2431: */
2432: public String getShortDescription(Object node)
2433: throws UnknownTypeException {
2434: throw new UnknownTypeException(node);
2435: }
2436:
2437: /**
2438: * Do nothing.
2439: *
2440: * @param l the listener to be added
2441: */
2442: public void addModelListener(ModelListener l) {
2443: }
2444:
2445: /**
2446: * Do nothing.
2447: *
2448: * @param l the listener to be removed
2449: */
2450: public void removeModelListener(ModelListener l) {
2451: }
2452: }
2453:
2454: /**
2455: * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
2456: *
2457: * @author Jan Jancura
2458: */
2459: private static final class EmptyTableModel implements TableModel {
2460:
2461: /**
2462: * Returns value to be displayed in column <code>columnID</code>
2463: * and row identified by <code>node</code>. Column ID is defined in by
2464: * {@link ColumnModel#getID}, and rows are defined by values returned from
2465: * {@link org.netbeans.spi.viewmodel.TreeModel#getChildren}.
2466: *
2467: * @param node a object returned from
2468: * {@link org.netbeans.spi.viewmodel.TreeModel#getChildren} for this row
2469: * @param columnID a id of column defined by {@link ColumnModel#getID}
2470: * @throws UnknownTypeException if there is no TableModel defined for given
2471: * parameter type
2472: *
2473: * @return value of variable representing given position in tree table.
2474: */
2475: public Object getValueAt(Object node, String columnID)
2476: throws UnknownTypeException {
2477: throw new UnknownTypeException(node);
2478: }
2479:
2480: /**
2481: * Returns true if value displayed in column <code>columnID</code>
2482: * and row <code>node</code> is read only. Column ID is defined in by
2483: * {@link ColumnModel#getID}, and rows are defined by values returned from
2484: * {@link TreeModel#getChildren}.
2485: *
2486: * @param node a object returned from {@link TreeModel#getChildren} for this row
2487: * @param columnID a id of column defined by {@link ColumnModel#getID}
2488: * @throws UnknownTypeException if there is no TableModel defined for given
2489: * parameter type
2490: *
2491: * @return true if variable on given position is read only
2492: */
2493: public boolean isReadOnly(Object node, String columnID)
2494: throws UnknownTypeException {
2495: throw new UnknownTypeException(node);
2496: }
2497:
2498: /**
2499: * Changes a value displayed in column <code>columnID</code>
2500: * and row <code>node</code>. Column ID is defined in by
2501: * {@link ColumnModel#getID}, and rows are defined by values returned from
2502: * {@link TreeModel#getChildren}.
2503: *
2504: * @param node a object returned from {@link TreeModel#getChildren} for this row
2505: * @param columnID a id of column defined by {@link ColumnModel#getID}
2506: * @param value a new value of variable on given position
2507: * @throws UnknownTypeException if there is no TableModel defined for given
2508: * parameter type
2509: */
2510: public void setValueAt(Object node, String columnID,
2511: Object value) throws UnknownTypeException {
2512: throw new UnknownTypeException(node);
2513: }
2514:
2515: /**
2516: * Do nothing.
2517: *
2518: * @param l the listener to be added
2519: */
2520: public void addModelListener(ModelListener l) {
2521: }
2522:
2523: /**
2524: * Do nothing.
2525: *
2526: * @param l the listener to be removed
2527: */
2528: public void removeModelListener(ModelListener l) {
2529: }
2530: }
2531:
2532: /**
2533: * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
2534: *
2535: * @author Jan Jancura
2536: */
2537: private static final class EmptyNodeActionsProvider implements
2538: NodeActionsProvider {
2539:
2540: /**
2541: * Performs default action for given node.
2542: *
2543: * @throws UnknownTypeException if this NodeActionsProvider implementation
2544: * is not able to resolve actions for given node type
2545: * @return display name for given node
2546: */
2547: public void performDefaultAction(Object node)
2548: throws UnknownTypeException {
2549: throw new UnknownTypeException(node);
2550: }
2551:
2552: /**
2553: * Returns set of actions for given node.
2554: *
2555: * @throws UnknownTypeException if this NodeActionsProvider implementation
2556: * is not able to resolve actions for given node type
2557: * @return display name for given node
2558: */
2559: public Action[] getActions(Object node)
2560: throws UnknownTypeException {
2561: throw new UnknownTypeException(node);
2562: }
2563: }
2564:
2565: /**
2566: * Creates one {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
2567: * from given list of NodeActionsProviders. DelegatingNodeActionsProvider asks all
2568: * underlaying models for each concrete parameter, and returns first
2569: * returned value.
2570: *
2571: * @author Jan Jancura
2572: */
2573: static final class DelegatingNodeActionsProvider implements
2574: NodeActionsProvider {
2575:
2576: private NodeActionsProvider[] models;
2577: private HashMap<String, NodeActionsProvider> classNameToModel = new HashMap<String, NodeActionsProvider>();
2578:
2579: /**
2580: * Creates new instance of DelegatingNodeActionsProvider for given list of
2581: * NodeActionsProvider.
2582: *
2583: * @param models a list of NodeActionsProvider
2584: */
2585: public DelegatingNodeActionsProvider(
2586: List<NodeActionsProvider> models) {
2587: this (convert(models));
2588: }
2589:
2590: private static NodeActionsProvider[] convert(
2591: List<NodeActionsProvider> l) {
2592: NodeActionsProvider[] models = new NodeActionsProvider[l
2593: .size()];
2594: return l.toArray(models);
2595: }
2596:
2597: /**
2598: * Creates new instance of DelegatingNodeActionsProvider for given array of
2599: * NodeActionsProvider.
2600: *
2601: * @param models a array of NodeActionsProvider
2602: */
2603: public DelegatingNodeActionsProvider(
2604: NodeActionsProvider[] models) {
2605: this .models = models;
2606: }
2607:
2608: /**
2609: * Returns set of actions for given node.
2610: *
2611: * @throws UnknownTypeException if this NodeActionsProvider implementation
2612: * is not able to resolve actions for given node type
2613: * @return display name for given node
2614: */
2615: public Action[] getActions(Object node)
2616: throws UnknownTypeException {
2617: NodeActionsProvider model = classNameToModel.get(node
2618: .getClass().getName());
2619: if (model != null)
2620: try {
2621: return model.getActions(node);
2622: } catch (UnknownTypeException e) {
2623: }
2624: int i, k = models.length;
2625: for (i = 0; i < k; i++) {
2626: try {
2627: Action[] dn = models[i].getActions(node);
2628: classNameToModel.put(node.getClass().getName(),
2629: models[i]);
2630: return dn;
2631: } catch (UnknownTypeException e) {
2632: }
2633: }
2634: throw new UnknownTypeException(node);
2635: }
2636:
2637: /**
2638: * Performs default action for given node.
2639: *
2640: * @throws UnknownTypeException if this NodeActionsProvider implementation
2641: * is not able to resolve actions for given node type
2642: * @return display name for given node
2643: */
2644: public void performDefaultAction(Object node)
2645: throws UnknownTypeException {
2646: NodeActionsProvider model = classNameToModel.get(node
2647: .getClass().getName());
2648: if (model != null)
2649: try {
2650: model.performDefaultAction(node);
2651: return;
2652: } catch (UnknownTypeException e) {
2653: }
2654: int i, k = models.length;
2655: for (i = 0; i < k; i++) {
2656: try {
2657: models[i].performDefaultAction(node);
2658: classNameToModel.put(node.getClass().getName(),
2659: models[i]);
2660: return;
2661: } catch (UnknownTypeException e) {
2662: }
2663: }
2664: throw new UnknownTypeException(node);
2665: }
2666:
2667: public String toString() {
2668: return super .toString() + "\n" + toString(" ");
2669: }
2670:
2671: public String toString(String n) {
2672: int i, k = models.length - 1;
2673: if (k == -1)
2674: return "";
2675: StringBuffer sb = new StringBuffer();
2676: for (i = 0; i < k; i++) {
2677: sb.append(n);
2678: sb.append(models[i]);
2679: sb.append('\n');
2680: }
2681: sb.append(n);
2682: sb.append(models[i]);
2683: return new String(sb);
2684: }
2685: }
2686:
2687: /**
2688: * Implements set of tree view features.
2689: */
2690: public static final class TreeFeatures {
2691:
2692: private JComponent view;
2693:
2694: private TreeFeatures(JComponent view) {
2695: this .view = view;
2696: }
2697:
2698: /**
2699: * Returns <code>true</code> if given node is expanded.
2700: *
2701: * @param node a node to be checked
2702: * @return <code>true</code> if given node is expanded
2703: */
2704: public boolean isExpanded(Object node) {
2705: return ((TreeTable) view).isExpanded(node);
2706: }
2707:
2708: /**
2709: * Expands given list of nodes.
2710: *
2711: * @param node a list of nodes to be expanded
2712: */
2713: public void expandNode(Object node) {
2714: ((TreeTable) view).expandNode(node);
2715: }
2716:
2717: /**
2718: * Collapses given node.
2719: *
2720: * @param node a node to be expanded
2721: */
2722: public void collapseNode(Object node) {
2723: ((TreeTable) view).collapseNode(node);
2724: }
2725: }
2726:
2727: /**
2728: * This model encapsulates all currently supported models.
2729: *
2730: * @see Models#createCompoundModel
2731: * @author Jan Jancura
2732: */
2733: public static final class CompoundModel implements TreeModel,
2734: ExtendedNodeModel, NodeActionsProvider, TableModel,
2735: TreeExpansionModel {
2736:
2737: private TreeModel treeModel;
2738: private ExtendedNodeModel nodeModel;
2739: private NodeActionsProvider nodeActionsProvider;
2740: private ColumnModel[] columnModels;
2741: private TableModel tableModel;
2742: private TreeExpansionModel treeExpansionModel;
2743:
2744: // <RAVE>
2745: // New field, setter/getter for propertiesHelpID, which is used
2746: // for property sheet help
2747: private String propertiesHelpID = null;
2748:
2749: // </RAVE>
2750:
2751: // init ....................................................................
2752:
2753: /**
2754: * Creates a new instance of {@link CompoundModel} for given models.
2755: *
2756: * @param treeModel a tree model to delegate on
2757: * @param nodeModel a node model to delegate on
2758: * @param nodeActionsProvider a node actions provider to delegate on
2759: * @param nodeActionsProvider a columns modeol to delegate on
2760: */
2761: private CompoundModel(TreeModel treeModel,
2762: TreeExpansionModel treeExpansionModel,
2763: ExtendedNodeModel nodeModel,
2764: NodeActionsProvider nodeActionsProvider,
2765: List<ColumnModel> columnModels, TableModel tableModel,
2766: String propertiesHelpID) {
2767: if (treeModel == null)
2768: throw new NullPointerException();
2769: if (treeModel == null)
2770: throw new NullPointerException();
2771: if (nodeModel == null)
2772: throw new NullPointerException();
2773: if (tableModel == null)
2774: throw new NullPointerException();
2775: if (nodeActionsProvider == null)
2776: throw new NullPointerException();
2777:
2778: this .treeModel = treeModel;
2779: this .treeExpansionModel = treeExpansionModel;
2780: this .nodeModel = nodeModel;
2781: this .tableModel = tableModel;
2782: this .nodeActionsProvider = nodeActionsProvider;
2783: this .columnModels = columnModels
2784: .toArray(new ColumnModel[columnModels.size()]);
2785: this .propertiesHelpID = propertiesHelpID;
2786: }
2787:
2788: // <RAVE>
2789: /**
2790: * Get a help ID for this model.
2791: * @return The help ID defined for the properties sheets,
2792: * or <code>null</code>.
2793: * @since 1.7
2794: */
2795: public String getHelpId() {
2796: return propertiesHelpID;
2797: }
2798:
2799: // </RAVE>
2800:
2801: // TreeModel ...............................................................
2802:
2803: /**
2804: * Returns the root node of the tree or null, if the tree is empty.
2805: *
2806: * @return the root node of the tree or null
2807: */
2808: public Object getRoot() {
2809: return treeModel.getRoot();
2810: }
2811:
2812: /**
2813: * Returns children for given parent on given indexes.
2814: *
2815: * @param parent a parent of returned nodes
2816: * @throws UnknownTypeException if this TreeModel implementation is not
2817: * able to resolve dchildren for given node type
2818: *
2819: * @return children for given parent on given indexes
2820: */
2821: public Object[] getChildren(Object parent, int from, int to)
2822: throws UnknownTypeException {
2823: return treeModel.getChildren(parent, from, to);
2824: }
2825:
2826: /**
2827: * Returns number of children for given node.
2828: *
2829: * @param node the parent node
2830: * @throws UnknownTypeException if this TreeModel implementation is not
2831: * able to resolve children for given node type
2832: *
2833: * @return true if node is leaf
2834: */
2835: public int getChildrenCount(Object node)
2836: throws UnknownTypeException {
2837: return treeModel.getChildrenCount(node);
2838: }
2839:
2840: /**
2841: * Returns true if node is leaf.
2842: *
2843: * @throws UnknownTypeException if this TreeModel implementation is not
2844: * able to resolve dchildren for given node type
2845: * @return true if node is leaf
2846: */
2847: public boolean isLeaf(Object node) throws UnknownTypeException {
2848: return treeModel.isLeaf(node);
2849: }
2850:
2851: // NodeModel ...............................................................
2852:
2853: /**
2854: * Returns display name for given node.
2855: *
2856: * @throws UnknownTypeException if this NodeModel implementation is not
2857: * able to resolve display name for given node type
2858: * @return display name for given node
2859: */
2860: public String getDisplayName(Object node)
2861: throws UnknownTypeException {
2862: if (nodeModel instanceof DelegatingNodeModel) {
2863: NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2864: .getModels();
2865: if (subModels.length == 0) {
2866: if (TreeModel.ROOT.equals(node)) {
2867: ColumnModel[] columns = getColumns();
2868: for (ColumnModel cm : columns) {
2869: if (cm.getType() == null) {
2870: return cm.getDisplayName();
2871: }
2872: }
2873: }
2874: return ""; // Nothing when there are no models
2875: }
2876: }
2877: return nodeModel.getDisplayName(node);
2878: }
2879:
2880: /**
2881: * Returns tooltip for given node.
2882: *
2883: * @throws UnknownTypeException if this NodeModel implementation is not
2884: * able to resolve tooltip for given node type
2885: * @return tooltip for given node
2886: */
2887: public String getShortDescription(Object node)
2888: throws UnknownTypeException {
2889: if (nodeModel instanceof DelegatingNodeModel) {
2890: NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2891: .getModels();
2892: if (subModels.length == 0) {
2893: if (TreeModel.ROOT.equals(node)) {
2894: ColumnModel[] columns = getColumns();
2895: for (ColumnModel cm : columns) {
2896: if (cm.getType() == null) {
2897: return cm.getShortDescription();
2898: }
2899: }
2900: }
2901: }
2902: }
2903: return nodeModel.getShortDescription(node);
2904: }
2905:
2906: /**
2907: * Returns icon for given node.
2908: *
2909: * @throws UnknownTypeException if this NodeModel implementation is not
2910: * able to resolve icon for given node type
2911: * @return icon for given node
2912: */
2913: public String getIconBase(Object node)
2914: throws UnknownTypeException {
2915: if (nodeModel instanceof DelegatingNodeModel) {
2916: NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2917: .getModels();
2918: if (subModels.length == 0) {
2919: return null; // Nothing when there are no models
2920: }
2921: }
2922: return nodeModel.getIconBase(node);
2923: }
2924:
2925: // NodeActionsProvider .....................................................
2926:
2927: /**
2928: * Performs default action for given node.
2929: *
2930: * @throws UnknownTypeException if this NodeActionsProvider implementation
2931: * is not able to resolve actions for given node type
2932: * @return display name for given node
2933: */
2934: public void performDefaultAction(Object node)
2935: throws UnknownTypeException {
2936: nodeActionsProvider.performDefaultAction(node);
2937: }
2938:
2939: /**
2940: * Returns set of actions for given node.
2941: *
2942: * @throws UnknownTypeException if this NodeActionsProvider implementation
2943: * is not able to resolve actions for given node type
2944: * @return display name for given node
2945: */
2946: public Action[] getActions(Object node)
2947: throws UnknownTypeException {
2948: return nodeActionsProvider.getActions(node);
2949: }
2950:
2951: // ColumnsModel ............................................................
2952:
2953: /**
2954: * Returns sorted array of
2955: * {@link org.netbeans.spi.viewmodel.ColumnModel}s.
2956: *
2957: * @return sorted array of ColumnModels
2958: */
2959: public ColumnModel[] getColumns() {
2960: return columnModels;
2961: }
2962:
2963: // TableModel ..............................................................
2964:
2965: public Object getValueAt(Object node, String columnID)
2966: throws UnknownTypeException {
2967: return tableModel.getValueAt(node, columnID);
2968: }
2969:
2970: public boolean isReadOnly(Object node, String columnID)
2971: throws UnknownTypeException {
2972: return tableModel.isReadOnly(node, columnID);
2973: }
2974:
2975: public void setValueAt(Object node, String columnID,
2976: Object value) throws UnknownTypeException {
2977: tableModel.setValueAt(node, columnID, value);
2978: }
2979:
2980: // TreeExpansionModel ......................................................
2981:
2982: /**
2983: * Defines default state (collapsed, expanded) of given node.
2984: *
2985: * @param node a node
2986: * @return default state (collapsed, expanded) of given node
2987: */
2988: public boolean isExpanded(Object node)
2989: throws UnknownTypeException {
2990: if (treeExpansionModel == null)
2991: return false;
2992: return treeExpansionModel.isExpanded(node);
2993: }
2994:
2995: /**
2996: * Called when given node is expanded.
2997: *
2998: * @param node a expanded node
2999: */
3000: public void nodeExpanded(Object node) {
3001: if (treeExpansionModel != null)
3002: treeExpansionModel.nodeExpanded(node);
3003: }
3004:
3005: /**
3006: * Called when given node is collapsed.
3007: *
3008: * @param node a collapsed node
3009: */
3010: public void nodeCollapsed(Object node) {
3011: if (treeExpansionModel != null)
3012: treeExpansionModel.nodeCollapsed(node);
3013: }
3014:
3015: // listeners ...............................................................
3016:
3017: /**
3018: * Registers given listener.
3019: *
3020: * @param l the listener to add
3021: */
3022: public void addModelListener(ModelListener l) {
3023: treeModel.addModelListener(l);
3024: if (nodeModel != treeModel) {
3025: nodeModel.addModelListener(l);
3026: }
3027: if (tableModel != treeModel && tableModel != nodeModel) {
3028: tableModel.addModelListener(l);
3029: }
3030: }
3031:
3032: /**
3033: * Unregisters given listener.
3034: *
3035: * @param l the listener to remove
3036: */
3037: public void removeModelListener(ModelListener l) {
3038: treeModel.removeModelListener(l);
3039: if (nodeModel != treeModel) {
3040: nodeModel.removeModelListener(l);
3041: }
3042: if (tableModel != treeModel && tableModel != nodeModel) {
3043: tableModel.removeModelListener(l);
3044: }
3045: }
3046:
3047: public String toString() {
3048: return super .toString() + "\n TreeModel = " + treeModel
3049: + "\n NodeModel = " + nodeModel
3050: + "\n TableModel = " + tableModel
3051: + "\n NodeActionsProvider = "
3052: + nodeActionsProvider + "\n ColumnsModel = "
3053: + java.util.Arrays.asList(columnModels);
3054: }
3055:
3056: // ExtendedNodeModel
3057:
3058: public boolean canRename(Object node)
3059: throws UnknownTypeException {
3060: return nodeModel.canRename(node);
3061: }
3062:
3063: public boolean canCopy(Object node) throws UnknownTypeException {
3064: return nodeModel.canCopy(node);
3065: }
3066:
3067: public boolean canCut(Object node) throws UnknownTypeException {
3068: return nodeModel.canCut(node);
3069: }
3070:
3071: public Transferable clipboardCopy(Object node)
3072: throws IOException, UnknownTypeException {
3073: return nodeModel.clipboardCopy(node);
3074: }
3075:
3076: public Transferable clipboardCut(Object node)
3077: throws IOException, UnknownTypeException {
3078: return nodeModel.clipboardCut(node);
3079: }
3080:
3081: /*
3082: public Transferable drag(Object node) throws IOException,
3083: UnknownTypeException {
3084: return nodeModel.drag(node);
3085: }
3086: */
3087:
3088: public PasteType[] getPasteTypes(Object node, Transferable t)
3089: throws UnknownTypeException {
3090: return nodeModel.getPasteTypes(node, t);
3091: }
3092:
3093: /*
3094: public PasteType getDropType(Object node, Transferable t, int action,
3095: int index) throws UnknownTypeException {
3096: return nodeModel.getDropType(node, t, action, index);
3097: }
3098: */
3099:
3100: public void setName(Object node, String name)
3101: throws UnknownTypeException {
3102: nodeModel.setName(node, name);
3103: }
3104:
3105: public String getIconBaseWithExtension(Object node)
3106: throws UnknownTypeException {
3107: return nodeModel.getIconBaseWithExtension(node);
3108: }
3109: }
3110: }
|