Archive

Archive for the ‘NB Platform’ Category

Custom Properties in NB Platform Application Config File (app.conf)

Since NetBeans V6.9 there’s a new property app.conf (project.properties) to configure a custom application configuration file. Geertjan wrote about that.

The default configuration file (from harness/etc/app.conf) looks like this (some lines are omitted):

# ${HOME} will be replaced by user home directory according to platform
default_userdir="${HOME}/.${APPNAME}/dev"

# options used by the launcher by default, can be overridden by explicit
# command line switches
default_options="--branding ${branding.token} -J-Xms24m -J-Xmx64m"

Unfortunately, only the property branding.token is supported by the Ant distribution task! But I want include other well known properties like app.version to my custom configuration file to define default_userdir more flexible like

# ${HOME} will be replaced by user home directory according to platform
default_userdir="${HOME}/.${APPNAME}/${app.version}"

To achieve this, only a small patch in the build.xml is needed. I have to override the Ant target “build-launchers” (from harness/suite.xml):

<project name="MyApp" basedir=".">
   ...
   <target name="build-launchers" depends="suite.build-launchers">
      <replace file="${build.launcher.dir}/etc/${app.name}.conf" 
               token="$${app.version}" value="${app.version}"/>
   </target>
</project>

Now when I run the ZIP target, my own configuration file is used and the application version property is replaced by the value from the project.properties:

# ${HOME} will be replaced by user home directory according to platform
default_userdir="${HOME}/.${APPNAME}/1.1"
Categories: Java, NB Platform, NetBeans Tags: ,

Toolbar buttons with label

2012-04-16 6 comments

As default, any action in a NetBeans toolbar is displayed with an icon only. If you want to show also a label for a desired action you have to implement a Presenter.TOOLBAR. If you don’t want do this for each action, register a custom org.openide.awt.Actions.ButtonActionConnector like this:

/**
 * @see org.openide.awt.Actions#connect(AbstractButton, Action)
 */
@ServiceProvider(service = ButtonActionConnector.class, position = 100)
public class MyButtonActionConnector implements ButtonActionConnector {

   @Override
   public boolean connect(AbstractButton button, Action action) {
      String text = (String)action.getValue("menuText"); // NOI18N
      if (text != null) {
         button.setAction(action);
         button.setText(Actions.cutAmpersand(text));
         String desc = (String)action.getValue(Action.SHORT_DESCRIPTION);
         if (desc != null) {
            button.setToolTipText(desc);
         } else {
            button.setToolTipText((String)action.getValue(Action.NAME));
         }
         return true;
      }
      return false;
   }

   @Override
   public boolean connect(JMenuItem item, Action action, boolean popup) {
      return false; // use default implementation
   }
}

If the property menuText is set, the the button is configured with icon and text. The basic use of the menuText Property is (copied from @ActionRegistration‘s javadoc):

Provides the JMenuItem text if one wants to use other than the name of the action returned by ActionRegistration.displayName().

With the custom ButtonActionConnector this property is “extended” to show a toolbar button text if supplied.

Provide a value for the @ActionRegistration’s menuText Attribute for the desired action(s):

@ActionRegistration(displayName = "#CTL_PwdChangeAction",
                    menuText = "#CTL_PwdChangeAction",
                    iconBase = "resources/key.png")
@ActionReference(path = "Toolbars/User")
@Messages("CTL_PwdChangeAction=Change Password…")
public final class PwdChangeAction implements ActionListener {
   ...
}

Result:

or

Tested with NetBeans 7.1.1 (see comments)

Fastest way to clear the Lookup contents

Suppose you have an AbstractLookup with a registered InstanceContent:

InstanceContent ic = new InstanceContent();
Lookup lkp = new AbstractLookup(ic);

The fastest way to clear all the Lookup contents:

ic.set(Collections.emptyList(), null);

Now I’m looking for a convenience command to remove all instances of a given type. I want to replace this code:

for (MyClass my : lkp.lookupAll(MyClass.class)) {  
   ic.remove(my);
}

Perhaps someone has an idea?

Categories: Java, NB Platform, NetBeans Tags:

Dynamically show/hide individual toolbars

In NetBeans you can define your own toolbar configurations (a set of visible/invisible toolbars). DevFaqHideShowToolbar shows you how you can activate a specific toolbar configuration at runtime. But how can I show an individual toolbar dynamically? For example, to show/hide certain toolbar(s) by the visibility of a TopComponent.

