Thursday Mar 08, 2012

Plug A JideTabbedPane into the NetBeans Platform

The JIDE Common Layer, which is an open source product, has some nicely configurable tabbed panes that can now, following the instructions introduced yesterday, be used in NetBeans Platform applications. Here are some examples:

And here's two examples of more generic NetBeans Platform applications using the JideTabbedPane:

Note that only the appearance is different. The behavior is unchanged, for example, when you right-click a tab, you get all the standard NetBeans Platform window system functionality, which functions exactly as before:


A great thing with the JideTabbedPane is that the shape and color of the tabs can be configured via simple calls, such as these:

setColorTheme(JideTabbedPane.COLOR_THEME_WINXP);
setTabShape(JideTabbedPane.SHAPE_ECLIPSE);

Your JideTabbedPane can also implement JideTabbedPane.ColorProvider or JideTabbedPane.GradientColorProvider to provide colors for the tab.

If JavaFX were to have its own JTabbedPane, I guess that could be used in the NetBeans Platform too.

Here's the Paint Application with JideTabbedPanes:


Basically, depending on your needs, and the time you want to invest in figuring out how to make it all work exactly as you'd like, the tabs in your NetBeans Platform application can look precisely how you'd like them to look, from NetBeans Platform 7.2 onwards. At that stage, anyone will be able to create a plugin for NetBeans IDE, or any other application on NetBeans Platform 7.2, that will override the existing tabs with new tabs, such as those provided by JIDE.

Wednesday Mar 07, 2012

Plug A Custom BasicTabbedPaneUI into the NetBeans Platform

Even better than the multi-row editor tabs in the upcoming NetBeans IDE 7.2 is how this new feature has been implemented. I guess Stan Aubrecht, the NetBeans window system engineer, must have thought: "If anyone ever wants a different tab layout ever again, they're just going to have to create it themselves!"

In a pluggable system, a thought like the above is supported very well indeed and so the NetBeans Platform now allows custom implementations of tab control. In a NetBeans module, I created the class below:

import org.netbeans.core.windows.view.ui.tabcontrol.JTabbedPaneAdapter;
import org.netbeans.swing.tabcontrol.WinsysInfoForTabbedContainer;
import org.netbeans.swing.tabcontrol.customtabs.Tabbed;
import org.netbeans.swing.tabcontrol.customtabs.TabbedComponentFactory;
import org.netbeans.swing.tabcontrol.customtabs.TabbedType;
import org.openide.util.lookup.ServiceProvider;

@ServiceProvider(service = TabbedComponentFactory.class, position = 500)
public class CustomTabbedPaneFactory implements TabbedComponentFactory {

    @Override
    public Tabbed createTabbedComponent(TabbedType type, WinsysInfoForTabbedContainer info) {
        JTabbedPaneAdapter tabPane = new JTabbedPaneAdapter(type, info);
        tabPane.setUI(new PlasticTabbedPaneUI());
        return tabPane.getTabbed();
    }
    
}

