1 19 20 package org.openide.windows; 21 22 import java.awt.EventQueue ; 23 import java.awt.Image ; 24 import java.awt.Toolkit ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 import java.awt.event.KeyEvent ; 28 import java.beans.PropertyChangeEvent ; 29 import java.beans.PropertyChangeListener ; 30 import java.io.Externalizable ; 31 import java.io.IOException ; 32 import java.io.ObjectInput ; 33 import java.io.ObjectInputStream ; 34 import java.io.ObjectOutput ; 35 import java.io.ObjectOutputStream ; 36 import java.io.ObjectStreamException ; 37 import java.io.Serializable ; 38 import java.lang.ref.Reference ; 39 import java.lang.ref.WeakReference ; 40 import java.lang.reflect.InvocationTargetException ; 41 import java.lang.reflect.Method ; 42 import java.util.ArrayList ; 43 import java.util.Arrays ; 44 import java.util.Collection ; 45 import java.util.List ; 46 import java.util.Set ; 47 import java.util.logging.Level ; 48 import java.util.logging.LogRecord ; 49 import java.util.logging.Logger ; 50 import javax.accessibility.Accessible ; 51 import javax.accessibility.AccessibleContext ; 52 import javax.accessibility.AccessibleRole ; 53 import javax.swing.Action ; 54 import javax.swing.ActionMap ; 55 import javax.swing.JComponent ; 56 import javax.swing.KeyStroke ; 57 import javax.swing.SwingUtilities ; 58 import javax.swing.Timer ; 59 import javax.swing.plaf.basic.BasicHTML ; 60 import javax.swing.text.Keymap ; 61 import org.openide.awt.UndoRedo; 62 import org.openide.nodes.Node; 63 import org.openide.nodes.NodeAdapter; 64 import org.openide.nodes.NodeListener; 65 import org.openide.util.ContextAwareAction; 66 import org.openide.util.HelpCtx; 67 import org.openide.util.Lookup; 68 import org.openide.util.NbBundle; 69 import org.openide.util.Utilities; 70 import org.openide.util.WeakListeners; 71 import org.openide.util.WeakSet; 72 import org.openide.util.actions.SystemAction; 73 74 89 public class TopComponent extends JComponent implements Externalizable , Accessible , HelpCtx.Provider, Lookup.Provider { 90 91 private static Logger UILOG = Logger.getLogger("org.netbeans.ui.actions"); 93 static final long serialVersionUID = -3022538025284122942L; 94 95 static final Logger LOG = Logger.getLogger(TopComponent.class.getName()); 96 97 104 @Deprecated 105 public static final int CLOSE_EACH = 0; 106 107 115 @Deprecated 116 public static final int CLOSE_LAST = 1; 117 118 119 public static final int PERSISTENCE_ALWAYS = 0; 120 121 123 public static final int PERSISTENCE_ONLY_OPENED = 1; 124 125 126 public static final int PERSISTENCE_NEVER = 2; 127 128 129 private static Object defaultLookupLock = new Object (); 130 131 132 private static final Set <Class > warnedTCPIClasses = new WeakSet<Class >(); 133 134 135 private static final Set <Class > warnedClasses = new WeakSet<Class >(); 136 137 140 private Object defaultLookupRef; 141 142 143 private NodeName nodeName; 144 145 147 148 private int closeOperation = CLOSE_LAST; 149 150 151 private transient Image icon; 152 153 154 private transient Node[] activatedNodes; 155 156 157 private transient String displayName; 158 159 161 private String htmlDisplayName; 162 163 166 short serialVersion = 1; 167 private AttentionGetter attentionGetter = null; 168 169 170 172 public TopComponent() { 173 this((Lookup) null); 174 } 175 176 184 public TopComponent(Lookup lookup) { 185 if (lookup != null) { 186 setLookup(lookup, true); 187 } 188 189 enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK); 190 191 setFocusable(false); 194 initActionMap(lookup); 195 } 196 197 199 201 private void initActionMap(Lookup lookup) { 202 ActionMap inner = null; 203 if (lookup != null) { 204 inner = lookup.lookup(ActionMap .class); 205 } 206 if (inner == null) { 207 inner = new ActionMap (); 208 } 209 210 javax.swing.ActionMap am = new DelegateActionMap(this, inner); 211 212 if (this instanceof TopComponent.Cloneable) { 213 am.put( 214 "cloneWindow", 215 new javax.swing.AbstractAction () { public void actionPerformed(ActionEvent evt) { 217 TopComponent cloned = ((TopComponent.Cloneable) TopComponent.this).cloneComponent(); 218 cloned.open(); 219 cloned.requestActive(); 220 } 221 } 222 ); 223 } 224 225 am.put( 226 "closeWindow", 227 new javax.swing.AbstractAction () { public void actionPerformed(ActionEvent evt) { 229 TopComponent.this.close(); 230 } 231 } 232 ); 233 234 setActionMap(am); 235 } 236 237 243 public static final Registry getRegistry() { 244 return WindowManager.getDefault().getRegistry(); 245 } 246 247 251 public final Node[] getActivatedNodes() { 252 return activatedNodes; 253 } 254 255 258 public final void setActivatedNodes(Node[] activatedNodes) { 259 boolean l = LOG.isLoggable(Level.FINER); 260 261 if (Arrays.equals(this.activatedNodes, activatedNodes)) { 262 if (l) { 263 LOG.finer("No change to activatedNodes for " + this); } 265 return; 266 } 267 268 Lookup lookup = getLookup(false); 269 270 if (lookup instanceof DefaultTopComponentLookup) { 271 if (l) { 272 LOG.finer("Updating lookup " + lookup + " for " + this); } 274 ((DefaultTopComponentLookup) lookup).updateLookups(activatedNodes); 275 } 276 277 Node[] old = this.activatedNodes; 278 this.activatedNodes = activatedNodes; 279 280 if (l) { 281 LOG.finer("activatedNodes changed: " + (activatedNodes == null ? "" : Arrays.asList(activatedNodes).toString())); } 283 WindowManager.getDefault().topComponentActivatedNodesChanged(this, this.activatedNodes); 285 286 if (l) { 287 LOG.finer("window manager notified: " + this); } 289 290 291 firePropertyChange("activatedNodes", old, this.activatedNodes); 293 if (l) { 294 LOG.finer("listeners notified: " + this); } 296 } 297 298 305 public int getPersistenceType() { 306 if (warnedClasses.add(getClass()) && !TopComponent.class.equals(getClass())) { 308 Logger.getAnonymousLogger().warning( 309 "Note - " +getClass().getName() + " ought to override getPersistenceType()" +" rather than using the client property or accepting the default." 312 ); } 314 315 String propValue = (String ) getClientProperty("PersistenceType"); 317 if (propValue == null) { 318 return PERSISTENCE_ALWAYS; 319 } else if ("Never".equals(propValue)) { 321 return PERSISTENCE_NEVER; 322 } else if ("OnlyOpened".equals(propValue)) { 324 return PERSISTENCE_ONLY_OPENED; 325 } else { 326 return PERSISTENCE_ALWAYS; 327 } 328 } 329 330 336 public UndoRedo getUndoRedo() { 337 return UndoRedo.NONE; 338 } 339 340 344 public void open() { 345 open(null); 346 } 347 348 352 @Deprecated 353 public void open(Workspace workspace) { 354 WindowManager.getDefault().topComponentOpen(this); 355 } 356 357 359 public final boolean isOpened() { 360 return isOpened(null); 361 } 362 363 367 @Deprecated 368 public final boolean isOpened(Workspace workspace) { 369 return WindowManager.getDefault().topComponentIsOpened(this); 370 } 371 372 375 public final boolean close() { 376 return close(null); 377 } 378 379 383 @Deprecated 384 public final boolean close(Workspace workspace) { 385 if (!isOpened()) { 386 return true; 387 } 388 389 if (canClose()) { 390 WindowManager.getDefault().topComponentClose(this); 391 392 return true; 393 } else { 394 return false; 395 } 396 } 397 398 401 public boolean canClose() { 402 if (!isOpened()) { 403 return false; 404 } 405 406 return canClose(null, true); 407 } 408 409 423 @Deprecated 424 public boolean canClose(Workspace workspace, boolean last) { 425 return true; 426 } 427 428 434 @Deprecated 435 protected void openNotify() { 436 } 437 438 444 @Deprecated 445 protected void closeNotify() { 446 } 447 448 452 @Deprecated 453 public SystemAction[] getSystemActions() { 454 return new SystemAction[0]; 455 } 456 457 467 public javax.swing.Action [] getActions() { 468 Action [] actions = WindowManager.getDefault().topComponentDefaultActions(this); 469 470 SystemAction[] sysActions = getSystemActions(); 471 472 if (sysActions.length > 0) { 474 List <Action > acs = new ArrayList <Action >(Arrays.asList(actions)); 475 acs.addAll(Arrays.asList(sysActions)); 476 477 return acs.toArray(new Action [0]); 478 } else { 479 return actions; 480 } 481 } 482 483 488 @Deprecated 489 public final void setCloseOperation(final int closeOperation) { 490 if ((closeOperation != CLOSE_EACH) && (closeOperation != CLOSE_LAST)) { 491 throw new IllegalArgumentException ( 492 NbBundle.getBundle(TopComponent.class).getString("EXC_UnknownOperation") 493 ); 494 } 495 496 if (this.closeOperation == closeOperation) { 497 return; 498 } 499 500 this.closeOperation = closeOperation; 501 firePropertyChange("closeOperation", null, null); } 503 504 507 @Deprecated 508 public final int getCloseOperation() { 509 return closeOperation; 510 } 511 512 524 protected String preferredID() { 525 Class clazz = getClass(); 526 527 if (getPersistenceType() != PERSISTENCE_NEVER && warnedTCPIClasses.add(clazz)) { 528 Logger.getAnonymousLogger().warning( 529 clazz.getName() + " should override preferredID()" ); 531 } 532 533 String name = getName(); 534 535 if (name == null) { 537 int ind = clazz.getName().lastIndexOf('.'); 538 name = (ind == -1) ? clazz.getName() : clazz.getName().substring(ind + 1); 539 } 540 541 return name; 542 } 543 544 550 protected void componentOpened() { 551 openNotify(); 552 } 553 554 559 protected void componentClosed() { 560 closeNotify(); 561 } 562 563 570 protected void componentShowing() { 571 } 572 573 581 protected void componentHidden() { 582 } 583 584 591 protected void componentActivated() { 592 } 593 594 602 protected void componentDeactivated() { 603 } 604 605 618 @Deprecated 619 public void requestFocus() { 620 if (isFocusable()) { 621 super.requestFocus(); 624 } 625 } 626 627 639 @Deprecated 640 public boolean requestFocusInWindow() { 641 if (isFocusable()) { 642 return super.requestFocusInWindow(); 643 } else { 644 return false; 645 } 646 } 647 648 650 public void requestActive() { 651 WindowManager.getDefault().topComponentRequestActive(this); 652 } 653 654 659 public void toFront() { 660 WindowManager.getDefault().topComponentToFront(this); 661 } 662 663 665 public void requestVisible() { 666 WindowManager.getDefault().topComponentRequestVisible(this); 667 org.netbeans.modules.openide.windows.GlobalActionContextImpl.blickActionMap(getActionMap()); 668 } 669 670 681 public final void requestAttention(final boolean brief) { 682 EventQueue.invokeLater( 684 new Runnable () { 685 public void run() { 686 if ((attentionGetter != null) && !brief) { 687 attentionGetter.kill(); 688 } else if (!brief) { 689 WindowManager.getDefault().topComponentRequestAttention(TopComponent.this); 690 } else if (attentionGetter != null) { 691 attentionGetter.reset(); 692 } else { 693 attentionGetter = new AttentionGetter(); 694 } 695 } 696 } 697 ); 698 } 699 700 704 public final void cancelRequestAttention() { 705 EventQueue.invokeLater( 707 new Runnable () { 708 public void run() { 709 if (attentionGetter != null) { 710 attentionGetter.stop(); 711 } else { 712 WindowManager.getDefault().topComponentCancelRequestAttention(TopComponent.this); 713 } 714 } 715 } 716 ); 717 } 718 719 723 public void setName(final String name) { 724 String old = getName(); 725 726 if ((name != null) && (name.equals(old))) { 727 return; 728 } 729 730 super.setName(name); 731 firePropertyChange("name", old, name); 733 WindowManager.getDefault().topComponentDisplayNameChanged(this, name); 735 } 736 737 740 public void setDisplayName(String displayName) { 741 String old = this.displayName; 742 743 if ((displayName == old) || ((displayName != null) && displayName.equals(old))) { 744 return; 745 } 746 747 if (BasicHTML.isHTMLString(displayName)) { 749 Logger.getAnonymousLogger().warning( 750 "Call of " + getClass().getName() + ".setDisplayName(\"" + displayName + "\")" + 751 " shouldn't contain any HTML tags. Please use " + getClass().getName() + ".setHtmlDisplayName(String)" + 752 "for such purpose. For details please see http://www.netbeans.org/issues/show_bug.cgi?id=66777."); 753 } 754 755 this.displayName = displayName; 756 firePropertyChange("displayName", old, displayName); 758 WindowManager.getDefault().topComponentDisplayNameChanged(this, displayName); 759 } 760 761 764 public String getDisplayName() { 765 return displayName; 766 } 767 768 777 public void setHtmlDisplayName(String htmlDisplayName) { 778 String old = this.htmlDisplayName; 779 780 if ((htmlDisplayName == old) || ((htmlDisplayName != null) && htmlDisplayName.equals(old))) { 781 return; 782 } 783 784 this.htmlDisplayName = htmlDisplayName; 785 firePropertyChange("htmlDisplayName", old, htmlDisplayName); 787 WindowManager.getDefault().topComponentHtmlDisplayNameChanged(this, htmlDisplayName); 788 } 789 790 798 public String getHtmlDisplayName() { 799 return htmlDisplayName; 800 } 801 802 803 805 public void setToolTipText(String toolTip) { 806 if ((toolTip != null) && toolTip.equals(getToolTipText())) { 807 return; 808 } 809 810 super.setToolTipText(toolTip); 811 812 WindowManager.getDefault().topComponentToolTipChanged(this, toolTip); 814 } 815 816 822 public void setIcon(final Image icon) { 823 if (icon == this.icon) { 824 return; 825 } 826 827 Image old = this.icon; 828 this.icon = icon; 829 830 WindowManager.getDefault().topComponentIconChanged(this, this.icon); 832 firePropertyChange("icon", old, icon); } 834 835 836 public Image getIcon() { 837 return icon; 838 } 839 840 844 public HelpCtx getHelpCtx() { 845 return new HelpCtx(TopComponent.class); } 847 848 868 public List <Mode> availableModes(List <Mode> modes) { 869 return modes; 870 } 871 872 874 protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { 875 boolean ret = super.processKeyBinding(ks, e, condition, pressed); 876 877 if ((JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT == condition) && (ret == false) && !e.isConsumed()) { 880 Keymap km = Lookup.getDefault().lookup(Keymap .class); 881 Action action = (km != null) ? km.getAction(ks) : null; 882 883 if (action == null) { 884 return false; 885 } 886 887 if (action instanceof ContextAwareAction) { 889 action = ((ContextAwareAction) action).createContextAwareInstance(getLookup()); 890 } else if (SwingUtilities.getWindowAncestor(e.getComponent()) instanceof java.awt.Dialog ) { 891 Object value = action.getValue("OpenIDE-Transmodal-Action"); 895 if (!Boolean.TRUE.equals(value)) { 896 return false; 897 } 898 } 899 900 if (action.isEnabled()) { 901 LogRecord rec = new LogRecord (Level.FINER, "UI_ACTION_KEY_PRESS"); rec.setParameters(new Object [] { ks, ks.toString(), action, action.getClass().getName(), action.getValue(Action.NAME) }); 903 rec.setResourceBundle(NbBundle.getBundle(TopComponent.class)); 904 rec.setLoggerName(UILOG.getName()); 905 UILOG.log(rec); 906 907 ActionEvent ev = new ActionEvent (this, ActionEvent.ACTION_PERFORMED, Utilities.keyToString(ks)); 908 action.actionPerformed(ev); 909 } else { 910 Toolkit.getDefaultToolkit().beep(); 911 } 912 913 return true; 914 } else { 915 return ret; 916 } 917 } 918 919 923 public void writeExternal(ObjectOutput out) throws IOException { 924 out.writeObject(new Short (serialVersion)); 925 out.writeInt(closeOperation); 926 out.writeObject(getName()); 927 out.writeObject(getToolTipText()); 928 929 if (getDisplayName() != null) { 930 out.writeObject(getDisplayName()); 931 } 932 933 Node n = (nodeName == null) ? null : nodeName.getNode(); 934 Node.Handle h = (n == null) ? null : n.getHandle(); 935 out.writeObject(h); 936 } 937 938 942 public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException { 943 Object firstObject = in.readObject(); 944 945 if (firstObject instanceof Integer ) { 946 serialVersion = 0; 948 949 closeOperation = ((Integer ) firstObject).intValue(); 950 951 in.readObject(); 955 956 super.setName((String ) in.readObject()); 957 setToolTipText((String ) in.readObject()); 958 959 961 967 } else { 968 serialVersion = ((Short ) firstObject).shortValue(); 970 971 closeOperation = in.readInt(); 972 super.setName((String ) in.readObject()); 973 setToolTipText((String ) in.readObject()); 974 975 Object obj = in.readObject(); 976 977 if (obj instanceof String ) { 978 setDisplayName((String ) obj); 979 obj = in.readObject(); 980 } 981 982 Node.Handle h = (Node.Handle) obj; 983 984 if (h != null) { 985 Node n = h.getNode(); 986 NodeName.connect(this, n); 987 } 988 } 989 990 if ((closeOperation != CLOSE_EACH) && (closeOperation != CLOSE_LAST)) { 991 throw new IOException ("invalid closeOperation: " + closeOperation); } 993 } 994 995 1001 protected Object writeReplace() throws ObjectStreamException { 1002 return new Replacer(this); 1003 } 1004 1005 1008 public AccessibleContext getAccessibleContext() { 1009 if (accessibleContext == null) { 1010 accessibleContext = new JComponent.AccessibleJComponent () { 1011 public AccessibleRole getAccessibleRole() { 1012 return AccessibleRole.PANEL; 1013 } 1014 1015 public String getAccessibleName() { 1016 if (accessibleName != null) { 1017 return accessibleName; 1018 } 1019 1020 return getName(); 1021 } 1022 1023 1024 public String getToolTipText() { 1025 return TopComponent.this.getToolTipText(); 1026 } 1027 }; 1028 } 1029 1030 return accessibleContext; 1031 } 1032 1033 1042 public Lookup getLookup() { 1043 return getLookup(true); 1044 } 1045 1046 1050 private Lookup getLookup(boolean init) { 1051 synchronized (defaultLookupLock) { 1052 if (defaultLookupRef instanceof Lookup) { 1053 return (Lookup) defaultLookupRef; 1054 } 1055 1056 if (defaultLookupRef instanceof Object []) { 1057 return (Lookup) ((Object []) defaultLookupRef)[0]; 1058 } 1059 1060 if (defaultLookupRef instanceof java.lang.ref.Reference ) { 1061 Object l = ((java.lang.ref.Reference ) defaultLookupRef).get(); 1062 1063 if (l instanceof Lookup) { 1064 return (Lookup) l; 1065 } 1066 } 1067 1068 if (!init) { 1069 return null; 1070 } 1071 1072 Lookup lookup = new DefaultTopComponentLookup(this); defaultLookupRef = new java.lang.ref.WeakReference <Lookup>(lookup); 1074 1075 return lookup; 1076 } 1077 } 1078 1079 1087 protected final void associateLookup(Lookup lookup) { 1088 setLookup(lookup, true); 1089 } 1090 1091 1100 final void setLookup(Lookup lookup, boolean sync) { 1101 synchronized (defaultLookupLock) { 1102 if (defaultLookupRef != null) { 1103 throw new IllegalStateException ( 1104 "Trying to set lookup " + lookup + " but there already is " + defaultLookupRef + 1105 " for component: " + this 1106 ); } 1108 1109 defaultLookupRef = lookup; 1110 1111 if (sync) { 1112 defaultLookupRef = new Object [] { defaultLookupRef, new SynchronizeNodes(lookup) }; 1113 } 1114 if (LOG.isLoggable(Level.FINE)) { 1115 LOG.fine("setLookup with " + lookup + " and sync: " + sync + " on " + this); } 1117 } 1118 } 1119 1120 private void attachNodeName(NodeName nodeName) { 1121 this.nodeName = nodeName; 1122 } 1123 1124 1128 public static interface Cloneable { 1129 1132 public TopComponent cloneComponent(); 1133 } 1134 1135 1140 public static interface Registry { 1141 1142 public static final String PROP_OPENED = "opened"; 1144 1145 public static final String PROP_ACTIVATED = "activated"; 1147 1148 public static final String PROP_CURRENT_NODES = "currentNodes"; 1150 1151 public static final String PROP_ACTIVATED_NODES = "activatedNodes"; 1153 1157 public static final String PROP_TC_OPENED = "tcOpened"; 1159 1163 public static final String PROP_TC_CLOSED = "tcClosed"; 1165 1169 public Set <TopComponent> getOpened(); 1170 1171 1174 public TopComponent getActivated(); 1175 1176 1180 public Node[] getCurrentNodes(); 1181 1182 1188 public Node[] getActivatedNodes(); 1189 1190 1193 public void addPropertyChangeListener(PropertyChangeListener l); 1194 1195 1198 public void removePropertyChangeListener(PropertyChangeListener l); 1199 } 1200 1201 private class AttentionGetter implements ActionListener { 1202 Timer timer = null; 1203 1204 public AttentionGetter() { 1205 reset(); 1206 } 1207 1208 public void reset() { 1209 assert EventQueue.isDispatchThread(); 1210 1211 if (timer != null) { 1212 timer.stop(); 1213 } 1214 1215 start(); 1216 timer = new Timer (3500, this); 1217 timer.setRepeats(false); 1218 timer.start(); 1219 } 1220 1221 private void start() { 1222 WindowManager.getDefault().topComponentRequestAttention(TopComponent.this); 1223 } 1224 1225 public void kill() { 1226 timer.stop(); 1227 attentionGetter = null; 1228 } 1229 1230 private void stop() { 1231 if (timer != null) { 1232 timer.stop(); 1233 } 1234 1235 attentionGetter = null; 1236 WindowManager.getDefault().topComponentCancelRequestAttention(TopComponent.this); 1237 attentionGetter = null; 1238 } 1239 1240 public void actionPerformed(ActionEvent ae) { 1241 stop(); 1242 } 1243 } 1244 1245 1253 @Deprecated 1254 public static class NodeName extends NodeAdapter { 1255 1256 private TopComponent top; 1257 1258 1259 private Reference node; 1260 1261 1262 private NodeListener nodeL; 1263 1264 1273 public static void connect(TopComponent top, Node n) { 1274 new NodeName(top).attach(n); 1275 } 1276 1277 1285 @Deprecated 1286 public NodeName(TopComponent top) { 1287 this.top = top; 1288 } 1289 1290 1294 @Deprecated 1295 public void propertyChange(PropertyChangeEvent ev) { 1296 if (ev.getPropertyName().equals(Node.PROP_DISPLAY_NAME)) { 1297 Node n = (Node) node.get(); 1298 if (n != null) { 1299 top.setName(n.getDisplayName()); 1300 } 1301 } 1302 } 1303 1304 1306 private void attach(Node n) { 1307 synchronized (top) { 1308 node = new WeakReference <Node>(n); 1309 nodeL = WeakListeners.create(NodeListener.class, this, n); 1310 n.addNodeListener(nodeL); 1311 top.attachNodeName(this); 1312 top.setActivatedNodes(new Node[] { n }); 1313 top.setName(n.getDisplayName()); 1314 } 1315 } 1316 1317 private Node getNode() { 1318 return (Node) node.get(); 1319 } 1320 1321 } 1323 1326 private static final class Replacer implements Serializable { 1327 1328 static final long serialVersionUID = -8897067133215740572L; 1329 1330 1332 transient TopComponent tc; 1333 1334 public Replacer(TopComponent tc) { 1335 this.tc = tc; 1336 } 1337 1338 private void writeObject(ObjectOutputStream oos) 1339 throws IOException , ClassNotFoundException { 1340 oos.writeObject(tc.getClass().getName()); 1342 1343 tc.writeExternal(oos); 1345 } 1346 1347 private void readObject(ObjectInputStream ois) 1348 throws IOException , ClassNotFoundException { 1349 String name = (String ) ois.readObject(); 1352 name = org.openide.util.Utilities.translate(name); 1353 1354 try { 1355 ClassLoader loader = Lookup.getDefault().lookup(ClassLoader .class); 1356 1357 if (loader == null) { 1358 loader = getClass().getClassLoader(); 1359 } 1360 1361 Class tcClass = Class.forName(name, true, loader); 1362 1363 java.lang.reflect.Constructor con = tcClass.getDeclaredConstructor(new Class [0]); 1366 con.setAccessible(true); 1367 1368 try { 1369 tc = (TopComponent) con.newInstance(new Object [0]); 1370 } finally { 1371 con.setAccessible(false); 1372 } 1373 1374 tc.readExternal(ois); 1375 1376 Method resolveMethod = findReadResolveMethod(tcClass); 1378 1379 if (resolveMethod != null) { 1380 Class [] result = resolveMethod.getExceptionTypes(); 1382 1383 if ((result.length == 1) && ObjectStreamException .class.equals(result[0])) { 1384 if (Object .class.equals(resolveMethod.getReturnType())) { 1386 resolveMethod.setAccessible(true); 1388 1389 try { 1391 TopComponent unresolvedTc = tc; 1392 tc = (TopComponent) resolveMethod.invoke(tc); 1393 1394 if (tc == null) { 1395 throw new java.io.InvalidObjectException ( 1396 "TopComponent.readResolve() cannot return null." +" See http://www.netbeans.org/issues/show_bug.cgi?id=27849 for more info." +" TopComponent:" + unresolvedTc 1399 ); } 1401 } finally { 1402 resolveMethod.setAccessible(false); 1403 } 1404 } 1405 } 1406 } 1407 } catch (Exception exc) { 1408 Throwable th = exc; 1409 1410 if (th instanceof InvocationTargetException ) { 1412 th = ((InvocationTargetException ) th).getTargetException(); 1413 } 1414 1415 if (th instanceof IOException ) { 1417 throw (IOException ) th; 1418 } 1419 1420 throw (IOException ) new IOException (th.toString()).initCause(th); 1422 } 1423 } 1424 1425 1426 private Object readResolve() throws ObjectStreamException { 1427 return tc; 1428 } 1429 1430 1433 private static Method findReadResolveMethod(Class clazz) { 1434 Method result = null; 1435 Class [] params = new Class [0]; 1436 1437 try { 1439 result = clazz.getMethod("readResolve", params); } catch (NoSuchMethodException exc) { 1441 for (Class i = clazz; (i != null) && (i != TopComponent.class); i = i.getSuperclass()) { 1445 try { 1446 result = i.getDeclaredMethod("readResolve", params); 1448 break; 1450 } catch (NoSuchMethodException exc2) { 1451 } 1453 } 1454 } 1455 1456 return result; 1457 } 1458 } 1459 1461 1463 private class SynchronizeNodes implements org.openide.util.LookupListener, Runnable { 1464 private Lookup.Result<Node> res; 1465 1466 public SynchronizeNodes(Lookup l) { 1467 res = l.lookup(new Lookup.Template<Node>(Node.class)); 1468 res.addLookupListener(this); 1469 resultChanged(null); 1470 } 1471 1472 public void resultChanged(org.openide.util.LookupEvent ev) { 1473 boolean l = LOG.isLoggable(Level.FINE); 1474 if (l) { 1475 LOG.fine("lookup changed for " + TopComponent.this + " is visible: " + TopComponent.this.isVisible()); } 1477 if (TopComponent.this.isVisible() && EventQueue.isDispatchThread()) { 1478 run(); 1480 } else { 1481 EventQueue.invokeLater(this); 1483 } 1484 if (l) { 1485 LOG.fine("lookup changed exit " + TopComponent.this); } 1487 } 1488 1489 public void run() { 1490 boolean l = LOG.isLoggable(Level.FINE); 1491 1492 Collection <? extends Node> nodes = res.allInstances(); 1493 1494 if (l) { 1495 LOG.fine("setting nodes for " + TopComponent.this + " to " + nodes); } 1497 setActivatedNodes(nodes.toArray(new Node[0])); 1498 if (l) { 1499 LOG.fine("setting nodes done for " + TopComponent.this + " to " + nodes); } 1501 } 1502 } 1503 } 1505 | Popular Tags |