An explicit Toolbar API isn’t available in the NetBeans Platform. The class org.openide.awt.ToolbarPool is used to install and update the configured toolbars. With the constructor public ToolbarPool(DataFolder df) an own toolbar configuration at the specified location in the layer.xml (DataFolder) can be created.

But I don’t want create a new toolbar configuration for each TopComponent who should have their own toolbars. The idea is:

  1. Declare the toolbar for the TopComponent at a certain location (!= Toolbars/) in the module’s layer.xml
  2. Register the toolbar in the active toolbar configuration
  3. show the toolbar on TopComponent#componentOpened()
  4. hide the toolbar on TopComponent#componentClosed()

All these steps should be performed dynamically at runtime. How can I achieve this? Let’s go ahead…

Declare the toolbar

<!-- file: layer.xml -->
<filesystem>
   ...
   <folder name="MyModule">
      <folder name="Toolbars">
         <folder name="MyToolbar">
            <attr name="displayName" stringvalue="My Toolbar" />
            <file name="my-action-1.instance">
               ...
            </file>
         </folder>
      </folder>
   </folder>
</filesystem>

Register the toolbar in the active toolbar configuration
Using a shadow entry any custom toolbar is registered once in the default toolbar pool (at Toolbars/):

public static boolean registerToolbar(String toolbarConfigPath) {
   try {
      FileObject fo = FileUtil.getConfigFile(toolbarConfigPath);
      if (fo == null) {
         return false;
      }
      DataFolder df = DataFolder.findFolder(fo);
      DataFolder target = ToolbarPool.getDefault().getFolder();
      FileObject targetFO = target.getPrimaryFile().getFileObject(fo.getNameExt() + ".shadow");

      if (df != null && targetFO == null) {
         DataShadow ds = df.createShadow(target);
         return true;
      }
   } catch (IOException ex) {
      Exceptions.printStackTrace(ex);
   }
   return false;
}

Show/hide the toolbar
For programatically hide and show a toolbar you can write:

Toolbar toolbar = ToolbarPool.getDefault().findToolbar("MyToolbar");
toolbar.getParent().setVisible(false);

The drawback is that the visible state of the toolbar will not be propagated to the toolbar context menu actions.

After debugging I found this solution (or hack):

public static void setToolbarVisible(Toolbar toolbar, boolean visible) {
   try {
      ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);
      Class cToolbarConfiguration = cl.loadClass("org.netbeans.core.windows.view.ui.toolbars.ToolbarConfiguration");
      // invoke static ToolbarConfiguration.findConfiguration( String name)
      Object toolbarConfig = cToolbarConfiguration.getMethod("findConfiguration", String.class).
              invoke(cToolbarConfiguration, "Standard");
      // invoke ToolbarConfiguration#setToolbarVisible( Toolbar tb, boolean visible)
      toolbarConfig.getClass().getMethod("setToolbarVisible", Toolbar.class, boolean.class).invoke(toolbarConfig, toolbar, visible);
   } catch (Exception ex) {
      throw new IllegalArgumentException(ex);
   }
}

Link the toolbar together with the TopComponent’s visibility state (simplified):

String toolbarName = "MyToolbar";

public final void componentOpened() {
   ToolbarUtil.registerToolbar("MyModule/Toolbars/" + toolbarName);
   ToolbarUtil.setToolbarVisible(toolbarName, true);
}

public final void componentClosed() {
  ToolbarUtil.setToolbarVisible(toolbarName, false);
}
Categories: Java, NB Platform, NetBeans Tags: ,

Simple Validation API & DialogDescriptor

This post shows you how the Simple Validation API (HowTo, Project@Kenai) can be used together with a NetBeans Platform standard dialog (using a DialogDescriptor).

The Simple Validation API gives you a convenience method to show a dialog like (excerpt from the BasicDemo):

JPanel panel = new JPanel();
... // setup panel

ValidationPanel vp = new ValidationPanel();
vp.setInnerComponent(panel);
... // setup validation

// Convenience method to show a simple dialog
if (vp.showOkCancelDialog("URL")) {
   System.exit(0);
} else {
   System.exit(1);
}

To use a standard NetBeans Platform dialog, the sample above can be replaced with:

... // as above
DialogDescriptor dd = ValidationUtil.createDialogDescriptor(vp, panel, "URL");
Object ret = DialogDisplayer.getDefault().notify(dd);
if (DialogDescriptor.OK_OPTION.equals(ret)) {
   System.exit(0);
} else {
   System.exit(1);
}
public class ValidationUtil {

   private ValidationUtil() {
      // default constructor suppressed for non-instantiability
   }

   public static DialogDescriptor createDialogDescriptor(ValidationPanel vp, Object innerPane, String title) {
      final DialogDescriptor dd = new DialogDescriptor(innerPane, title);

      ValidationUI okButtonEnabler = new ValidationUI() {
         private NotificationLineSupport nls = dd.createNotificationLineSupport();

         public void showProblem(Problem problem) {
            if (problem != null) {
               switch (problem.severity()) {
                  case FATAL:
                     nls.setErrorMessage(problem.getMessage());
                     dd.setValid(false);
                     break;
                  case WARNING:
                     nls.setWarningMessage(problem.getMessage());
                     dd.setValid(true);
                     break;
                  default:
                     nls.setInformationMessage(problem.getMessage());
                     dd.setValid(true);
               }
            } else {
               nls.clearMessages();
               dd.setValid(true);
            }
         }

         public void clearProblem() {
            showProblem(null);
         }
      };

      vp.getValidationGroup().addUI(okButtonEnabler);
      vp.getValidationGroup().performValidation();
      return dd;
   }
}

Custom Toolbar Configuration

2010-08-19 6 comments

In my first NetBeans Platform post I show you how you can change the default toolbar configuration of your NetBeans Platform application:

  • Change the default toolbar icon size to 16px
  • Right aligned toolbar
  • Non-floating toolbar
  • Create your own set of Toolbar configuration

After reading this article about general toolbar configurations and some investigation in the NetBeans Platform source code I found the solution for the items above. The improved DTD for toolbar configuration (version 1.1) introduced with NetBeans V6.7 allows you to use the new attributes “align” and “dragable”, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar 1.1//EN"
 "http://www.netbeans.org/dtds/toolbar1_1.dtd">
<Configuration>
   <Row>
      <Toolbar name="File" visible="true" />
      <Toolbar name="Clipboard" visible="false"/>
      <Toolbar name="UndoRedo" visible="false"/>
      <Toolbar name="Memory" visible="true" draggable="false" align="right"/>
      <Toolbar name="Picture" visible="true" draggable="false" align="right"/>
   </Row>
</Configuration>

Overwrite the default toolbar configuration in the layer.xml:

<!-- http://wiki.netbeans.org/DevFaqHideShowToolbar -->
<!-- http://blogs.sun.com/geertjan/entry/toolbar_configurations -->
<folder name="Toolbars">
   <file name="MyToolbars.xml" url="res/MyToolbars.xml">
      <attr name="position" intvalue="100"/>
   </file>
</folder>

A NetBeans Platform application comes with the two toolbar sets:

  • Default
  • Debugging

In the example configuration above I created a new one named “MyToolbars”.

Now I want “MyToolbars” as my default toolbar configuration. Additionally I need to have 16px icons as default.
To achieve this, write a custom Window Manager Properties file:

<!-- File: res/windowManager.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE windowmanager PUBLIC
          "-//NetBeans//DTD Window Manager Properties 2.1//EN"
          "http://www.netbeans.org/dtds/windowmanager-properties2_1.dtd">

<windowmanager version="2.1">
   <main-window> 
      <joined-properties centered-horizontally="true" centered-vertically="true"
                           relative-width="0.9" relative-height="0.9" />
      <separated-properties centered-horizontally="true" relative-y="0.1"
                           relative-width="0.8" relative-height="0.08" />
   </main-window>
   <editor-area state="joined">
      <constraints>
         <path orientation="horizontal" number="60" weight="0.7" />
         <path orientation="vertical" number="40" weight="0.7" />
         <path orientation="horizontal" number="40" weight="0.7" />
      </constraints>
      <relative-bounds x="33" y="24" width="42" height="44"/>
   </editor-area>
   <screen width="1280" height="1024" />
   <active-mode name="explorer" />
   <maximized-mode name="" />
   <toolbar configuration="MyToolbars" preferred-icon-size="16" />
</windowmanager>

… and registered in the layer.xml:

<folder name="Windows2">          
   <file name="WindowManager.wswmgr" url="res/windowManager.xml" />
</folder>
Categories: NB Platform Tags: ,