And the result (because the 'position' attribute above is lower than the position of the NetBeans Platform's own BasicTabbedPaneUI):

The PlasticTabbedPaneUI is not my own—if you want to play with this and other tab displays, see this very useful blog entry which has several different examples, including a JAR that contains them all. (And here is a useful article.)

Thursday Dec 22, 2011

Singleton/Non-Singleton TopComponent via Annotations

This is a TopComponent with the annotations created by the New Window wizard:

import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;

@TopComponent.Description(preferredID = "MySingletonTopComponent",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.test.module.MySingletonTopComponent")
@ActionReference(path = "Menu/Window")
@TopComponent.OpenActionRegistration(displayName = "#CTL_MySingletonAction",
preferredID = "MySingletonTopComponent")
@NbBundle.Messages({
    "CTL_MySingletonAction=MySingleton",
    "CTL_MySingletonTopComponent=MySingleton Window",
    "HINT_MySingletonTopComponent=This is a MySingleton window"
})
public class MySingletonTopComponent extends TopComponent {
 
     public MySingletonTopComponent() {

        setName(Bundle.CTL_MySingletonTopComponent());
        setToolTipText(Bundle.HINT_MySingletonTopComponent());

    }
 
}

However, I don't always want a singleton. So, if you change the annotations slightly, you have a non-singleton. All I did was remove the "preferredID" from the @TopComponent.OpenActionRegistration annotation (i.e., the bit you see in bold above) and now I can open multiple instances of the TopComponent below:

import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;

@TopComponent.Description(preferredID = "MyInstanceTopComponent",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.test.module.MyInstanceTopComponent")
@ActionReference(path = "Menu/Window")
@TopComponent.OpenActionRegistration(displayName = "#CTL_MyInstanceTopComponentAction")
@Messages({
    "CTL_MyInstanceTopComponentAction=MyInstance",
    "CTL_MyInstanceTopComponent=MyInstance Window",
    "HINT_MyInstanceTopComponent=This is a MyInstance window"
})
public final class MyInstanceTopComponent extends TopComponent {

    public MyInstanceTopComponent() {

        setName(Bundle.CTL_MyInstanceTopComponent());
        setToolTipText(Bundle.HINT_MyInstanceTopComponent());

    }

}

Probably it means that the Action is unable to find the existing instance of the TopComponent, since it doesn't know its ID, and therefore creates a new one.

Thursday Oct 13, 2011

Window System in 7.1

Trying to build up a complete list of all the enhancements in the NetBeans window system in 7.1.

  • Roles. There's support for roles/perspectives/profiles in NetBeans Platform 7.1, for the first time, as I wrote earlier in this blog. That's good news, now window layouts can be stored/retrieved per user. What's less good news is that this is limited to the window system, i.e., would have been nice to have had the entire file system be available on a per-user basis, e.g., some Actions are relevant to Admin users, while others aren't. Though other solutions exist in the NetBeans Platform for solving this scenario, it would have been nice if it had been included in the "roles" enhancement.

  • Modes. New mode "topSlidingSide", i.e., that lets you minimize a TopComponent above the window display area, in addition to the existing "leftSlidingSide", "rightSlidingSide", and "bottomSlidingSide", and you can drag and drop TopComponents into that area, as done below for the Projects window, Services window, and Files window:



  • Groups. For TopComponents found in the same "view" mode—e.g., in the "explorer" mode, which is a "view" mode, you have "Projects window", "Files window", and "Services window", as shown below—there are now new menu items, available when you click to the right of the TopComponent tabs, for manipulating the group as one unit:

    ">

    Above, you can see that a number of menu items are disabled, since they do not relate to the current context, which is group behavior, since we didn't select a specific TopComponent but, rather, to the right of the tabs of the TopComponents, i.e., in the brand new "group tab area". So, above, the "Move" action is disabled, since it would only make sense when a single TopComponent is selected, rather than a group, as shown below:



    Above, the majority of the menu items are enabled, since here we right-clicked on an individual TopComponent's tab, rather than to the right of the tabs, in the brand new "group tab area", which is what the earlier screenshot showed.

    So, that's the new behavior for "view" modes. Modes of kind "editor" are different, they've always had different behavior to "view" modes. E.g., TopComponents in "view" modes can be minimized, while TopComponents in "editor" modes can be cloned. That's logical functionality, i.e., it makes no sense to clone (i.e., create a splitter) for the Projects window, while split pane functionality for editor documents is something that is often needed.



    You can see new behavior above for TopComponents in "editor" modes, too. (There's always only one "editor" mode, as far as I am aware, by the way, with multiple editor documents docked within it.) You can now create separated "Document Tab Groups", which then have behavior dedicated to the group, such as the ability for the documents within the tab group to be floated out of the main frame of the application together.

    In the same way as there is a new "group tab area" to the right of TopComponent tabs in "view" modes, there is also such an area to the right of the tabs of TopComponents in "editor" modes.

    Something that's interesting, and possibly unintentional, is that you can now, for the first time, drag TopComponents from "view" modes into "editor" modes, and vice versa:



  • Tools. When you create a new TopComponent via the Window wizard, you'll see a new button to the right of the "Window Position" drop-down, letting you create your own new mode or customize one of those that already exist. Another entry point into the same functionality is the new "Layout of Windows" template in the New File dialog. I blogged earlier about this new template here.

  • Terminology. The term "undock" is replaced by "float". So, where in the past you would dock/undock a TopComponent from the main window, you now dock/float a TopComponent or a group of TopComponents from the main window. Another new term is "Document Tab Group".

A related enhancement is the pluggability of multiview components, though that relates to a completely different API. So, above you see all the window system enhancements of which I am personally aware. Probably there are a few others, hoping I'll be enlightened about these soon.

Friday Aug 19, 2011

NetBeans IDE 7.1 Window Layout Designer

In 7.1, you'll see this in the New File dialog:

I.e., as you can see, there'll be two new file templates. One for creating & registering a new layer file (hurray!), which you'll not be able to create when you create a new module. That's good, because you'll only have a layer file when you actually need it.

Secondly, you'll see the "Layout of Windows" wizard, which will be very useful when you're creating your own modes. When you step through the wizard, this dialog will appear, where you're able to create new modes:

For example, as you can see below, I have added two new modes ("banner1" and "banner2") and positioned them (using drag and drop) within the frame of the application:

When I close the window that you see above, the wizard recognizes that there are two new modes, as you can see below:

Then, when you click Next above, you can see that two new mode files will be created, and that the layer file will be changed, i.e., those two new mode files will be registered in the layer file when the wizard completes:

And, here you can see what is found in my module when the wizard completes:

Therefore, when I create new windows, I can now choose the new modes I designed above:

That should take some of the pain away when designing the layout of your applications on the NetBeans Platform.


Tuesday Jun 07, 2011

Visual Editor for Window System Layout

Issue 198318 indicates work is being done on a much needed Visual Editor for Window System Layout. The bane of many developers' lives revolves around figuring out how to correctly position & size the windows in their NetBeans Platform application. You need to run the app in development mode, move the windows where you want them, then copy the generated mode files into your module, and register them in your layer.

An early version of the Visual Editor for Window System Layout is already available, though it is not the final version. However, it does the basics of what I'd expect, simply automating the procedure above. Here you see it, constructed by doing a hg clone of NetBeans main, with the two diffs from the issue above integrated: 

The above is available when you click the "Redefine..." button below:

You can then move existing modes around, as well as create new ones, which can then be positioned via drag-and-drop in the window system:

Immediately you're done with the above, you'll see your new modes available in the "Window Position" drop-down and when the wizard completes you'll have newly created modes in your module, registered in your layer:

Again, note that this is an early version and that it will not be supported. I.e., if you put it together and start using it, you're on your own, and you'll not be able to report bugs against it. However, for the desperate, it's something, though, again, not much, since it is not an official solution. If you need something like it, something actually supported, go to the issue above and state your needs.

Friday Oct 20, 2006

Creating a New Window Group

In the IDE, when you're involved in GUI editing, several helper windows open together with the Design mode of the editor. For example, when you open a TopComponent in Design mode, the Palette and the Properties window open too. However, if you had previously opened the TopComponent in Design mode and closed the Palette, the Palette isn't opened when next you open the TopComponent. Basically, the helper windows (i.e., in this case, the Palette and Properties window) are only open if you had them open previously, on the assumption that their previous open/closed state are the ones you would like to maintain.

If you had to code that for all your windows, it would be something like this in pseudo code:

 

if (TopComponentA is opened) {
   if (HelperTopComponentB was open previously and is now closed) {
         HelperTopComponentB must open again
   }
   if (HelperTopComponentC was open previously and is now closed) {
         HelperTopComponentC must open again
   }
}

That would be a lot of cumbersome work, since the above is only for the opening of the TopComponent; there'd have to be something similar for closing the TopComponent. Wouldn't it be cool if I could create a group of components and then simply do this:

 

group.open();

And, then, later, when I close a TopComponent, I would simply call this:

 

group.close();

Then, all the opened and closed helper windows would be saved in whatever state they're in, automatically, without me having to think about it. Now, that would be cool. Hmmm... I think I should create an issue in Issuezilla for this. Okay, let's do that. Oops. Wait. Section 2.3 of the "New Window System API Changes" is titled "Window Groups". That's, in fact, exactly what I was looking for... So, three cheers for Interface TopComponentGroup.

So, if you go to config/Windows2Local in your user directory, you should see (after closing the IDE at least once) the following:

In the previous two blog entries, I wrote about the "Modes" folder above. The first blog entry was about creating a new mode. The second was about two modes sharing the 'editor' area of the IDE (or of another application based on the NetBeans Platform). This time, let's look at the "Groups" folder. If you open the "Groups" folder, one of the subfolders is called "debugger". It contains files for 9 TopComponents, which are all opened at the same time when a debug process begins and closed at the same time when it ends.

Let's create our own group, add two TopComponents, and then open the TopComponents simultaneously.

 

     

  1. Create a new module project, with org.netbeans.modules.windowgroupsample as the code name base.

     

  2. Use the Window Component wizard twice, to create two TopComponents. In the first page of the wizard, choose "editor" for the first and "output" for the second (or anything else, it really doesn't matter). Make sure that you don't select the checkbox, so that the TopComponent won't be shown at start up. Let's say the first is called "OneTopComponent" and the second "TwoTopComponent" (which means you should type "One" and "Two" as the prefix in the wizard) and we'll put them both in the main package.

     

  3. Now we're going to create the window group. Right-click the top package, create a new XML document called "MyGroupWsgrp.xml", within a new subpackage called "groups". Add a subpackage to the new group and call that subpackage "MyGroup". Inside of it, create two XML documents, one called "OneTopComponentWstcgrp.xml" and the other "TwoTopComponentWstcgrp.xml". You should now see this in the Projects window:

     

  4. Next, put this in "MyGroupWsgrp.xml":

     

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE group PUBLIC
      "-//NetBeans//DTD Group Properties 2.0//EN"
      "http://www.netbeans.org/dtds/group-properties2_0.dtd">
    
    <group version="2.0">
        <module name="org.netbeans.modules.windowgroupsample" spec="1.0" />
        <name unique="MyGroup" />
        <state opened="false" />
    </group>

    Note: The value of the state element above specifies that the group will be closed, by default, when the application starts up.

     

  5. In "OneTopComponentWstcgrp.xml", change the content to this:

     

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE tc-group PUBLIC
      "-//NetBeans//DTD Top Component in Group Properties 2.0//EN"
      "http://www.netbeans.org/dtds/tc-group2_0.dtd">
    
    <tc-group version="2.0">
        <module name="org.netbeans.modules.windowgroupsample" spec="1.0"/>
        <tc-id id="OneTopComponent" />
        <open-close-behavior open="true" close="true" />
    </tc-group>

    Note 1: The value of the tc-id element must match the value of the PREFERRED_ID String that was generated in your TopComponent, when you finished the Window Component wizard. Have a look, and notice that the two match.

    Note 2: The values of the open-close-behavior element are the flags that indicate what will happen when group.open() and group.close() are called. For example, if the open attribute is set to "true", then by default the TopComponent will open when the group opens.

    Similar to the above, change the content of "TwoTopComponentWstcgrp.xml" to this:

     

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE tc-group PUBLIC
      "-//NetBeans//DTD Top Component in Group Properties 2.0//EN"
      "http://www.netbeans.org/dtds/tc-group2_0.dtd">
    
    <tc-group version="2.0">
        <module name="org.netbeans.modules.windowgroupsample" spec="1.0"/>
        <tc-id id="TwoTopComponent" />
        <open-close-behavior open="true" close="true" />
    </tc-group>

     

  6. Now we will register our new group in the XML Layer. Open the XML Layer and notice the Windows2 section at the end (all generated when you created your two TopComponents). Add the highlighted section below, to register our new group:

     

    <folder name="Windows2">
        <folder name="Components">
            <file name="OneTopComponent.settings" url="OneTopComponentSettings.xml"/>
            <file name="TwoTopComponent.settings" url="TwoTopComponentSettings.xml"/>
        </folder>
        <folder name="Modes">
            <folder name="editor">
                <file name="OneTopComponent.wstcref" url="OneTopComponentWstcref.xml"/>
            </folder>
            <folder name="output">
                <file name="TwoTopComponent.wstcref" url="TwoTopComponentWstcref.xml"/>
            </folder>
        </folder>
        <folder name="Groups">
            <file name="MyGroup.wsgrp" url="groups/MyGroupWsgrp.xml"/>
            <folder name="MyGroup">
                <file name="OneTopComponent.wstcgrp" url="groups/MyGroup/OneTopComponentWstcgrp.xml"/>
                <file name="TwoTopComponent.wstcgrp" url="groups/MyGroup/TwoTopComponentWstcgrp.xml"/>
            </folder>
        </folder>
    </folder>

     

  7. Save everything. Don't install the module yet, let's first refresh all our window positions to their defaults (just in case you've moved things around and things go wrong later, best to have everything at their defaults so that we can analyze the situation better). Close the IDE. Go to the user directory and delete the Windows2Local folder in the user directory's config folder.

     

  8. Start the IDE again. Install the module in the IDE. Close the IDE. Go back to the Windows2Local folder and, when you open the Groups folder, you should now see your new group definition file as well as a folder, containing a file for each of the two TopComponents that belongs to the group (according to your registration entries in the XML Layer):

     

  9. Now start the IDE again. Use the New Action wizard twice. The first time, create "ShowMyGroupAction" and stick this in the performAction() event:

     

    TopComponentGroup group = WindowManager.getDefault().findTopComponentGroup("MyGroup");
    if (group == null) {
        return;
    }
    group.open();

    Put the cursor on the first line above and, when the lightbulb appears, let the IDE generate import statements for these packages:

     

    import org.openide.windows.TopComponentGroup;
    import org.openide.windows.WindowManager;

    The second time you use the New Action wizard, create "HideMyGroupAction" and stick the following into the performAction() event:

     

    TopComponentGroup group = WindowManager.getDefault().findTopComponentGroup("MyGroup");
    if (group == null) {
        return;
    }
    group.close();

    Again let the IDE generate import statements for the two required packages.

     

  10. Install the module again. Now you can use the menu items to show and hide both TopComponents simultaneously. There's a lot of variations that apply here. If you close one of them after opening both, it will not be opened next time you use the menu item for showing both. And that's only one example of the way the Window System API now does all the thinking for you.

Read Section 2.3, where you'll find 5 scenarios and the ways that the open/close state of the windows is handled for you.

About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today