以下部分截取自http://platform.netbeans.org/tutorials/nbm-selection-1.html

有时间再整理!

使用向导创建的TopComponent都是singleton的。以下步骤可以创建非singleton的TopComponent。

 

 

Creating the Editor Component

Now you need something to actually provide instances of APIObject, for this code to be of any use. Fortunately this is quite simple.

You will create another TopComponent, this time, one that opens in the editor area and offers an instance of APIObject from its Lookup. You could use the Window template again, but that template is designed for creating singleton components, rather than components there can be many of. So you will simply create a TopComponent subclass without the template, and an action which will open additional ones.

  1. You will need three dependencies to the My Editor module for it to be able to find the classes you will be using. Right click the My Editor project and choose Properties. On the Library page of the Project Properties dialog box, click the Add Dependency button, and type TopComponent. The dialog should automatically suggest setting a dependency on the Window System API. Do the same thing for Lookups (Lookup API). Also set a dependency on the Utilities API, as well the UI Utilities API, which provide various helpful supporting classes that are made available by the NetBeans Platform.
  2. Right-click the org.myorg.myeditor package in the My Editor project, and choose New > JPanel Form.
  3. Name it "MyEditor", and finish the wizard.
  4. When the form editor opens, drop two JTextFields on the form, one above the other. On the property sheet, set the Editable property (checkbox) to false for each one.
  5. Click the Source button in the editor toolbar to switch to the code editor.
  6. Change the signature of MyEditor to extends TopComponent instead of javax.swing.JPanel and annotate the class to specify the location of the window and the menu item for opening it:
    @TopComponent.Description(preferredID = "MyEditorTopComponent", 
    persistenceType = TopComponent.PERSISTENCE_NEVER)
    @TopComponent.Registration(mode = "explorer", openAtStartup = false)
    @TopComponent.OpenActionRegistration(displayName = "#CTL_MyEditorAction")
    @ActionID(category = "Window", id = "org.myorg.myviewer.MyEditorTopComponent")
    @ActionReference(path = "Menu/Window")

    public class MyEditor extends TopComponent {
  7. As indicated by the "displayName" attribute above, in the Bundle.properties file you need to define this key/value pair:
    CTL_MyEditorAction=Open Editor
  8. Add the following code to the constructor of MyEditor:
    APIObject obj = new APIObject();
    associateLookup (Lookups.singleton (obj));
    jTextField1.setText ("APIObject #" + obj.getIndex());
    jTextField2.setText ("Created: " + obj.getDate());
    setDisplayName ("MyEditor " + obj.getIndex());
    Right-click in the editor and choose Fix Imports.

The line associateLookup (Lookups.singleton (obj)); will create a Lookup that contains only one object—the new instance of APIObject—and assign that Lookup to be what is returned by MyEditor.getLookup(). While this is an artificial example, you can imagine how APIObject might represent a file, an entity in a database or anything else you might want to edit or view. Probably you can also imagine one component that allowed you to select or edit multiple unique instances of APIObject—that will be the subject of the next tutorial.

To make your editor component at least somewhat interesting (though it doesn't actually edit anything), you set the text fields' values to values from the APIObject, so you have something to display.

----------------------------------------------------------------------------------------------------------------------------------

How can I change my TopComponent to not be a singleton?
http://wiki.netbeans.org/DevFaqNonSingletonTopComponents

 

The "New Window Component" wizard in the NetBeans IDE generates a singleton TopComponent. That's fine for windows that there should only be one of. Particularly if you are creating some kind of editor, you will want to create multiple instances of your TopComponent.

 

 

The really easy way

If you have not already used the New Window template to create your TopComponent subclass, don't.

Instead, use New > JPanel Form. Once the new JPanel is created, switch to the Code tab, and replace extends javax.swing.JPanel with extends TopComponent. Then do the following things:

  • Override getPersistenceType().
    • If you do not want your components reopened on restart
      • return PERSISTENCE_NEVER—that is all you need to do to make sure they are not preserved across restarts.
    • If you do want your components reopened on restart, then
      • return PERSISTENCE_ONLY_OPENED from getPersistenceType()
      • Add the following slightly-cryptic annotation to the class: @ConvertAsProperties(dtd = "-//com.yourmodule.yourpackage//YourTopComponent//EN", autostore = false), replacing the package and class name with your own. This identifies a DTD. You do not need to define the DTD. You just need to give it a unique namespace that nothing else is using. Package and class name work well for that.
      • Add two additional methods (you are not overriding anything and they can be package-private, like serialization methods):
        • void writeProperties(Properties p) - here we will call p.put() passing enough information to reconstruct your component on restart. If we are editing a file, we might save the path to the file. If we are viewing a URL, we might save the URL. If we want to be particularly fastidious, we might save the scroll position, or what line the editor caret was on , or anything else useful to restore the state of our component.
        • void readProperties(Properties p) - here we will reading whatever keys we wrote out in writeProperties and (re)initializing the component to its pre-shutdown state. This method will be called on startup to restore our component to its pre-shutdown state as best can be done. If we were, say, editing a file that no longer exists, the appropriate thing to do is throw an exception.

If you already have a generated singleton TopComponent subclass

The good news is that you won't have to write any code -- you'll just have to delete some of the code that was generated for you.

In your TopComponent's .java source file:

  • Delete the static instance variable, which ought to be declared a few lines above the constructor.
  • Make sure your TopComponent class is public
  • Make sure your TopComponent has a no-argument constructor which is public
  • Delete the getDefault() method (typically somewhere around the middle of the file)
  • Delete the findInstance() method (which typically follows the getDefault() method)
  • Update the persistence code which saves your component's state on shutdown and restores it on restart to reopen your component as follows
    • Locate the getPersistenceType method and change its return value to either TopComponent.PERSISTENCE_NEVER or TopComponent.PERSISTENCE_ONLY_OPENED (see below for why).
    • If you have methods called writeReplace()and an inner class called ResolvableHelper (NetBeans 6.8 and earlier):
      • Delete the writeReplace() method (typically towards the end of the file)
      • Delete the ResolvableHelper inner class (typically towards the end of the file)
    • If you do not want persistence across restarts — you are returning PERSISTENCE_NEVER from getPersistenceType()
      • If you have a @ConvertAsProperties annotation and readProperties(Properties) and writeProperties(Properties) methods, delete the annotation and both methods
    • If do want persistence across restarts — you are returning PERSISTENCE_ONLY_OPENED fromgetPersistenceType()
      • If you already have the @ConvertAsProperties annotation and readProperties(Properties) and writeProperties(Properties) methods just leave them there
      • If you do not have the annotation and those methods, implement them as described in the previous section

Next we will need to delete the metadata that registers the component:

  • For all versions of NetBeans:
    • Delete the settings XML file for your component. If your component class is MyWindow then that file will be in the same folder and will be called MyWindowSettings.xml.
    • Delete the wstcrf ("window system TopComponent reference") XML file in that folder. If your component class is MyWindow then that file will be named MyWindowWstcrf.xml
    • Edit your module's [DevFaqModulesLayerFile| layer.xml file] to
      • Remove any references to either of these files (just use Ctrl-F to search for e.g. MyWindowSettings.xml and MyWindowWstcrf.xml). They will be in <file> tags.
      • If you have removed a <file> entry, and it was the only entry in that folder, you can remove the XML for parent folder (and its parent if it is now empty, and so forth)
      • Find where an Action is registered for to open your (formerly) singleton TopComponent
        • NetBeans 6.9 and later:
          • Look for an <file> registered in Actions/Windowin the XML file. It will have an <attr> element that refers to your TopComponent class, e.g. <attr name="component" methodvalue="com.foo.MyWindow.findInstance"/>. Delete the entire <file> entry.
          • Look for <file> entry for a .shadow file in Actions/Menu in the XML, with its originalFile pointing to the file entry you just deleted. Delete the .shadow <file> too.
        • NetBeans 6.8 and earlier:
          • There will be an Action class in your sources which is registered, e.g. MyWindowAction.java. Delete the java source file.
          • Look for an <file> registered in Actions/Windowin the XML file. It will be a <file> whose name is the munged fully-qualified class name of the Action you just deleted, e.g. com-foo-MyWindowAction.instance. Delete the <file> entry for it
          • Look for <file> entry for a .shadow file in Actions/Menu in the XML, with its originalFile pointing to the file entry you just deleted. Delete the .shadow <file> too.

Creating And Opening Your TopComponents

Now that you have deleted the actions for your TopComponent, presumably they will be created some other way (for example, from a file's popup menu). You can create new instances of your TopComponent, open them and give them focus as follows:

TopComponent win = new MyTopComponent();
win.open();
win.requestActive();

If you wrote your persistence code correctly, your components will magically reopen on restart with no further work.


What About PERSISTENCE_ALWAYS?

There is one other value you can return from TopComponent.getPersistenceType(). That value is TopComponent.PERSISTENCE_ALWAYS.

While it is legal to return this value from a non-singleton TopComponent, it is almost never what you want to do. What will happen if you do this is:

  • Every instance of your component that is ever created will be persisted on shutdown, forever
    • Even if it is closed
    • Even if nothing can use it, or it represents a file that was deleted, or is in some other way invalid
    • Even if no code will ever be able to find it and open it again
  • One every restart, forever
    • Every instance of your component that has ever existed will be read back from disk
      • Each one will slow down startup a little bit
      • Each one will be wasting disk space

PERSISTENCE_ALWAYS is for singleton components that need to be remembered forever across restarts. Don't use it for non-singletons.


If you do not have any persistence code, but your components are reopening on restart...

You are returning either PERSISTENCE_ONLY_OPENED or PERSISTENCE_ALWAYS from getPersistenceType(). If there is no persistence code, but you are returning one of these values, NetBeans will use plain old Java serialization to store and reload your component.

Either use PERSISTENCE_NEVER or write persistence code as described above. Serialization is slower and more fragile than proper persistence, and is never a good option for production code.

 

 

 

 

 

posted on 2011-08-12 10:41  网络大豆  阅读(735)  评论(0编辑  收藏  举报