1 19 20 package org.netbeans.spi.viewmodel; 21 22 import java.awt.event.ActionEvent ; 23 import java.lang.StringBuffer ; 24 import java.lang.ref.WeakReference ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.Collections ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.IdentityHashMap ; 31 import java.util.Iterator ; 32 import java.util.LinkedList ; 33 import java.util.List ; 34 import java.util.Set ; 35 import java.util.Vector ; 36 import java.util.WeakHashMap ; 37 import javax.swing.AbstractAction ; 38 import javax.swing.Action ; 39 import javax.swing.JComponent ; 40 import javax.swing.SwingUtilities ; 41 42 import org.netbeans.modules.viewmodel.TreeModelNode; 43 import org.netbeans.modules.viewmodel.TreeTable; 44 45 import org.netbeans.spi.viewmodel.ColumnModel; 46 import org.netbeans.spi.viewmodel.NodeActionsProvider; 47 import org.netbeans.spi.viewmodel.NodeActionsProviderFilter; 48 import org.netbeans.spi.viewmodel.NodeModel; 49 import org.netbeans.spi.viewmodel.NodeModelFilter; 50 import org.netbeans.spi.viewmodel.TableModel; 51 import org.netbeans.spi.viewmodel.TableModelFilter; 52 import org.netbeans.spi.viewmodel.TreeModel; 53 import org.netbeans.spi.viewmodel.TreeModelFilter; 54 import org.netbeans.spi.viewmodel.ModelListener; 55 import org.netbeans.spi.viewmodel.UnknownTypeException; 56 import org.openide.nodes.Node; 57 import org.openide.util.WeakSet; 58 59 import org.openide.windows.TopComponent; 60 61 62 67 public final class Models { 68 69 70 private static WeakHashMap defaultExpansionModels = new WeakHashMap (); 71 74 public static CompoundModel EMPTY_MODEL = createCompoundModel 75 (new ArrayList ()); 76 77 78 public static int MULTISELECTION_TYPE_EXACTLY_ONE = 1; 79 public static int MULTISELECTION_TYPE_ALL = 2; 80 public static int MULTISELECTION_TYPE_ANY = 3; 81 82 private static boolean verbose = 83 System.getProperty ("netbeans.debugger.models") != null; 84 85 86 94 public static JComponent createView ( 95 CompoundModel compoundModel 96 ) { 97 TreeTable tt = new TreeTable (); 98 tt.setModel (compoundModel); 99 return tt; 100 } 101 102 108 public static void setModelsToView ( 109 final JComponent view, 110 final CompoundModel compoundModel 111 ) { 112 if (!(view instanceof TreeTable)) { 113 throw new IllegalArgumentException ("Expecting an instance of "+TreeTable.class.getName()+", which can be obtained from Models.createView()."); 114 } 115 if (verbose) 116 System.out.println (compoundModel); 117 SwingUtilities.invokeLater (new Runnable () { 118 public void run () { 119 ((TreeTable) view).setModel (compoundModel); 120 } 121 }); 122 } 123 124 135 public static CompoundModel createCompoundModel (List models) { 136 return createCompoundModel(models, null); 137 } 138 139 153 public static CompoundModel createCompoundModel (List models, String propertiesHelpID) { 154 List treeModels; 155 List treeModelFilters; 156 List treeExpansionModels; 157 List nodeModels; 158 List nodeModelFilters; 159 List tableModels; 160 List tableModelFilters; 161 List nodeActionsProviders; 162 List nodeActionsProviderFilters; 163 List columnModels; 164 List otherModels; 165 166 boolean hasLists = false; 168 if (models.size() == 11) { 169 Iterator it = models.iterator (); 170 while (it.hasNext ()) { 171 if (!(it.next() instanceof List )) break; 172 } 173 if (!it.hasNext()) { hasLists = true; 175 } 176 } 177 if (hasLists) { treeModels = (List ) models.get(0); 179 treeModelFilters = (List ) models.get(1); 180 revertOrder(treeModelFilters); 181 treeExpansionModels = (List ) models.get(2); 182 nodeModels = (List ) models.get(3); 183 nodeModelFilters = (List ) models.get(4); 184 revertOrder(nodeModelFilters); 185 tableModels = (List ) models.get(5); 186 tableModelFilters = (List ) models.get(6); 187 revertOrder(tableModelFilters); 188 nodeActionsProviders = (List ) models.get(7); 189 nodeActionsProviderFilters = (List ) models.get(8); 190 revertOrder(nodeActionsProviderFilters); 191 columnModels = (List ) models.get(9); 192 otherModels = (List ) models.get(10); 193 } else { treeModels = new LinkedList (); 195 treeModelFilters = new LinkedList (); 196 treeExpansionModels = new LinkedList (); 197 nodeModels = new LinkedList (); 198 nodeModelFilters = new LinkedList (); 199 tableModels = new LinkedList (); 200 tableModelFilters = new LinkedList (); 201 nodeActionsProviders = new LinkedList (); 202 nodeActionsProviderFilters = new LinkedList (); 203 columnModels = new LinkedList (); 204 otherModels = models; 205 } 206 207 Iterator it = otherModels.iterator (); 208 while (it.hasNext ()) { 209 Object model = it.next (); 210 boolean first = model.getClass ().getName ().endsWith ("First"); 211 if (model instanceof TreeModel) 212 treeModels.add(model); 213 if (model instanceof TreeModelFilter) 214 if (first) 215 treeModelFilters.add(model); 216 else 217 treeModelFilters.add(0, model); 218 if (model instanceof TreeExpansionModel) 219 treeExpansionModels.add(model); 220 if (model instanceof NodeModel) 221 nodeModels.add(model); 222 if (model instanceof NodeModelFilter) 223 if (first) 224 nodeModelFilters.add(model); 225 else 226 nodeModelFilters.add(0, model); 227 if (model instanceof TableModel) 228 tableModels.add(model); 229 if (model instanceof TableModelFilter) 230 if (first) 231 tableModelFilters.add(model); 232 else 233 tableModelFilters.add(0, model); 234 if (model instanceof NodeActionsProvider) 235 nodeActionsProviders.add(model); 236 if (model instanceof NodeActionsProviderFilter) 237 if (first) 238 nodeActionsProviderFilters.add(model); 239 else 240 nodeActionsProviderFilters.add(0, model); 241 if (model instanceof ColumnModel) 242 columnModels.add(model); 243 } 244 256 if (treeModels.isEmpty ()) { 257 treeModels = Collections.singletonList(new EmptyTreeModel ()); 258 } 259 if (treeExpansionModels.isEmpty()) { 260 TreeExpansionModel tem = (TreeExpansionModel) defaultExpansionModels.get(models); 261 if (tem == null) { 262 tem = new DefaultTreeExpansionModel(); 263 defaultExpansionModels.put(models, tem); 264 } 265 treeExpansionModels = Collections.singletonList(tem); 266 } 267 268 return new CompoundModel ( 269 createCompoundTreeModel ( 270 new DelegatingTreeModel (treeModels), 271 treeModelFilters 272 ), 273 new DelegatingTreeExpansionModel (treeExpansionModels), 274 createCompoundNodeModel ( 275 new DelegatingNodeModel (nodeModels), 276 nodeModelFilters 277 ), 278 createCompoundNodeActionsProvider ( 279 new DelegatingNodeActionsProvider (nodeActionsProviders), 280 nodeActionsProviderFilters 281 ), 282 columnModels, 283 createCompoundTableModel ( 284 new DelegatingTableModel (tableModels), 285 tableModelFilters 286 ), 287 propertiesHelpID 288 ); 289 } 290 291 private static void revertOrder(List filters) { 292 int n = filters.size(); 293 for (int i = 0; i < n; ) { 294 Object filter = filters.remove(i); 295 boolean first = filter.getClass ().getName ().endsWith ("First"); 296 if (first) { filters.add(filter); 298 n--; 299 } else { 300 filters.add(0, filter); 301 i++; 302 } 303 } 304 } 305 306 307 317 public static Action createAction ( 318 String displayName, 319 ActionPerformer performer, 320 int multiselectionType 321 ) { 322 return new ActionSupport ( 323 displayName, 324 performer, 325 multiselectionType 326 ); 327 } 328 329 337 public static TreeFeatures treeFeatures (JComponent view) 338 throws UnsupportedOperationException { 339 return new TreeFeatures (view); 340 } 341 342 343 345 354 private static TreeModel createCompoundTreeModel ( 355 TreeModel originalTreeModel, 356 List treeModelFilters 357 ) { 358 TreeModel tm = originalTreeModel; 359 int i, k = treeModelFilters.size (); 360 for (i = 0; i < k; i++) 361 tm = new CompoundTreeModel ( 362 tm, 363 (TreeModelFilter) treeModelFilters.get (i) 364 ); 365 return tm; 366 } 367 368 377 private static NodeModel createCompoundNodeModel ( 378 NodeModel originalNodeModel, 379 List treeNodeModelFilters 380 ) { 381 NodeModel nm = originalNodeModel; 382 int i, k = treeNodeModelFilters.size (); 383 for (i = 0; i < k; i++) 384 nm = new CompoundNodeModel ( 385 nm, 386 (NodeModelFilter) treeNodeModelFilters.get (i) 387 ); 388 return nm; 389 } 390 391 400 private static TableModel createCompoundTableModel ( 401 TableModel originalTableModel, 402 List tableModelFilters 403 ) { 404 TableModel tm = originalTableModel; 405 int i, k = tableModelFilters.size (); 406 for (i = 0; i < k; i++) 407 tm = new CompoundTableModel ( 408 tm, 409 (TableModelFilter) tableModelFilters.get (i) 410 ); 411 return tm; 412 } 413 414 423 private static NodeActionsProvider createCompoundNodeActionsProvider ( 424 NodeActionsProvider originalNodeActionsProvider, 425 List nodeActionsProviderFilters 426 ) { 427 NodeActionsProvider nap = originalNodeActionsProvider; 428 int i, k = nodeActionsProviderFilters.size (); 429 for (i = 0; i < k; i++) 430 nap = new CompoundNodeActionsProvider ( 431 nap, 432 (NodeActionsProviderFilter) nodeActionsProviderFilters.get (i) 433 ); 434 return nap; 435 } 436 437 438 440 443 private static class ActionSupport extends AbstractAction { 444 445 private ActionPerformer performer; 446 private int multiselectionType; 447 private String displayName; 448 449 450 ActionSupport ( 451 String displayName, 452 ActionPerformer performer, 453 int multiselectionType 454 ) { 455 super (displayName); 456 this.performer = performer; 457 this.displayName = displayName; 458 this.multiselectionType = multiselectionType; 459 } 460 461 public boolean isEnabled () { 462 if (multiselectionType == MULTISELECTION_TYPE_ANY) 463 return true; 464 Node[] ns = TopComponent.getRegistry ().getActivatedNodes (); 465 if (multiselectionType == MULTISELECTION_TYPE_EXACTLY_ONE) { 466 if (ns.length != 1) return false; 467 return performer.isEnabled ( 468 ns[0].getLookup().lookup(Object .class) 469 ); 470 } 471 int i, k = ns.length; 472 for (i = 0; i < k; i++) 473 if (!performer.isEnabled ( 474 ns[i].getLookup().lookup(Object .class) 475 )) return false; 476 return true; 477 } 478 479 public void actionPerformed (ActionEvent e) { 480 Node[] ns = TopComponent.getRegistry ().getActivatedNodes (); 481 int i, k = ns.length; 482 IdentityHashMap h = new IdentityHashMap (); 483 for (i = 0; i < k; i++) { 484 Object node = ns[i].getLookup().lookup(Object .class); 485 Action [] as = ns [i].getActions (false); 486 int j, jj = as.length; 487 for (j = 0; j < jj; j++) 488 if (equals (as [j])) { 489 ArrayList l = (ArrayList ) h.get (as [j]); 490 if (l == null) { 491 l = new ArrayList (); 492 h.put (as [j], l); 493 } 494 l.add (node); 495 } 496 } 497 Iterator it = h.keySet ().iterator (); 498 while (it.hasNext ()) { 499 ActionSupport a = (ActionSupport) it.next (); 500 a.performer.perform ( 501 ((ArrayList ) h.get (a)).toArray () 502 ); 503 } 504 } 505 506 public int hashCode () { 507 return displayName.hashCode (); 508 } 509 510 public boolean equals (Object o) { 511 return (o instanceof ActionSupport) && 512 displayName.equals (((ActionSupport) o).displayName); 513 } 514 } 515 516 520 public static interface ActionPerformer { 521 522 530 public boolean isEnabled (Object node); 531 532 540 public void perform (Object [] nodes); 541 } 542 543 549 final static class CompoundTreeModel implements TreeModel, ModelListener { 550 551 552 private TreeModel model; 553 private TreeModelFilter filter; 554 555 private Collection modelListeners = new HashSet (); 556 557 558 562 CompoundTreeModel (TreeModel model, TreeModelFilter filter) { 563 this.model = model; 564 this.filter = filter; 565 } 566 567 572 public Object getRoot () { 573 return filter.getRoot (model); 574 } 575 576 587 public Object [] getChildren (Object parent, int from, int to) 588 throws UnknownTypeException { 589 590 return filter.getChildren (model, parent, from, to); 591 } 592 593 604 public int getChildrenCount (Object node) throws UnknownTypeException { 605 return filter.getChildrenCount (model, node); 606 } 607 608 615 public boolean isLeaf (Object node) throws UnknownTypeException { 616 return filter.isLeaf (model, node); 617 } 618 619 624 public void addModelListener (ModelListener l) { 625 synchronized (modelListeners) { 626 if (modelListeners.size() == 0) { 627 filter.addModelListener (this); 628 model.addModelListener (this); 629 } 630 modelListeners.add(l); 631 } 632 } 633 634 639 public void removeModelListener (ModelListener l) { 640 synchronized (modelListeners) { 641 modelListeners.remove(l); 642 if (modelListeners.size() == 0) { 643 filter.removeModelListener (this); 644 model.removeModelListener (this); 645 } 646 } 647 } 648 649 public void modelChanged(ModelEvent event) { 650 ModelEvent newEvent = translateEvent(event, this); 651 Collection listeners; 652 synchronized (modelListeners) { 653 listeners = new ArrayList (modelListeners); 654 } 655 for (Iterator it = listeners.iterator(); it.hasNext(); ) { 656 ((ModelListener) it.next()).modelChanged(newEvent); 657 } 658 } 659 660 public String toString () { 661 return super.toString () + "\n" + toString (" "); 662 } 663 664 public String toString (String n) { 665 if (model instanceof CompoundTreeModel) 666 return n + filter + "\n" + 667 ((CompoundTreeModel) model).toString (n + " "); 668 return n + filter + "\n" + 669 n + " " + model; 670 } 671 672 } 673 674 private static ModelEvent translateEvent(ModelEvent event, Object newSource) { 675 ModelEvent newEvent; 676 if (event instanceof ModelEvent.NodeChanged) { 677 newEvent = new ModelEvent.NodeChanged(newSource, 678 ((ModelEvent.NodeChanged) event).getNode(), 679 ((ModelEvent.NodeChanged) event).getChange()); 680 } else if (event instanceof ModelEvent.TableValueChanged) { 681 newEvent = new ModelEvent.TableValueChanged(newSource, 682 ((ModelEvent.TableValueChanged) event).getNode(), 683 ((ModelEvent.TableValueChanged) event).getColumnID()); 684 } else if (event instanceof ModelEvent.TreeChanged) { 685 newEvent = new ModelEvent.TreeChanged(newSource); 686 } else { 687 newEvent = event; 688 } 689 return newEvent; 690 } 691 692 698 final static class CompoundNodeModel implements NodeModel, ModelListener { 699 700 701 private NodeModel model; 702 private NodeModelFilter filter; 703 704 private Collection modelListeners = new HashSet (); 705 706 707 711 CompoundNodeModel (NodeModel model, NodeModelFilter filter) { 712 this.model = model; 713 this.filter = filter; 714 } 715 716 723 public String getDisplayName (Object node) 724 throws UnknownTypeException { 725 return filter.getDisplayName (model, node); 726 } 727 728 735 public String getIconBase (Object node) 736 throws UnknownTypeException { 737 return filter.getIconBase (model, node); 738 } 739 740 747 public String getShortDescription (Object node) 748 throws UnknownTypeException { 749 return filter.getShortDescription (model, node); 750 } 751 752 753 758 public void addModelListener (ModelListener l) { 759 synchronized (modelListeners) { 760 if (modelListeners.size() == 0) { 761 filter.addModelListener (this); 762 model.addModelListener (this); 763 } 764 modelListeners.add(l); 765 } 766 } 767 768 773 public void removeModelListener (ModelListener l) { 774 synchronized (modelListeners) { 775 modelListeners.remove(l); 776 if (modelListeners.size() == 0) { 777 filter.removeModelListener (this); 778 model.removeModelListener (this); 779 } 780 } 781 } 782 783 public void modelChanged(ModelEvent event) { 784 ModelEvent newEvent = translateEvent(event, this); 785 Collection listeners; 786 synchronized (modelListeners) { 787 listeners = new ArrayList (modelListeners); 788 } 789 for (Iterator it = listeners.iterator(); it.hasNext(); ) { 790 ((ModelListener) it.next()).modelChanged(newEvent); 791 } 792 } 793 794 public String toString () { 795 return super.toString () + "\n" + toString (" "); 796 } 797 798 public String toString (String n) { 799 if (model instanceof CompoundNodeModel) 800 return n + filter + "\n" + 801 ((CompoundNodeModel) model).toString (n + " "); 802 if (model instanceof DelegatingNodeModel) 803 return n + filter + "\n" + 804 ((DelegatingNodeModel) model).toString (n + " "); 805 return n + filter + "\n" + 806 n + " " + model; 807 } 808 } 809 810 816 final static class CompoundTableModel implements TableModel, ModelListener { 817 818 819 private TableModel model; 820 private TableModelFilter filter; 821 822 private Collection modelListeners = new HashSet (); 823 824 825 829 CompoundTableModel (TableModel model, TableModelFilter filter) { 830 this.model = model; 831 this.filter = filter; 832 } 833 834 847 public Object getValueAt (Object node, String columnID) throws 848 UnknownTypeException { 849 return filter.getValueAt (model, node, columnID); 850 } 851 852 865 public boolean isReadOnly (Object node, String columnID) throws 866 UnknownTypeException { 867 return filter.isReadOnly (model, node, columnID); 868 } 869 870 882 public void setValueAt (Object node, String columnID, Object value) 883 throws UnknownTypeException { 884 filter.setValueAt (model, node, columnID, value); 885 } 886 887 892 public void addModelListener (ModelListener l) { 893 synchronized (modelListeners) { 894 if (modelListeners.size() == 0) { 895 filter.addModelListener (this); 896 model.addModelListener (this); 897 } 898 modelListeners.add(l); 899 } 900 } 901 902 907 public void removeModelListener (ModelListener l) { 908 synchronized (modelListeners) { 909 modelListeners.remove(l); 910 if (modelListeners.size() == 0) { 911 filter.removeModelListener (this); 912 model.removeModelListener (this); 913 } 914 } 915 } 916 917 public void modelChanged(ModelEvent event) { 918 ModelEvent newEvent = translateEvent(event, this); 919 Collection listeners; 920 synchronized (modelListeners) { 921 listeners = new ArrayList (modelListeners); 922 } 923 for (Iterator it = listeners.iterator(); it.hasNext(); ) { 924 ((ModelListener) it.next()).modelChanged(newEvent); 925 } 926 } 927 928 public String toString () { 929 return super.toString () + "\n" + toString (" "); 930 } 931 932 public String toString (String n) { 933 if (model instanceof CompoundTableModel) 934 return n + filter + "\n" + 935 ((CompoundTableModel) model).toString (n + " "); 936 if (model instanceof DelegatingTableModel) 937 return n + filter + "\n" + 938 ((DelegatingTableModel) model).toString (n + " "); 939 return n + filter + "\n" + 940 n + " " + model; 941 } 942 } 943 944 951 final static class DelegatingTreeModel implements TreeModel { 952 953 private TreeModel[] models; 954 private HashMap classNameToModel = new HashMap (); 955 956 957 963 DelegatingTreeModel (List models) { 964 this (convert (models)); 965 } 966 967 private static TreeModel[] convert (List l) { 968 TreeModel[] models = new TreeModel [l.size ()]; 969 return (TreeModel[]) l.toArray (models); 970 } 971 972 978 DelegatingTreeModel (TreeModel[] models) { 979 this.models = models; 980 } 981 982 987 public Object getRoot () { 988 return models [0].getRoot (); 989 } 990 991 1003 public Object [] getChildren (Object node, int from, int to) 1004 throws UnknownTypeException { 1005 TreeModel model = (TreeModel) classNameToModel.get ( 1006 node.getClass ().getName () 1007 ); 1008 if (model != null) 1009 try { 1010 return model.getChildren (node, from, to); 1011 } catch (UnknownTypeException e) { 1012 } 1013 int i, k = models.length; 1014 for (i = 0; i < k; i++) { 1015 try { 1016 Object [] v = models [i].getChildren (node, from, to); 1017 classNameToModel.put (node.getClass ().getName (), models [i]); 1018 return v; 1019 } catch (UnknownTypeException e) { 1020 } 1021 } 1022 throw new UnknownTypeException (node); 1023 } 1024 1025 1035 public int getChildrenCount (Object node) 1036 throws UnknownTypeException { 1037 TreeModel model = (TreeModel) classNameToModel.get ( 1038 node.getClass ().getName () 1039 ); 1040 if (model != null) 1041 try { 1042 return model.getChildrenCount (node); 1043 } catch (UnknownTypeException e) { 1044 } 1045 int i, k = models.length; 1046 for (i = 0; i < k; i++) { 1047 try { 1048 int result = models [i].getChildrenCount (node); 1049 classNameToModel.put (node.getClass ().getName (), models [i]); 1050 return result; 1051 } catch (UnknownTypeException e) { 1052 } 1053 } 1054 throw new UnknownTypeException (node); 1055 } 1056 1057 1064 public boolean isLeaf (Object node) throws UnknownTypeException { 1065 TreeModel model = (TreeModel) classNameToModel.get ( 1066 node.getClass ().getName () 1067 ); 1068 if (model != null) 1069 try { 1070 return model.isLeaf (node); 1071 } catch (UnknownTypeException e) { 1072 } 1073 int i, k = models.length; 1074 for (i = 0; i < k; i++) { 1075 try { 1076 boolean result = models [i].isLeaf (node); 1077 classNameToModel.put (node.getClass ().getName (), models [i]); 1078 return result; 1079 } catch (UnknownTypeException e) { 1080 } 1081 } 1082 throw new UnknownTypeException (node); 1083 } 1084 1085 1090 public void addModelListener (ModelListener l) { 1091 int i, k = models.length; 1092 for (i = 0; i < k; i++) 1093 models [i].addModelListener (l); 1094 } 1095 1096 1101 public void removeModelListener (ModelListener l) { 1102 int i, k = models.length; 1103 for (i = 0; i < k; i++) 1104 models [i].removeModelListener (l); 1105 } 1106 1107 public String toString () { 1108 return super.toString () + "\n" + toString (" "); 1109 } 1110 1111 public String toString (String n) { 1112 int i, k = models.length - 1; 1113 if (k == -1) return ""; 1114 StringBuffer sb = new StringBuffer (); 1115 for (i = 0; i < k; i++) { 1116 sb.append (n); 1117 sb.append (models [i]); 1118 sb.append ('\n'); 1119 } 1120 sb.append (n); 1121 sb.append (models [i]); 1122 return new String (sb); 1123 } 1124 } 1125 1126 1133 final static class CompoundNodeActionsProvider 1134 implements NodeActionsProvider { 1135 1136 1137 private NodeActionsProvider model; 1138 private NodeActionsProviderFilter filter; 1139 1140 1141 1146 CompoundNodeActionsProvider ( 1147 NodeActionsProvider model, 1148 NodeActionsProviderFilter filter 1149 ) { 1150 this.model = model; 1151 this.filter = filter; 1152 } 1153 1154 1162 public void performDefaultAction (Object node) 1163 throws UnknownTypeException { 1164 filter.performDefaultAction (model, node); 1165 } 1166 1167 1174 public Action [] getActions (Object node) 1175 throws UnknownTypeException { 1176 return filter.getActions (model, node); 1177 } 1178 1179 public String toString () { 1180 return super.toString () + "\n" + toString (" "); 1181 } 1182 1183 public String toString (String n) { 1184 if (model instanceof CompoundNodeActionsProvider) 1185 return n + filter + "\n" + 1186 ((CompoundNodeActionsProvider) model).toString (n + " "); 1187 if (model instanceof DelegatingNodeActionsProvider) 1188 return n + filter + "\n" + 1189 ((DelegatingNodeActionsProvider) model).toString (n + " "); 1190 return n + filter + "\n" + 1191 n + " " + model; 1192 } 1193 } 1194 1195 1202 final static class DelegatingTableModel implements TableModel { 1203 1204 private TableModel[] models; 1205 private HashMap classNameToModel = new HashMap (); 1206 1207 1208 1214 DelegatingTableModel (List models) { 1215 this (convert (models)); 1216 } 1217 1218 private static TableModel[] convert (List l) { 1219 TableModel[] models = new TableModel [l.size ()]; 1220 return (TableModel[]) l.toArray (models); 1221 } 1222 1223 1229 DelegatingTableModel (TableModel[] models) { 1230 this.models = models; 1231 } 1232 1233 1246 public Object getValueAt (Object node, String columnID) 1247 throws UnknownTypeException { 1248 TableModel model = (TableModel) classNameToModel.get ( 1249 node.getClass ().getName () 1250 ); 1251 if (model != null) 1252 try { 1253 return model.getValueAt (node, columnID); 1254 } catch (UnknownTypeException e) { 1255 } 1256 int i, k = models.length; 1257 for (i = 0; i < k; i++) { 1258 try { 1259 Object v = models [i].getValueAt (node, columnID); 1260 classNameToModel.put (node.getClass ().getName (), models [i]); 1261 return v; 1262 } catch (UnknownTypeException e) { 1263 } 1264 } 1265 throw new UnknownTypeException (node); 1266 } 1267 1268 1281 public boolean isReadOnly (Object node, String columnID) throws 1282 UnknownTypeException { 1283 TableModel model = (TableModel) classNameToModel.get ( 1284 node.getClass ().getName () 1285 ); 1286 if (model != null) 1287 try { 1288 return model.isReadOnly (node, columnID); 1289 } catch (UnknownTypeException e) { 1290 } 1291 int i, k = models.length; 1292 for (i = 0; i < k; i++) { 1293 try { 1294 boolean ro = models [i].isReadOnly (node, columnID); 1295 classNameToModel.put (node.getClass ().getName (), models [i]); 1296 return ro; 1297 } catch (UnknownTypeException e) { 1298 } 1299 } 1300 throw new UnknownTypeException (node); 1301 } 1302 1303 1315 public void setValueAt (Object node, String columnID, Object value) 1316 throws UnknownTypeException { 1317 TableModel model = (TableModel) classNameToModel.get ( 1318 node.getClass ().getName () 1319 ); 1320 if (model != null) 1321 try { 1322 model.setValueAt (node, columnID, value); 1323 return; 1324 } catch (UnknownTypeException e) { 1325 } 1326 int i, k = models.length; 1327 for (i = 0; i < k; i++) { 1328 try { 1329 models [i].setValueAt (node, columnID, value); 1330 classNameToModel.put (node.getClass ().getName (), models [i]); 1331 return; 1332 } catch (UnknownTypeException e) { 1333 } 1334 } 1335 throw new UnknownTypeException (node); 1336 } 1337 1338 1343 public void addModelListener (ModelListener l) { 1344 int i, k = models.length; 1345 for (i = 0; i < k; i++) 1346 models [i].addModelListener (l); 1347 } 1348 1349 1354 public void removeModelListener (ModelListener l) { 1355 int i, k = models.length; 1356 for (i = 0; i < k; i++) 1357 models [i].removeModelListener (l); 1358 } 1359 1360 public String toString () { 1361 return super.toString () + "\n" + toString (" "); 1362 } 1363 1364 public String toString (String n) { 1365 int i, k = models.length - 1; 1366 if (k == -1) return ""; 1367 StringBuffer sb = new StringBuffer (); 1368 for (i = 0; i < k; i++) { 1369 sb.append (n); 1370 sb.append (models [i]); 1371 sb.append ('\n'); 1372 } 1373 sb.append (n); 1374 sb.append (models [i]); 1375 return new String (sb); 1376 } 1377 } 1378 1379 1386 final static class DelegatingTreeExpansionModel 1387 implements TreeExpansionModel { 1388 1389 private TreeExpansionModel[] models; 1390 private HashMap classNameToModel = new HashMap (); 1391 1392 1393 1399 DelegatingTreeExpansionModel (List models) { 1400 this (convert (models)); 1401 } 1402 1403 private static TreeExpansionModel[] convert (List l) { 1404 TreeExpansionModel[] models = new TreeExpansionModel [l.size()]; 1405 return (TreeExpansionModel[]) l.toArray (models); 1406 } 1407 1408 1414 private DelegatingTreeExpansionModel (TreeExpansionModel[] models) { 1415 this.models = models; 1416 } 1417 1418 1424 public boolean isExpanded (Object node) 1425 throws UnknownTypeException { 1426 TreeExpansionModel model = (TreeExpansionModel) 1427 classNameToModel.get ( 1428 node.getClass ().getName () 1429 ); 1430 if (model != null) 1431 try { 1432 return model.isExpanded (node); 1433 } catch (UnknownTypeException e) { 1434 } 1435 int i, k = models.length; 1436 for (i = 0; i < k; i++) { 1437 try { 1438 boolean result = models [i].isExpanded (node); 1439 classNameToModel.put (node.getClass ().getName (), models [i]); 1440 return result; 1441 } catch (UnknownTypeException e) { 1442 } 1443 } 1444 throw new UnknownTypeException (node); 1445 } 1446 1447 1448 1453 public void nodeExpanded (Object node) { 1454 int i, k = models.length; 1455 for (i = 0; i < k; i++) { 1456 models [i].nodeExpanded (node); 1457 } 1458 } 1459 1460 1465 public void nodeCollapsed (Object node) { 1466 int i, k = models.length; 1467 for (i = 0; i < k; i++) { 1468 models [i].nodeCollapsed (node); 1469 } 1470 } 1471 1472 public String toString () { 1473 return super.toString () + "\n" + toString (" "); 1474 } 1475 1476 public String toString (String n) { 1477 int i, k = models.length - 1; 1478 if (k == -1) return ""; 1479 StringBuffer sb = new StringBuffer (); 1480 for (i = 0; i < k; i++) { 1481 sb.append (n); 1482 sb.append (models [i]); 1483 sb.append ('\n'); 1484 } 1485 sb.append (n); 1486 sb.append (models [i]); 1487 return new String (sb); 1488 } 1489 } 1490 1491 private static class DefaultTreeExpansionModel implements TreeExpansionModel { 1492 1493 private Set expandedNodes = new WeakSet(); 1494 private Set collapsedNodes = new WeakSet(); 1495 1496 1502 public boolean isExpanded (Object node) 1503 throws UnknownTypeException { 1504 synchronized (this) { 1505 if (expandedNodes.contains(node)) { 1506 return true; 1507 } 1508 if (collapsedNodes.contains(node)) { 1509 return false; 1510 } 1511 } 1512 return false; 1514 } 1515 1516 1521 public void nodeExpanded (Object node) { 1522 synchronized (this) { 1523 expandedNodes.add(node); 1524 collapsedNodes.remove(node); 1525 } 1526 } 1527 1528 1533 public void nodeCollapsed (Object node) { 1534 synchronized (this) { 1535 collapsedNodes.add(node); 1536 expandedNodes.remove(node); 1537 } 1538 } 1539 1540 } 1541 1542 1549 static final class DelegatingNodeModel implements NodeModel { 1550 1551 private NodeModel[] models; 1552 private HashMap classNameToModel = new HashMap (); 1553 1554 1555 1561 DelegatingNodeModel ( 1562 List models 1563 ) { 1564 this (convert (models)); 1565 } 1566 1567 private static NodeModel[] convert (List l) { 1568 NodeModel[] models = new NodeModel [l.size ()]; 1569 return (NodeModel[]) l.toArray (models); 1570 } 1571 1572 1578 DelegatingNodeModel ( 1579 NodeModel[] models 1580 ) { 1581 this.models = models; 1582 1583 } 1584 1585 NodeModel[] getModels() { 1586 return models; 1587 } 1588 1589 1596 public String getDisplayName (Object node) 1597 throws UnknownTypeException { 1598 NodeModel model = (NodeModel) classNameToModel.get ( 1599 node.getClass ().getName () 1600 ); 1601 if (model != null) 1602 try { 1603 return model.getDisplayName (node); 1604 } catch (UnknownTypeException e) { 1605 } 1606 int i, k = models.length; 1607 for (i = 0; i < k; i++) { 1608 try { 1609 String dn = models [i].getDisplayName (node); 1610 classNameToModel.put (node.getClass ().getName (), models [i]); 1611 return dn; 1612 } catch (UnknownTypeException e) { 1613 } 1614 } 1615 throw new UnknownTypeException (node); 1616 } 1617 1618 1625 public String getShortDescription (Object node) 1626 throws UnknownTypeException { 1627 NodeModel model = (NodeModel) classNameToModel.get ( 1628 node.getClass ().getName () 1629 ); 1630 if (model != null) 1631 try { 1632 return model.getShortDescription (node); 1633 } catch (UnknownTypeException e) { 1634 } 1635 int i, k = models.length; 1636 for (i = 0; i < k; i++) { 1637 try { 1638 String dn = models [i].getShortDescription (node); 1639 classNameToModel.put (node.getClass ().getName (), models [i]); 1640 return dn; 1641 } catch (UnknownTypeException e) { 1642 } 1643 } 1644 throw new UnknownTypeException (node); 1645 } 1646 1647 1654 public String getIconBase (Object node) 1655 throws UnknownTypeException { 1656 NodeModel model = (NodeModel) classNameToModel.get ( 1657 node.getClass ().getName () 1658 ); 1659 if (model != null) 1660 try { 1661 return model.getIconBase (node); 1662 } catch (UnknownTypeException e) { 1663 } 1664 int i, k = models.length; 1665 for (i = 0; i < k; i++) { 1666 try { 1667 String dn = models [i].getIconBase (node); 1668 classNameToModel.put (node.getClass ().getName (), models [i]); 1669 return dn; 1670 } catch (UnknownTypeException e) { 1671 } 1672 } 1673 throw new UnknownTypeException (node); 1674 } 1675 1676 1681 public void addModelListener (ModelListener l) { 1682 int i, k = models.length; 1683 for (i = 0; i < k; i++) 1684 models [i].addModelListener (l); 1685 } 1686 1687 1692 public void removeModelListener (ModelListener l) { 1693 int i, k = models.length; 1694 for (i = 0; i < k; i++) 1695 models [i].removeModelListener (l); 1696 } 1697 1698 public String toString () { 1699 return toString (" "); 1700 } 1701 1702 public String toString (String n) { 1703 int i, k = models.length - 1; 1704 if (k == -1) return ""; 1705 StringBuffer sb = new StringBuffer (); 1706 for (i = 0; i < k; i++) { 1707 sb.append (n); 1708 sb.append (models [i]); 1709 sb.append ('\n'); 1710 } 1711 sb.append (n); 1712 sb.append (models [i]); 1713 return new String (sb); 1714 } 1715 } 1716 1717 1722 private static final class EmptyTreeModel implements TreeModel { 1723 1724 1729 public Object getRoot () { 1730 return ROOT; 1731 } 1732 1733 1738 public Object [] getChildren (Object parent, int from, int to) { 1739 return new Object [0]; 1740 } 1741 1742 1751 public int getChildrenCount (Object node) { 1752 return 0; 1753 } 1754 1755 1760 public boolean isLeaf (Object node) { 1761 return false; 1762 } 1763 1764 1769 public void addModelListener (ModelListener l) { 1770 } 1771 1772 1777 public void removeModelListener (ModelListener l) { 1778 } 1779 } 1780 1781 1786 private static final class EmptyNodeModel implements NodeModel { 1787 1788 1795 public String getDisplayName (Object node) 1796 throws UnknownTypeException { 1797 throw new UnknownTypeException (node); 1798 } 1799 1800 1807 public String getIconBase (Object node) 1808 throws UnknownTypeException { 1809 throw new UnknownTypeException (node); 1810 } 1811 1812 1819 public String getShortDescription (Object node) 1820 throws UnknownTypeException { 1821 throw new UnknownTypeException (node); 1822 } 1823 1824 1829 public void addModelListener (ModelListener l) { 1830 } 1831 1832 1837 public void removeModelListener (ModelListener l) { 1838 } 1839 } 1840 1841 1846 private static final class EmptyTableModel implements TableModel { 1847 1848 1862 public Object getValueAt (Object node, String columnID) throws 1863 UnknownTypeException { 1864 throw new UnknownTypeException (node); 1865 } 1866 1867 1880 public boolean isReadOnly (Object node, String columnID) throws 1881 UnknownTypeException { 1882 throw new UnknownTypeException (node); 1883 } 1884 1885 1897 public void setValueAt (Object node, String columnID, Object value) 1898 throws UnknownTypeException { 1899 throw new UnknownTypeException (node); 1900 } 1901 1902 1907 public void addModelListener (ModelListener l) { 1908 } 1909 1910 1915 public void removeModelListener (ModelListener l) { 1916 } 1917 } 1918 1919 1924 private static final class EmptyNodeActionsProvider implements 1925 NodeActionsProvider { 1926 1927 1934 public void performDefaultAction (Object node) 1935 throws UnknownTypeException { 1936 throw new UnknownTypeException (node); 1937 } 1938 1939 1946 public Action [] getActions (Object node) 1947 throws UnknownTypeException { 1948 throw new UnknownTypeException (node); 1949 } 1950 } 1951 1952 1960 static final class DelegatingNodeActionsProvider implements NodeActionsProvider { 1961 1962 private NodeActionsProvider[] models; 1963 private HashMap classNameToModel = new HashMap (); 1964 1965 1966 1972 public DelegatingNodeActionsProvider ( 1973 List models 1974 ) { 1975 this (convert (models)); 1976 } 1977 1978 private static NodeActionsProvider[] convert (List l) { 1979 NodeActionsProvider[] models = new NodeActionsProvider [l.size ()]; 1980 return (NodeActionsProvider[]) l.toArray (models); 1981 } 1982 1983 1989 public DelegatingNodeActionsProvider (NodeActionsProvider[] models) { 1990 this.models = models; 1991 } 1992 1993 2000 public Action [] getActions (Object node) 2001 throws UnknownTypeException { 2002 NodeActionsProvider model = (NodeActionsProvider) classNameToModel.get ( 2003 node.getClass ().getName () 2004 ); 2005 if (model != null) 2006 try { 2007 return model.getActions (node); 2008 } catch (UnknownTypeException e) { 2009 } 2010 int i, k = models.length; 2011 for (i = 0; i < k; i++) { 2012 try { 2013 Action [] dn = models [i].getActions (node); 2014 classNameToModel.put (node.getClass ().getName (), models [i]); 2015 return dn; 2016 } catch (UnknownTypeException e) { 2017 } 2018 } 2019 throw new UnknownTypeException (node); 2020 } 2021 2022 2029 public void performDefaultAction (Object node) throws UnknownTypeException { 2030 NodeActionsProvider model = (NodeActionsProvider) classNameToModel.get ( 2031 node.getClass ().getName () 2032 ); 2033 if (model != null) 2034 try { 2035 model.performDefaultAction (node); 2036 return; 2037 } catch (UnknownTypeException e) { 2038 } 2039 int i, k = models.length; 2040 for (i = 0; i < k; i++) { 2041 try { 2042 models [i].performDefaultAction (node); 2043 classNameToModel.put (node.getClass ().getName (), models [i]); 2044 return; 2045 } catch (UnknownTypeException e) { 2046 } 2047 } 2048 throw new UnknownTypeException (node); 2049 } 2050 2051 public String toString () { 2052 return super.toString () + "\n" + toString (" "); 2053 } 2054 2055 public String toString (String n) { 2056 int i, k = models.length - 1; 2057 if (k == -1) return ""; 2058 StringBuffer sb = new StringBuffer (); 2059 for (i = 0; i < k; i++) { 2060 sb.append (n); 2061 sb.append (models [i]); 2062 sb.append ('\n'); 2063 } 2064 sb.append (n); 2065 sb.append (models [i]); 2066 return new String (sb); 2067 } 2068 } 2069 2070 2073 public static final class TreeFeatures { 2074 2075 private JComponent view; 2076 2077 private TreeFeatures (JComponent view) { 2078 this.view = view; 2079 } 2080 2081 2087 public boolean isExpanded ( 2088 Object node 2089 ) { 2090 return ((TreeTable) view).isExpanded (node); 2091 } 2092 2093 2098 public void expandNode ( 2099 Object node 2100 ) { 2101 ((TreeTable) view).expandNode (node); 2102 } 2103 2104 2109 public void collapseNode ( 2110 Object node 2111 ) { 2112 ((TreeTable) view).collapseNode (node); 2113 } 2114 } 2115 2116 2122 public static final class CompoundModel implements TreeModel, 2123 NodeModel, NodeActionsProvider, TableModel, TreeExpansionModel { 2124 2125 private TreeModel treeModel; 2126 private NodeModel nodeModel; 2127 private NodeActionsProvider nodeActionsProvider; 2128 private ColumnModel[] columnModels; 2129 private TableModel tableModel; 2130 private TreeExpansionModel treeExpansionModel; 2131 2132 private String propertiesHelpID = null; 2136 2138 2140 2148 private CompoundModel ( 2149 TreeModel treeModel, 2150 TreeExpansionModel treeExpansionModel, 2151 NodeModel nodeModel, 2152 NodeActionsProvider nodeActionsProvider, 2153 List columnModels, 2154 TableModel tableModel, 2155 String propertiesHelpID 2156 ) { 2157 if (treeModel == null) throw new NullPointerException (); 2158 if (treeModel == null) throw new NullPointerException (); 2159 if (nodeModel == null) throw new NullPointerException (); 2160 if (tableModel == null) throw new NullPointerException (); 2161 if (nodeActionsProvider == null) throw new NullPointerException (); 2162 2163 this.treeModel = treeModel; 2164 this.treeExpansionModel = treeExpansionModel; 2165 this.nodeModel = nodeModel; 2166 this.tableModel = tableModel; 2167 this.nodeActionsProvider = nodeActionsProvider; 2168 this.columnModels = (ColumnModel[]) columnModels.toArray ( 2169 new ColumnModel [columnModels.size ()] 2170 ); 2171 this.propertiesHelpID = propertiesHelpID; 2172 } 2173 2174 2181 public String getHelpId() { 2182 return propertiesHelpID; 2183 } 2184 2186 2188 2193 public Object getRoot () { 2194 return treeModel.getRoot (); 2195 } 2196 2197 2206 public Object [] getChildren (Object parent, int from, int to) 2207 throws UnknownTypeException { 2208 return treeModel.getChildren (parent, from, to); 2209 } 2210 2211 2220 public int getChildrenCount (Object node) throws UnknownTypeException { 2221 return treeModel.getChildrenCount (node); 2222 } 2223 2224 2231 public boolean isLeaf (Object node) throws UnknownTypeException { 2232 return treeModel.isLeaf (node); 2233 } 2234 2235 2236 2238 2245 public String getDisplayName (Object node) throws UnknownTypeException { 2246 if (nodeModel instanceof DelegatingNodeModel) { 2247 NodeModel[] subModels = ((DelegatingNodeModel) nodeModel).getModels(); 2248 if (subModels.length == 0) { 2249 return ""; } 2251 } 2252 return nodeModel.getDisplayName (node); 2253 } 2254 2255 2262 public String getShortDescription (Object node) 2263 throws UnknownTypeException { 2264 return nodeModel.getShortDescription (node); 2265 } 2266 2267 2274 public String getIconBase (Object node) 2275 throws UnknownTypeException { 2276 if (nodeModel instanceof DelegatingNodeModel) { 2277 NodeModel[] subModels = ((DelegatingNodeModel) nodeModel).getModels(); 2278 if (subModels.length == 0) { 2279 return null; } 2281 } 2282 return nodeModel.getIconBase (node); 2283 } 2284 2285 2286 2288 2295 public void performDefaultAction (Object node) throws UnknownTypeException { 2296 nodeActionsProvider.performDefaultAction (node); 2297 } 2298 2299 2306 public Action [] getActions (Object node) throws UnknownTypeException { 2307 return nodeActionsProvider.getActions (node); 2308 } 2309 2310 2311 2313 2319 public ColumnModel[] getColumns () { 2320 return columnModels; 2321 } 2322 2323 2324 2326 public Object getValueAt (Object node, String columnID) throws 2327 UnknownTypeException { 2328 return tableModel.getValueAt (node, columnID); 2329 } 2330 2331 public boolean isReadOnly (Object node, String columnID) throws 2332 UnknownTypeException { 2333 return tableModel.isReadOnly (node, columnID); 2334 } 2335 2336 public void setValueAt (Object node, String columnID, Object value) throws 2337 UnknownTypeException { 2338 tableModel.setValueAt (node, columnID, value); 2339 } 2340 2341 2342 2344 2350 public boolean isExpanded (Object node) throws UnknownTypeException { 2351 if (treeExpansionModel == null) return false; 2352 return treeExpansionModel.isExpanded (node); 2353 } 2354 2355 2360 public void nodeExpanded (Object node) { 2361 if (treeExpansionModel != null) 2362 treeExpansionModel.nodeExpanded (node); 2363 } 2364 2365 2370 public void nodeCollapsed (Object node) { 2371 if (treeExpansionModel != null) 2372 treeExpansionModel.nodeCollapsed (node); 2373 } 2374 2375 2376 2378 2383 public void addModelListener (ModelListener l) { 2384 treeModel.addModelListener (l); 2385 if (nodeModel != treeModel) { 2386 nodeModel.addModelListener (l); 2387 } 2388 if (tableModel != treeModel && tableModel != nodeModel) { 2389 tableModel.addModelListener (l); 2390 } 2391 } 2392 2393 2398 public void removeModelListener (ModelListener l) { 2399 treeModel.removeModelListener (l); 2400 if (nodeModel != treeModel) { 2401 nodeModel.removeModelListener (l); 2402 } 2403 if (tableModel != treeModel && tableModel != nodeModel) { 2404 tableModel.removeModelListener (l); 2405 } 2406 } 2407 2408 public String toString () { 2409 return super.toString () + 2410 "\n TreeModel = " + treeModel + 2411 "\n NodeModel = " + nodeModel + 2412 "\n TableModel = " + tableModel + 2413 "\n NodeActionsProvider = " + nodeActionsProvider + 2414 "\n ColumnsModel = " + java.util.Arrays.asList(columnModels); 2415 } 2416 } 2417} 2418 | Popular Tags |