NetBeans Platform 6.9: Advanced Aspects of Window System

(For more resources on NetBeans, see here.)

Creating custom modes

You can get quite far with the standard modes provided by the NetBeans Platform. Still, sometimes you may need to provide a custom mode, to provide a new position for the TopComponents within the application. A custom mode is created declaratively in XML files, rather than programmatically in Java code.

In the following example, you create two new modes that are positioned side by side in the lower part of the application using a specific location relative to each other.

  1. Create a new module named CustomModes, with Code Name Base com.netbeansrcp.custommodes, within the existing WindowSystemExamples application.
  2. Right-click the module project and choose New | Other to open the New File dialog. Then choose Other | Empty File, as shown in the following screenshot:

  3. Type mode1.wsmode as the new filename and file extension, as shown in the following screenshot. Click Finish.

  4. Define the content of the new mode1.wsmode as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    "-//NetBeans//DTD Mode Properties 2.3//EN"
    <mode version="2.3">
    <name unique="mode1" />
    <kind type="view" />
    <state type="joined" />
    <path orientation="vertical" number="20" weight="0.2"/>
    <path orientation="horizontal" number="20" weight="0.5"/>

  5. Create another file to define the second mode and name it mode2.wsmode. Add this content to the new file:

    <?xml version="1.0" encoding="UTF-8"?>
    "-//NetBeans//DTD Mode Properties 2.3//EN"
    <mode version="2.3">
    <name unique="mode2" />
    <kind type="view" />
    <state type="joined" />
    <path orientation="vertical" number="20" weight="0.2"/>
    <path orientation="horizontal" number="40" weight="0.5"/>

Via the two wsmode files described above, you have defined two custom modes. The first mode has the unique name mode1, with the second named mode2. Both are created for normal TopComponents (view instead of editor) that are integrated into the main window, rather than being undocked by default (joined instead of separated).

The constraints elements in the files are comparable to GridBagLayout, with a relative horizontal and vertical position, as well as a relative horizontal and vertical weight. You place mode1 in position 20/20 with a weighting of 0,5/0,2, while mode2 is placed in position 20/40 with the same weighting.

If all the other defined modes have TopComponents opened within them, the TopComponents in the two new modes should lie side by side, right above the status bar, taking up 20% of the available vertical space, with the horizontal space shared between them.

  1. Let us now create two new TopComponents and register them in the layer.xml file so that they will be displayed in your new modes. Do this by using the New Window wizard twice in the CustomModes module, first creating a window called Class Name Prefix Red and then a window with Class Name Prefix Blue.

    What should I set the window position to?
    In the wizard, in both cases, it does not matter what you set to be the window position, as you are going to change that setting manually afterwards. Let both of them open automatically when the application starts.

  2. In the Design mode of both TopComponents, add a JPanel to each of the TopComponents. Change the background property of the panel in the RedTopComponent to red and in the BlueTopComponent to blue.
  3. Edit the layer.xml of CustomModes module, registering the two .wsmode files and ensuring that the two new TopComponents open in the new modes:

    <folder name="Windows2">
    <folder name="Components">
    <file name="BlueTopComponent.settings"
    <file name="RedTopComponent.settings"
    <folder name="Modes">
    <file name="mode1.wsmode" url="mode1.wsmode"/>
    <file name="mode2.wsmode" url="mode2.wsmode"/>
    <folder name="mode1">
    <file name="RedTopComponent.wstcref"
    <folder name="mode2">
    <file name="BlueTopComponent.wstcref"

  4. As before, perform a Clean and Build on the application project node and then start the application again. It should look as shown in the following screenshot:

In the summary, you defined two new modes in XML files and registered them in the module's layer.xml file. To confirm that the modes work correctly, you use the layer.xml file to register two new TopComponents so that they open by default into the new modes. As a result, you now know how to extend the default layout of a NetBeans Platform application with new modes.

(For more resources on NetBeans, see here.)

Creating window groups

Some windows should always open and close together with other windows. For example, in NetBeans IDE, the Matisse GUI Builder's Design mode always opens together with the Inspector, the Palette, and the Properties window. That combination of windows constitutes a workspace to use when laying out an application's user interface. To achieve this yourself in your own application, you need to define a TopComponentGroup.

