1 19 20 package org.openide.windows; 21 22 import java.io.Externalizable ; 23 import java.io.IOException ; 24 import java.io.ObjectInput ; 25 import java.io.ObjectInputStream ; 26 import java.io.ObjectOutput ; 27 import java.io.Serializable ; 28 import java.util.Collections ; 29 import java.util.Enumeration ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.Set ; 33 import org.openide.util.NbBundle; 34 import org.openide.util.io.NbMarshalledObject; 35 36 44 public abstract class CloneableTopComponent extends TopComponent implements Externalizable , TopComponent.Cloneable { 45 46 static final long serialVersionUID = 4893753008783256289L; 47 48 50 60 61 63 public static final Ref EMPTY = new Ref(); 64 65 66 private Ref ref; 67 68 70 public CloneableTopComponent() { 71 } 72 73 76 public final Object clone() { 77 return cloneComponent(); 78 } 79 80 86 public final CloneableTopComponent cloneTopComponent() { 87 CloneableTopComponent top = createClonedObject(); 88 89 top.setReference(getReference()); 91 92 return top; 93 } 94 95 98 public final TopComponent cloneComponent() { 99 return cloneTopComponent(); 100 } 101 102 109 protected CloneableTopComponent createClonedObject() { 110 try { 111 NbMarshalledObject o = new NbMarshalledObject(this); 113 return (CloneableTopComponent) o.get(); 114 } catch (IOException ex) { 115 throw new AssertionError (ex); 116 } catch (ClassNotFoundException ex) { 117 throw new AssertionError (ex); 118 } 119 } 120 121 125 public synchronized final Ref getReference() { 126 if (ref == null) { 127 ref = new Ref(this); 128 } 129 130 return ref; 131 } 132 133 136 public synchronized final void setReference(Ref another) { 137 if (another == EMPTY) { 138 throw new IllegalArgumentException ( 139 NbBundle.getBundle(CloneableTopComponent.class).getString("EXC_CannotAssign") 140 ); 141 } 142 143 if (ref != null) { 144 ref.removeComponent(this); 146 } 147 148 another.register(this); 150 151 ref = another; 153 } 154 155 157 protected void componentClosed() { 158 super.componentClosed(); 159 160 if (!isOpened()) { 161 getReference().unregister(this); 162 } 163 } 164 165 169 public boolean canClose() { 170 if (!isOpened()) { 171 return false; 172 } 173 174 return getReference().unregister(this); 175 } 176 177 @SuppressWarnings ("deprecation") 178 public boolean canClose(Workspace workspace, boolean last) { 179 if (last) { 180 return getReference().unregister(this); 181 } 182 183 return true; 184 } 185 186 192 protected boolean closeLast() { 193 return true; 194 } 195 196 public void readExternal(ObjectInput oi) throws IOException , ClassNotFoundException { 197 super.readExternal(oi); 198 199 if (serialVersion != 0) { 200 Ref ref = (Ref) oi.readObject(); 203 204 if (ref != null) { 205 setReference(ref); 206 } 207 } 208 } 209 210 public void writeExternal(ObjectOutput oo) throws java.io.IOException { 211 super.writeExternal(oo); 212 213 oo.writeObject(ref); 214 } 215 216 223 public static class Ref implements Serializable { 224 225 static final long serialVersionUID = 5543148876020730556L; 226 227 228 private static final Object LOCK = new Object (); 229 230 231 private transient Set <CloneableTopComponent> componentSet = new HashSet <CloneableTopComponent>(7); 232 233 235 protected Ref() { 236 } 237 238 241 private Ref(CloneableTopComponent c) { 242 synchronized (LOCK) { 243 componentSet.add(c); 244 } 245 } 246 247 250 public Enumeration <CloneableTopComponent> getComponents() { 251 Set <CloneableTopComponent> components; 252 253 synchronized (LOCK) { 254 components = new HashSet <CloneableTopComponent>(componentSet); 255 } 256 257 return Collections.enumeration(components); 258 } 259 260 263 public boolean isEmpty() { 264 synchronized (LOCK) { 265 return componentSet.isEmpty(); 266 } 267 } 268 269 275 public CloneableTopComponent getAnyComponent() { 276 synchronized (LOCK) { 277 return componentSet.iterator().next(); 278 } 279 } 280 281 286 public CloneableTopComponent getArbitraryComponent() { 287 TopComponent activated = WindowManager.getDefault().getRegistry().getActivated(); 288 289 synchronized (LOCK) { 290 if (componentSet.contains(activated)) { 292 return (CloneableTopComponent) activated; 293 } 294 295 Iterator <CloneableTopComponent> it = componentSet.iterator(); 296 297 if (it.hasNext()) { 298 return it.next(); 299 } else { 300 return null; 301 } 302 } 303 } 304 305 308 private final void register(CloneableTopComponent c) { 309 synchronized (LOCK) { 310 componentSet.add(c); 311 } 312 } 313 314 320 private final boolean unregister(CloneableTopComponent c) { 321 int componentCount; 322 323 synchronized (LOCK) { 324 if (!componentSet.contains(c)) { 325 return true; 326 } 327 328 componentCount = componentSet.size(); 329 } 330 331 if ((componentCount > 1) || c.closeLast()) { 332 removeComponent(c); 333 334 return true; 335 } else { 336 return false; 337 } 338 } 339 340 private void removeComponent(CloneableTopComponent c) { 341 synchronized (LOCK) { 342 componentSet.remove(c); 343 } 344 } 345 346 347 private void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 348 in.defaultReadObject(); 349 350 synchronized (LOCK) { 351 componentSet = new HashSet <CloneableTopComponent>(7); 352 } 353 } 354 } 355 } 357 | Popular Tags |