In the following example, you group the two TopComponents you have created in the previous sections and open and close them together as a single unit.

  1. To get started, within the CustomModes module, create a new empty file named colorgroup.wsgrp, with the following content:

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE group PUBLIC
    "-//NetBeans//DTD Group Properties 2.0//EN"
    <group version="2.0">
    <name unique="colorgroup" />
    <state opened="false" />

    You have now defined a group named colorgoup and you have specified that initially the TopComponents within the group are closed.

  2. Let us now specify which TopComponents belong to the group. Create two new files called RedTopComponentWstcgrp.xml and BlueTopComponentWstcgrp.xml, with the content shown in the following code snippets:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE tc-group PUBLIC "-//NetBeans//DTD Top Component in Group
    Properties 2.0//EN" "">
    <tc-group version="2.0">
    <module name="com.netbeansrcp.custommodes" spec="1.0"/>
    <tc-id id="RedTopComponent" />
    <open-close-behavior open="true" close="true" />
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode
    Properties 2.0//EN" "">
    <tc-ref version="2.0" >
    <module name="com.netbeansrcp.custommodes" spec="1.0"/>
    <tc-id id="BlueTopComponent"/>
    <open-close-behavior open="true" close="true" />

    You now have a file per TopComponent, providing the TopComponent's unique ID, while declaring the state of the TopComponent when the group to which it belongs is opened or closed.

  3. Now modify the layer.xml to register the two files created in the previous step, within the Windows2 | Groups folder:

    <folder name="Groups">
    <file name="colorgroup.wsgrp" url="colorgroup.wsgrp"/>
    <folder name="colorgroup">
    <file name="RedTopComponent.wstcgrp"
    <file name="BlueTopComponent.wstcgrp"

    The file colorgroup.wsgrp declares the group to the Window System and refers to the group definition file of the same name. The subfolder color-group describes the contents of the group and adds references to the file for each TopComponent, so that they now belong to the group.

  4. Use the New Action wizard to create two new Always Enabled actions, OpenRedBlueAction and CloseRedBlueAction, with display names OpenRedBlue and CloseRedBlue, for opening/closing the group. Within the ActionListener classes generated by the New Action wizard, define the code to be invoked as follows:

    public void actionPerformed(ActionEvent evt) {
    TopComponentGroup myGroup
    if (myGroup != null) {;

    public void actionPerformed(ActionEvent evt) {
    TopComponentGroup myGroup = WindowManager.getDefault()
    if (myGroup != null) {

  5. Modify the files BlueTopComponentWstcref.xml and RedTopComponentWstcref.xml, to ensure that their individual default states are set to closed:

    <state opened="false"/>

  6. Choose Clean and Build on the application to remove the build folder that contains the user settings persisted from the last deployment of the application. Start the application again. Select Window | OpenRedBlue and notice that both TopComponents open. Then select Window | CloseRedBlue and notice that both TopComponents close.

In the summary, you have learned how to define a group of TopComponents that open and close together as a unit.

Extending the default TopComponent persistence

You've probably noticed that when you restart the application, its layout is not reset to its default state. Instead, the layout settings from the last deployment are reused whenever you restart the application. That is what the user typically expects, though this may be inconvenient during development. During development, if you'd like the default layout to be used when you run the application, you need to select Clean and Build on the application node. This menu item deletes the application's build folder, which contains the testuserdir folder, where the settings from the previous deployment are stored.

It is this feature, that of automatic persistence, that we now look at more closely. In this section, we extend the persistence of our application, as the NetBeans Platform allows us to access the persistence feature and to save additional data when the application is closed.

In the next example, we create a simple form with content that is restored when the application restarts.

  1. Create a new NetBeans Platform application, containing a new module, with a TopComponent created via the New Window wizard. The TopComponent should have PersistenceDemo as its Class Name Prefix, it should be positioned within the editor mode, and it should open when the application starts. Design the content of the new TopComponent as shown the following screenshot:

    The Window System API provides special support for serialization of configuration data. To store configuration data, and to reload them at restart, we need to override the methods writeProperties and readProperties, which are generated by the New Window wizard when you created the Top-Component. These methods are required so that the @ConvertAsProperties annotation, declared at the top of the TopComponent class, is able to generate the code at compile time, persisting the specified settings.

    To fine-tune the TopComponent persistence outlined above, you have two additional values that need to be set, but which are set by default when you use the New Window wizard to create your TopComponent:

    • The value returned by the preferredID() method. The returned value uniquely identifies the TopComponent to the window system.
    • The value returned by the getPersistenceType method. This value determines the conditions under which the TopComponent is persisted. The value TopComponent.PERSISTENCE_ALWAYS specifies that the content of the TopComponent will be persisted, in so far as you have specified settings for persistence. PERSISTENCE_NEVER specifies that when the application closes, nothing set in the TopComponent will be persisted. Finally, PERSISTENCE_ONLY_OPENED specifies that a TopComponent is only persisted if it is open when the application shuts down. The latter is useful if the TopComponent is some kind of editor, for example, as in the cases of the editor windows in NetBeans IDE, which reopen on startup if they had been closed when the application shut down.
  2. Specify that the PersistenceDemoTopComponent should persist if it was open when the application shut down. Next, define the writeProperties and readProperties methods as follows:

    void writeProperties(java.util.Properties p) {
    // better to version settings since initial version as advocated
    // at
    p.setProperty("version", "1.0");
    p.setProperty("element1", jTextField1.getText());
    if (jRadioButton1.isSelected()) {
    p.setProperty("element2", "1");
       if (jRadioButton2.isSelected()) {
           p.setProperty("element2", "2");
       if (jRadioButton3.isSelected()) {
           p.setProperty("element2", "3");
       p.setProperty("element3", String.valueOf(jCheckBox1.isSelected()));
       p.setProperty("element4", String.valueOf(jSlider1.getValue()));
    Object readProperties(java.util.Properties p) {
       if (instance == null) {
           instance = this;
       return instance;
    private void readPropertiesImpl(java.util.Properties p) {
       String version = p.getProperty("version");
       if (p.getProperty("element2").equals("1")) {
       if (p.getProperty("element2").equals("2")) {
       if (p.getProperty("element2").equals("3")) {
       if (p.getProperty("element3").equals("true")) {
       } else  {

  3. Restart the application. Enter some values into the TopComponent and then close the application. When you restart the application, notice that the values you specified are restored as shown in the following screenshot:

When you close the application, do a Clean and Build on the TaskManager project node. Then, now that the application user directory is removed, restart the application and notice that all the values are set back to their defaults.

In summary, you have extended the persistence of the TopComponent, so that the values specified in the TopComponent at the time the application shuts down are restored when the application is restarted.


In this two-part article series you have been introduced to all of the most important topics relating to working with the NetBeans Window System. Not only did you learn how to create new windows, that is, TopComponents, but you also learned how to position them, group them, and extend their persistence.

Further resources on this subject:

You've been reading an excerpt of:

NetBeans Platform 6.9 Developer's Guide

Explore Title
comments powered by Disqus