layer.xml

a netbeans rcp blog

Work quicker in NetBeans

Posted by Nicklas Löf on July 12, 2011

Usually I’m writing about NetBeans RCP applications but this time it will be about NetBeans as an IDE. I’m going to share some tricks I use daily to work faster when writing code.

alt+enter

This is the ultimate shortcut that everyone should know about and use. It triggers different behaviors depending on where it’s executed. Normally it’s used to bring up the “light bulb-menu” that shows errors, warnings and hints that is shown on the left part of the editor. So there is no need to find your mouse and move it over there and click on it. Just hit alt+enter and the menu is shown.

Assign to a variable

If you, for example, has called a getter-method you can assign the returned object to a variable quickly by hitting alt+enter and NetBeans IDE will automatically lookup the type and create a variable for you.

Adding fields quickly.

If you have a constructor that takes a parameter you can hit alt+enter when the cursor is placed over the parameter and NetBeans will both add a this.variable = variable  to the constructor body and also create the field needed in the class (as a private final).

ctrl+space

Another time saver and a great way to explore the APIs. I guess most people knows about this one but maybe not all the features.

The basic usage is to quickly lookup what Object you can create and what methods that are available on an object. So after you have type new just hit ctrl+space and it will show a list of all aviable classes that you can create an instance of and it will filter the list while you type. And to show the methods available on an object just hit ctrl+space after the dot and those will be shown with the javadoc. So this is something most people knows about and use ctrl+space for..  but there is more!

Auto generate variable names

If you for example adds a new variable in a constructor just enter the type and ctrl+space and NetBeans will show a few example of the variable name that you can use. This also work in the body of a method.

Override methods.

If you place the cursor outside a method body and hit ctrl+space it will show a list of available methods that can be overridden if you class is extending another class for example. And it’s clever enough and just shows the ones you haven’t override already.

Create getter and setters.

Just like the example above. Place the cursor outside a method and hit ctrl+space and start type get or set and it will show a list of getters and setters it can create for fields in your class that doesn’t have ones yet.

Constructors

Hit ctrl+space and type the name of your class and it can autogenerate the constructor. And if you have fields in the class that can be populated from the constructor the different alternates of constructors is shown too.

Camel casing.

All the filter-while-your-type can be camel cased. So if you are looking for ArrayList you don’t have to type Arra.. to see it in the drop down menu. Just type AL and NetBeans will automatically try to match that to ArrayList. (or HMap for HashMap..  and so on)

Code Templates

NetBeans IDE has many predefined code templates that not only will generate a small block of code for you,it will also generate the code based on the current context and tries to autofill types and variables for you. There is lots of them available and to see a list of all just open up the Options window and look in Editor and the tab Code templates. Here you can also add your own ones.

fore

This is my favourite. It saves lot of time while creating for each loops. Type fore and tab once. Now you can see the basic structure of a for each loop. NetBeans tries to lookup and Collections in the class you are editing and sometimes it gets it right and sometimes now. But instead of correcting the type, variable name and the collection by hand just hit tab twice and you will be placed in the collection field. Here you can now start typing the name of the collection (use ctrl+space to quickly see and filter ones that are available) and when you have selected the collection you want it will automatically change the type and variable name. And you aren’t limited to Collections in the current class. You can call for an static method somewhere else in your application that returns a Collection and NetBeans will automatically generate the loop your you.

fori

Like above but quickly create for (int i=0….)-loops.

lkp

(Thanks to my collegaue Eric Aili that showed me this one yesterday). Just type lkp + tab and start to enter the Type you want to query the Global lookup for and NetBeans will auto generate the Lookup call, the Type and variable name.

newo

Like the one above but for creating new objects of a class. Type newo + tab and enter the Type and the rest is autogenerated.

Insert

This one is shown if you hit alt+insert (ctrl+i on Mac) and shows a list of things that NetBeans can automatically create and insert for you in the current class.

Getter and Setters

Quickly populate the class with all the getters and setters. When it’s selected it will show a window with all fields in the class that currently doesn’t have a getter or setter. With the checkboxes you can selected which fields you want to generate for and after hitting Ok those will be created with the correct types and everything needed. If you just want to create one it might be quicker to use the ctrl+space shortcut shown earlier.

Constructor

Same as above but you can choose which fields in the current class that can be populated from the Constructor method.

Add property

This one can save lot of time if you are creating a new property. It allows you to select the type and the name. The access and if NetBeans should create Getters and Setters for you. And this property mini wizard is especially useful if you are editing a class with propertychange support since it will take care of adding the code to fire the property change in the setter.

Override method

I usually use the ctrl+space way to do this but if I’m not sure excactly what I’m looking for this one is handy since it shows a browsable list of all avalable methods that can be overridden and I can select multiple ones. The drawback from the ctrl+space way is that you can’t see the JavaDoc of the method.

So this is some of the shortcuts and tricks I use daily to speed up writing code and once again..  alt+enter alt+enter alt+enter! Stop finding your mouse when you see the lightbulb and keep the hands on the keyboard.

Posted in Netbeans | 1 Comment »

How to add functionality to NetBeans part 2

Posted by Nicklas Löf on February 28, 2011

In my previous post about how to add functionality into NetBeans I did hard code my FaceBook access token into the class which is a bad idea, especially if you want to share the module with someone else. Luckily NetBeans makes all this very easy to solve.

What APIs are we gonna cover?

  • Preferences
  • Dialogs
  • Lets get started!

    First we need to add a dependency to the Dialogs API by right clicking our module, select properties and in the Library panel add it.

    With that done we gonna modify our FaceBookServiceImpl a bit. We gonna add a private method that will make sure that we have a FaceBook access token set and if it isn’t it’s gonna prompt us for it. We also gonna change the ACCESS_TOKEN variable and call the new method from the constructor. So this is how the modified parts will look like:

    public class FaceBookServiceImpl implements FaceBookService {
    
        private String ACCESS_TOKEN;
        private final InstanceContent instanceContent;
        private final AbstractLookup abstractLookup;
    
        public FaceBookServiceImpl() {
            instanceContent = new InstanceContent();
            abstractLookup = new AbstractLookup(instanceContent);
            initAccessToken();
        }
    
        private void initAccessToken() {
            ACCESS_TOKEN = NbPreferences.forModule(FaceBookServiceImpl.class).get("faceBookAccessToken", "");
            if (ACCESS_TOKEN.isEmpty()) {
                NotifyDescriptor.InputLine i = new NotifyDescriptor.InputLine("Please enter your Facebbok Access Token", "Access token", NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.QUESTION_MESSAGE);
                if (DialogDisplayer.getDefault().notify(i) == NotifyDescriptor.OK_OPTION) {
                    String accesstoken = i.getInputText();
                    if (!accesstoken.isEmpty()) {
                        NbPreferences.forModule(FaceBookService.class).put("faceBookAccessToken", accesstoken);
                        ACCESS_TOKEN = accesstoken;
                    }
                }
            }
        }
        REST OF THE SOURCE FROM PART 1
    }
    

    First of all it calls the Preferences API and asks for the faceBookAccessToken. If it doesn’t exist we will get back an empty String. So now we need to ask the user for the access token. As you can see we doesn’t have to build any UI components here, NetBeans will take care of this with a NotifyDescriptor where we feed it with the title of the window, the text and what buttons should be visible (Ok and Cancel, Yes and No etc..). Then we take this descriptor and gives it to the DialogDisplayer which will wait until the user has done something and if the user did press Ok we can execute some code.

    From the Notifydescriptor we will now get the string the user did enter. If isn’t empty we will store it into our preferences so the next time the application is started the user doesn’t have to enter the same information again. And don’t forget to actually add the access token into the field ACCESS_TOKEN.

    And thats all! Now our module will remember our access token and you can pass this module around to other users even if the way of getting the access token is a bit non user friendly.

    Home work

    What if the user is entering the wrong access token? Then we will end up with no way to re enter it. You could extend the method to make a call to FaceBook trough the RestFB library and make check that it doesn’t give an access denied message and display this to the user and don’t set the preference until it’s a valid access token.

    Posted in Netbeans | Leave a Comment »

    How to add functionality to NetBeans

    Posted by Nicklas Löf on February 26, 2011

    This post will be more of a small tutorial walking trough some of the basic NetBeans APIs that make it possible to add new functionality to NetBeans. The goal is to add a toolbar button into the IDE (or any NetBeans RCP based application) that will show you if you have notifications waiting on Facebook. But the steps taken in this tutorial is not limited to Facebook since that is just a small part in total. You can use everything shown here to build something similar like a Twitter button or a Google reader button showing that there are updates waiting.

    What APIs and functionality are we gonna cover?

    • The module layer file (layer.xml)
    • Actions
    • Lookup – ServiceProvider creation
    • Lookup – Lookup listeners
    • Module Installer
    • And a little bit of Facebook OAuth and FQL (Facebook Query Language)

    Files needed for this tutorial:
    RestFB – A minimal Facebook library with zero dependencies
    Icons – Six icons in 16,24 and 32 icon size versions. I have used “Newsfeed for Chrome” FB icon as base and added red notifications colors to it in GIMP.

    So..  lets get started! First of all we need to create a NetBeans module that can be loaded into the IDE. This is done by creating a new project and select NetBeans Module -> Module. Give it a name and choose that it should be a Standalone module and select the Platform it’s gonna be based on (for example NetBeans IDE 6.9.1) which is there by default if you have 6.9.1. Finally give it a code name base (java package path) and a display name. Finally check the Generate XML layer checkbox.

    Icons

    Before we start enter some code lets copy our resources first which is the icons (link above). In the root package create a new folder and call it resources. Then switch to the file view and select the icons in your operating system file manager (Finder for OSX and Explorer in Windows) and select copy. Then right click the resources folder (when you are in the file view) and select paste and the icons will automatically be copied and included in your project.

    Library

    Now we also need to add the restfb library. Usually it’s done by creating a separate wrapper module but in this case we gonna add it to this module. Switch back to the projects view and right click on the project and select properties. In the libraries display select Wrapped JARs and click add JAR. Browse to the restfb jar file (link above) and it will now be included and distributed together with our module.

    Dependencies

    We also need to specify which modules from the Platform that we gonna depend on. This is done in the Library panel in the module project properties. For this module we need to add Actions APIs, Lookup, Module System API, UI Utilities API and Utilities API.

    Create an action

    All right..  now we have included the icons and the library we need. Now lets start to generate some code… So how do we get a button in the toolbar? By creating an action which is also done by a wizard. So click new and create a new action. Select the action to be Always enabled. Now we need to decide where our button will be visible. Lets put Internet into the Category and uncheck the Global menu item checkbox since we don’t want to have a menu item. Select the global toolbar button checkbox and choose where you want it to be placed. I did choose File and the position to be after the Save all button. Finally give the action a class name and a display name. In this step you also gonna choose the icon for the action. Icons are handled in a clever way in NetBeans as I’m gonna describe a bit further down but to get us started browse to the resource folder and select fbicon.png and none of the other icons.

    Now we have our action ready and by default it implements an actionlistener and all registration is done in the layer.xml file. We need our action to do more things than just launch something when clicked so lets start modify what the wizard generated for us. First remove implements actionlistener and replace it with “extends AbstractAction implements LookupListener” and fix imports. The actionPerformend method can also be removed. Now we need to modify the registration in layer.xml. We gonna remove all the <attr….> tags from the file in Actions/Internet but save the iconBase value since we gonna need to add it into our action code.

    Now lets add all the code needed for our action to display the Facebook action and react on updates. Replace all methods with these ones:

    public final class FaceBookToolbarAction extends AbstractAction implements LookupListener {
    
        private final Lookup lookup;
        private Result<Boolean> lkpInfo;
    
        public FaceBookToolbarAction() {
            this(Lookup.getDefault().lookup(FaceBookService.class).getLookup());
            setEnabled(false);
            putValue("iconBase", "st/rhapsody/facebook/nbtoolbar/resources/fbicon.png");
            putValue(Action.NAME, NbBundle.getMessage(FaceBookToolbarAction.class, "CTL_FaceBookToolbarAction"));
        }
    
        public FaceBookToolbarAction(Lookup lookup) {
            this.lookup = lookup;
            init();
        }
    
        private void init() {
    
            if (lkpInfo != null) {
                return;
            }
            lkpInfo = lookup.lookupResult(Boolean.class);
            lkpInfo.addLookupListener(this);
            resultChanged(null);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
    
            if (Desktop.isDesktopSupported()) {
                try {
                    Desktop.getDesktop().browse(new URI("http://www.facebook.com/notifications.php"));
                } catch (URISyntaxException ex) {
                    Exceptions.printStackTrace(ex);
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }
                updateEnableStatus(false);
            }
        }
    
        @Override
        public void resultChanged(LookupEvent ev) {
            if (lkpInfo.allInstances().size() > 0) {
                for (Boolean notification : lkpInfo.allInstances()) {
                    updateEnableStatus(notification);
                }
            }
        }
    
        private void updateEnableStatus(final boolean enabled) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    setEnabled(enabled);
                }
            });
        }
    }
    

    Replace the String in the iconBase setValue with the value from “iconBase” from your layer.xml file and fix all imports. Now there is some errors left which will be solved soon when we implement our facebookservice that will take care of the communication with Facebook.

    But lets start by explain what the code in the action does. Lets go trough from top to bottom.

    The constructors. The first one is called when NetBeans creates an instance of the action. It will use Lookup to find an instance of FaceBookService.class (that we haven’t created yet). From that instance it will get the lookup and put that into the lookup field so we can listen for changes that happens in the FaceBookService implementation. Then we are setting the action to be disabled. And finally we call init() which will check if the Lookupresult from the FaceBookService is already created and skip the rest of the code. If it isn’t it will ask the FaceBookService lookup for the lookupresult and tells it that we are only interested in getting updates that are of Booleans. And to the result we are adding a looklistener that will be informed each time a change has occurred in the FaceBookService.

    We also put two values into the action. The first one is the base path to the icon and the other one is the name which is picked up from the file Bundle.properties. Why do we pick the name from here? In case your application is shipped in different languages you can provide different translations for Strings which are read from the bundle file instead of being hard coded into the class files.

    actionPerformed(). This is the code that gets executed when the user press the button in the toolbar. And what we want done is opening the notifications page at Facebook which is done with the help of the Desktop class in Java6.

    resultChanged(). this is where all the magic happens. If our lookupresult.allInstances() (which is a collection) is bigger than 0 means that we have an update to show. As you can see we are getting instances of FaceBookUpdate from the result and we are checking if doesNotificationExist() is true or false. If it’s true it means that notifications exists and our action has to be enabled. If it’s false it means that no notifications exists and our action has to be disabled. The status is set in the updateEnableStatus() method.

    Summary: So in short our action will get enabled when there is Facebook notifications and disabled when there is no Facebook notifications. And it will be notified about these changes from an external service so the action itself doesn’t have to execute all the communication code with Facebook.

    How NetBeans are handling icons.

    NetBeans will show different icons if it’s enabled or disabled. But how do we control that from our action? All we did was setting the action enable status. This is the trick. When NetBeans is scanning for the icon (provided by the iconBase) it will also look alternate icons based on the filename. So when it’s looking for fbicon.png it will also look for fbicon24.png and fbicon32.png so we can provide different icons for different sizes. It will also look for icon files with _disabled.png in the filename and use that one when our action is disabled. So all you need to do is provide the basename of the icon and NetBeans will automatically handle what is shown. And this is the trick I’m using here. When our action is disabled it just displays a facebook icon.(fbiconXX_disabled.png) When it gets enabled it will display the normal icon showing a little red square to tell us that we have a notification.

    Facebook service

    Now it’s time to implement the service that will actually do the work by updating the status from Facebook. We could add this code into the action but that’s not very nice. We gonna do it in a better way. As you can see above we are using Lookup to locate an implementation of FaceBookService.class which is an interface. So lets create that interface by adding a new interface to our project and add the following code:

    public interface FaceBookService extends Lookup.Provider {
        @Override
        public Lookup getLookup();
        public void updateNotifications();
    }
    

    And then add a normal java class file that will implement this interface:

    @ServiceProvider(service = FaceBookService.class)
    public class FaceBookServiceImpl implements FaceBookService {
    
        private final InstanceContent instanceContent;
        private final AbstractLookup abstractLookup;
        private static final String ACCESS_TOKEN = "YOUR FACEBOOK ACCESS TOKEN";
    
        public FaceBookServiceImpl() {
            instanceContent = new InstanceContent();
            abstractLookup = new AbstractLookup(instanceContent);
        }
    
        @Override
        public Lookup getLookup() {
            return abstractLookup;
        }
    
        @Override
        public void updateNotifications() {
            FacebookClient facebookClient = new DefaultFacebookClient(ACCESS_TOKEN);
            String query = "SELECT notification_id, href, title_text, app_id, created_time, is_unread FROM notification WHERE recipient_id=me() AND is_unread = 1";
            List<FqlNotification> notifications = facebookClient.executeQuery(query, FqlNotification.class);
            if (notifications.isEmpty()) {
                instanceContent.set(Arrays.asList(Boolean.valueOf("False")), null);
            }else{
                instanceContent.set(Arrays.asList(Boolean.valueOf("True")), null);
            }
        }
    
        public static class FqlNotification {
    
            @Facebook
            String notification_id;
            @Facebook
            String href;
            @Facebook
            String title_text;
            @Facebook
            String app_id;
            @Facebook
            String created_time;
            @Facebook
            String is_unread;
    
            @Override
            public String toString() {
                return "FqlNotification{" + "notification_id=" + notification_id + "href=" + href + "title_text=" + title_text + "app_id=" + app_id + "created_time=" + created_time + "is_unread=" + is_unread + '}';
            }
        }
    }
    

    Lets go trough the class:
    @ServiceProvider This was one of the news in NetBeans 6.9. Earlier you had to do this by editing external files but can now be done by this simple annotation. It tells NetBeans that this class is handled by NetBeans Lookup and a new instance will be created when it’s first called. In our case the init() method in the actions that asks the Lookup for an instance.

    The two fields and getLookup(). These are used to help us to implement a Lookup that other classes can connect to and we can communicate with them from our class. We don’t even have to know who is interested in our lookup as you can see we just provide a getter for the Lookup. (And don’t confuse this Lookup with the ServiceProvider lookup.)

    updateNotifications().This is where we connect to Facebook and checks for updates. We are creating a new instance of the RestFB client and use something called Facebook Query Language which is like SQL but used to query the Facebook API service for information. In our case we are asking for unread notifications. If there are notifications we will create a new instance of Boolean with True and if no notifications exists we will create an a Boolean with false. Everyone that is looking for changes in our lookup will now receive a boolean in the lookupresult.

    ACCESS_TOKEN. This is explained a bit further down.

    Schedule the service to update frequently

    Now there is one last thing to do. To execute our service frequently. The easiest way to do this is to add a hook into the NetBeans lifecycle manager and make sure that our facebookservice gets executed once every minute. Right click the module and create “Installer/Activator”. Here we can control what is happening when our module is loaded. In general modules shouldnt use the installer method because if every module is executing code on NetBeans startup the time it takes to start NetBeans will take more and more time but we will use it anyway in this example ;-)

    public class Installer extends ModuleInstall {
    
        private ScheduledFuture<?> scheduleWithFixedDelay;
        @Override
        public void restored() {
             scheduleWithFixedDelay = Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(new Runnable() {
    
                @Override
                public void run() {
                    Lookup.getDefault().lookup(FaceBookService.class).updateNotifications();
                }
            }, 60, 60, TimeUnit.SECONDS);
        }
    }

    All we do here is creating a new runnable that will make sure that the updateNotifications() method is called once every minute with an initial delay of one minute.

    Facebook Oauth

    And we are done! All that is left to do is connect to facebook and authenticate. Facebook is using something called Oauth2 which means that you will receive an access token that gives a certain application access to use your Facebook account. The instructions below are copied from the RestFB web page and in the end you will have an access token that you can paste into the ACCESS_TOKEN constant in FaceBookServiceImpl. It looks like this: 123|123abc123-123|aBC1 (but much longer). As you have noticed we are hard coding the ACCESS_TOKEN into our module which isn’t good! In my followup to this post I will show how easy it’s to save preferences with NetBeans so the token key can be entered once into the application and then saved. The instructions below can be found at http://restfb.com/

    In order to use these, you’ll need to create a Facebook Application and then request an OAuth access token with the proper permissions, e.g. publish_stream,offline_access,create_event.
    The Facebook Graph API authorization documentation explains how to do this in detail.
    If you’re in a hurry, though, here’s a quick example:
    Create a Facebook Application
    Request https://graph.facebook.com/oauth/authorize?client_id=MY_API_KEY&amp; redirect_uri=http://www.facebook.com/connect/login_success.html& scope=publish_stream,offline_access,create_event
    Facebook will redirect you to http://www.facebook.com/connect/login_success.html? code=MY_VERIFICATION_CODE
    Request https://graph.facebook.com/oauth/access_token?client_id=MY_API_KEY&amp; redirect_uri=http://www.facebook.com/connect/login_success.html& client_secret=MY_APP_SECRET&code=MY_VERIFICATION_CODE
    Facebook will respond with access_token=MY_ACCESS_TOKEN

    And with all this in place this is how my toolbar looks like:

    I will do two follow ups to this post where I will show how to:

  • Make the ACCESS_TOKEN be saved together with the application instead of hard code it into the class file.
  • How to extend so we have a basic internetservice module where we can plugin services (as separate NetBeans modules) that we want to receive notifications from in our toolbar. For example 3 toolbar icons with Facebook, Twitter and Google reader.
  • Install the module into the NetBeans IDE

    One last thing. To install this module into your IDE, right click on the module and select Create NBM. In the output window you will see the path to st-rhapsody-facebook-nbtoolbar.nbm. Open the plugin window in NetBeans and select the Downloaded tab, browse to the .nbm file you just created and install it. After the installation is done you will directly see the icon in the toolbar (if you haven’t choosen to hide the File toolbar offcourse) without even have to restart NetBeans.

    Posted in Netbeans | 14 Comments »

    Get the application title inside your platform application

    Posted by Nicklas Löf on February 22, 2011

    I’m adding some information into the platform applications title bar and I have hard coded the application name title in one of my classes. This works but when the application name changes (for example version/release number) I have to remember to change in two places (my class and in the branding dialog box).

    Today I finally did have a look how to get the application title in my code and it was this simple:

    NbBundle.getBundle("org.netbeans.core.windows.view.ui.Bundle").getString("CTL_MainWindow_Title");

    And to set the titlebar of the application:

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            WindowManager.getDefault().getMainWindow().setTitle(NbBundle.getBundle("org.netbeans.core.windows.view.ui.Bundle").getString("CTL_MainWindow_Title") + " - " + myOtherInformationIWantInTheTitleBar);
        });
    

    Posted in Netbeans | 11 Comments »

    Wallpaper in a NetBeans RCP application

    Posted by Nicklas Löf on February 18, 2011

    Yesterday I wrote about my attempts to put an image in the root window of a Netbeans RCP application that is shown when no TopComponents are open.

    Today I did finalize the code and added so I could add a logotype at the bottom on the right side and when the application window is resized it will stay at the bottom right side. So here is the complete code.

        private ImageIcon bgimage;
    
        @Override
        public void restored() {
            bgimage = new ImageIcon(ImageUtilities.loadImage("path/to/my/wallpaper.jpg"));
                SwingUtilities.invokeLater(new Runnable() {
    
                    public void run() {
                        JFrame main = (JFrame) WindowManager.getDefault().getMainWindow();
                        JPanel mainPanel = new JPanel(new BorderLayout()) {
    
                            @Override
                            public void add(Component comp, Object constraints) {
                                super.add(comp, constraints);
                                if (constraints == BorderLayout.CENTER) {
                                    if (comp instanceof JPanel) {
                                        final JPanel panel = (JPanel) comp;
                                        panel.setBorder(BorderFactory.createEmptyBorder());
                                        panel.add(new BackgroundLabel(bgimage), java.awt.BorderLayout.CENTER);
                                    }
                                }
                            }
                        };
                        main.setContentPane(mainPanel);
                    }
                });
            }
        }
    
        private class BackgroundLabel extends JLabel {
            private boolean showBgImage = true;
            private ComponentAdapter componentAdapter;
            private Image image;
    
            public BackgroundLabel(ImageIcon imageIcon) {
                super(imageIcon);
                image = ((ImageIcon) getIcon()).getImage();
                setupAdapter();
                TopComponent.getRegistry().addPropertyChangeListener(new PropertyChangeListener() {
    
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if (TopComponent.getRegistry().getOpened().isEmpty()) {
                            showBgImage = true;
                            repaint();
                        } else {
                            showBgImage = false;
                        }
                    }
                });
            }
    
            @Override
            public void paintComponent(Graphics g) {
                if (showBgImage) {
                    int x = getParent().getSize().width - image.getWidth(this);
                    int y = getParent().getSize().height - image.getHeight(this);
                    g.drawImage(image, x, y, image.getWidth(this), image.getHeight(this), this);
                }
            }
    
            private void setupAdapter() {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        componentAdapter = new ComponentAdapter() {
    
                            @Override
                            public void componentResized(ComponentEvent e) {
                                BackgroundLabel.this.setSize(getParent().getSize());
                            }
                        };
                        getParent().addComponentListener(componentAdapter);
                    }
                });
            }
        }

    Any image loaded into bgimage will be put at the bottom right corner of the application and stay there even when the window resizes.

    To modify this behaviour just change the x and y parameters in paintComponent(Graphics g). For example setting them to 0,0 would draw the image at the top left corner. To stretch an image the width and height parameters should be modified.

    Here is two screenshots showing this in action. The first one is just a quick logo I did created in GIMP since I can’t show my real application here, the other one is a fullscreen netbeans desktop background downloaded from http://netbeans.org/community/teams/evangelism/collateral.html.

    Posted in Netbeans | 4 Comments »

    Put a wallpaper in the root frame of a Netbeans RCP application

    Posted by Nicklas Löf on February 17, 2011

    A few days ago I had dinner with Geertjan Wielenga and Henry Arousell and Henry did show me his application he is working on. He did have a background image in one of his topcomponents and I really loved that idea. (After finishing this blog post I saw that this will actually be easier in Netbeans 7!  Really looking forward for that)

    But I wanted to take it even further. My application is showing a complete empty window when it’s opened until the user has opened up something. And the background is dark grey and booring. So I want to put a background image there showing the company name and the application name at the bottom. A discrete background image off course.. nothing big with lots of colors.

    But how can I do that? There is nothing in the plattform allowing me to set the background image and the only way I know off to do it in a good way is to override the paintComponent(Graphics g) method which I can’t override since that is the root window of the netbeans platform application.

    I’m using OfficeLAF and I did know they did a few tricks in the Installer restored() method that I did modify a bit. What they are doing is that they get the mainWindow trough WindowManager.getDefault().getMainWindow(); Then they add a panel to the mainwindow that overrides the add method. So when the platform is adding it’s own panel it’s picked up in the add method and modified.

    So with my modification this is how it looks:

    public void restored() {
                bgimage = (Image) UIManager.get("Nb.Explorer.Folder.icon");
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        JFrame main = (JFrame) WindowManager.getDefault().getMainWindow();
                        JPanel mainPanel = new JPanel(new BorderLayout()) {
                            @Override
                            public void add(Component comp, Object constraints) {
                                super.add(comp, constraints);
                                if (constraints == BorderLayout.CENTER) {
                                    comp.setBackground(GRAY_76);
                                    if (comp instanceof JPanel) {
                                        final JPanel panel = (JPanel) comp;
                                        panel.setBorder(BorderFactory.createEmptyBorder());
                                        panel.add(new BackgroundLabel(new ImageIcon(bgimage)));
                                    }
                                }
                            }
                        };
                        main.setContentPane(mainPanel);
                } 

    What I have added here that isn’t in OfficeLAF is the new BackgroundLabel() creation. This will add a Label with an ImageIcon to the rootframe.

    My first version of BackgroundLabel looked like this:

        private class BackgroundLabel extends JLabel {
            public BackgroundLabel(ImageIcon imageIcon) {
                super(imageIcon);
            }
       }
    
        @Override
            public void paintComponent(Graphics g) {
                g.drawImage(((ImageIcon) getIcon()).getImage(), 0, 0, getParent().getParent().getSize().width, getParent().getParent().getSize().height, this);
            }
    }

    This almost worked.. the biggest problem was that it’s painting the image ABOVE my Topcomponents instead of in the background. So I needed to tweak this a bit. Only paint when there is no TopComponents open. So the final version looks like this:

        private class BackgroundLabel extends JLabel {
            private boolean showBgImage = true;
            public BackgroundLabel(ImageIcon imageIcon) {
                super(imageIcon);
                TopComponent.getRegistry().addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if (TopComponent.getRegistry().getOpened().isEmpty()) {
                            showBgImage = true;
                            repaint();
                        } else {
                            showBgImage = false;
                        }
                    }
                });
            }
       }
    
        @Override
            public void paintComponent(Graphics g) {
                if (showBgImage) {
                    g.drawImage(((ImageIcon) getIcon()).getImage(), 0, 0, getParent().getParent().getSize().width, getParent().getParent().getSize().height, this);
                }
            }
    }

    What I added is a propertychangelistener to the TopComponent registry. Each time something happens with a topcomponent I’m checking how many topcomponents are open. If none are open I will set the showBgImage boolean to true and call for a repaint(). And if there are TopComponents showing again the showBgImage are set to false again. (no repaint is needed now).

    The reason I listen to all propertychanges is because the propertychanges seems to not be trusted. At the same time I got closed events I also got open events so I listen to all instead.

    My only problem left is that the image isn’t resized properly if the application gets bigger than the initial size. Otherwise the resize works just great. Performance wise there is no problem. The paintComponent() method is only called on the first paint and then on resizes. If it works when not using OfficeLAF and/or Mac I have no answer to.

    And below you can see a small screenshot with my temporary image which is just a (Image) UIManager.get(“Nb.Explorer.Folder.icon”) that I picked by random. Also see Part 2.

    Posted in Netbeans | 2 Comments »

    Place the quicksearch component anywhere you like

    Posted by Nicklas Löf on February 16, 2011

    In one of my applications I needed to put the Quicksearch into one of my Topcomponents instead of having it in the standard netbeans toolbar. The main reason for this is I’m using OfficeLAF so I don’t have the default toolbar at all.

    This turned out to be a bit of a problem and I had to do one of my favourite things again..   dive into the Netbeans Platform source code and this is how to get hold of the Quicksearch component and place it anywhere you want.

    The first problem I had is that the whole implementation of the QuickSearch component is not exposed so it’s not possible to do something like new QuickSearchComboBar();

    After some investigation I found out that the Action for the QuichSearch component is a CallableSystemAction which has a nice little method called getToolbarPresenter() which returns an AWT Component! So now all I need is to get hold of the Action. The QuickSearchAction is living in the Layer in “Actions/Edit” so what we could do is Utilities.actionsForPath(“Actions/Edit”) which returns a list of Actions. But how do we actually get the Action we want?

    One answer would be  (if action instanceOf QuickSearchAction)   but that will not work because QuickSearchAction is not visible and the compile of the netbeans module will fail.

    So what about (if action instanceOf Presenter.Toolbar)?  Thats a bit closer but there are multiple Actions matching.

    How about (if action.getValue(Action.NAME).equals(“Quick search blahblah something”)? Might work but what if the name changes.. especially if you are using bundles and different languages. Also you can’t get the message from the bundle since NbBundle.getMessage(QuickSearchAction.class, “CTL_QuickSearchAction”); wouldn’t work since QuickSearchAction is still not visible.

    Finally I did it like this. In my module layer.xml file:

    <folder name="QuickSearchShadow">
        <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow">
            <attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/>
        </file>
    </folder>

    Now I have a shadow of this instance in my layer.xml and I can finally get hold of my action like this:

    List<? extends Action> actions = Utilities.actionsForPath("QuickSearchShadow");
    for (Action action : actions) {
        if (action instanceof Presenter.Toolbar) {
            do stuff
        }
    }

    So..  there we have our QuickSearchAction instance finally!  Now to “do stuff”:

    quickSearchToolbarItem = ((Presenter.Toolbar) action).getToolbarPresenter();
    quickSearchPanel.add(quickSearchToolbarItem);
    

    And now the complete quicksearch component is available for you and you can put it anywhere..  in an JPanel that you have created in Matisse in your Topcomponent for example.

    As usual.. if anyone has a better way to do this..  please let me know..   that’s one of the reasons for having a blog by others comments :-)

    Posted in Netbeans | 1 Comment »

    No, I don’t want to rename my node

    Posted by Nicklas Löf on February 14, 2011

    Two weeks ago I needed to make my Outlineview readonly. All properties it’s showing was only for read and all changes was gonna be done in a separate editor window.

    Making the properties read only is very easy. If you are using BeanNodes just edit the BeanInfo and select Read-only on each property. If you are using AbstractNodes you probably are creating your own propertyset and if I remember correctly just include the getter and the property will be read only.

    So now everything is ok but I did discover that in the tree column of the outlineview I could double click on the node name and rename the node. This was something I didn’t want to do and I started to look around how to fix this. All I could found was suggestions that Overriding getPreferredAction and set the action I want to execute when I double click on my node. If this is set to null no action will be executed. But still I could double click on the name and the node was renamed.

    The solution was easy..   override canRename() and return false and booom it’s not possible to rename the node name anymore!

    Posted in Netbeans | Leave a Comment »

    Dynamic node edit property menu

    Posted by Nicklas Löf on February 14, 2011

    Hi everybody.

    I’m sorry for the last months of no posts here but there hasn’t been any time for me to write any blog posts since I have been really busy at work (working with Netbeans RCP offcourse)

    But here is a post I started to wrote some time ago but haven’t been able to finish until today.

    So, in my application I wanted to have my users to be able to access the property editor for each of my Nodes properties without having to open up the normal Properties popup panel (which action you can access with SystemAction.get(PropertiesAction.class)). My goal was that when the user did right click on a node the menu would show me a bunch of Edit ‘Propertyname’ menu entries and when it was selected the editor for that property was showing up (the same editor that you get when clicking the “…” button in the properties panel). The screenshot below shows what I’m trying to describe in words.

    So how can we achieve this?  I couldn’t find any clear examples so I did one of my favourite things..   look at the netbeans source code..  And this might not be the only way to do this and most certain not the nicest way but it works.

    To start with we need to do this in our Node.java file and we need to override the following method:

    public Action[] getActions(boolean context){ }

    This method is called each time the user right clicks on a node in your application. And as we can see it expects to get back an Array of Actions so lets create an array with our dynamic actions:

    public Action[] getActions(boolean context){
        ArrayList<Action> actionsToShow = new ArrayList<Action>();
            for (Node.PropertySet propertySet : getPropertySets()) {
                for (final Node.Property<?> property : propertySet.getProperties()) {
                    if (property.canWrite() && property.getPropertyEditor().supportsCustomEditor()) {
                        actionsToShow.add(new EditPropertyAction(property, this));
                     }
               }
        }
        return (Action[]) actionsToShow.toArray(new Action[actionsToShow.size()]);
    }

    Ok. What is this code doing? First I’m just creating an ArrayList that I can add my Actions into. Then I’m asking my node to get the the propertyset and for each property I’m asking for the Node.Property. If Node.Property is writeable (we don’t want to show read-only properties in the menu) and that it has a customeditor (Integers doesnt have one for example) then I’m creating a EditPropertyAction that takes two arguments, the property and the node itself. Finally I’m returning the ArrayList as an Array.

    Are we done yet? No we aren’t. We need to implement the EditPropertyAction.

        private static class EditPropertyAction extends AbstractAction {
            private final Node.Property<?> property;
            private final Node node;
    
            public EditPropertyAction(Node.Property<?> property, Node node) {
                this.property = property;
                this.node = node;
                putValue(Action.NAME, "Edit " + property.getDisplayName());
            }
    
            @Override
            public void actionPerformed(ActionEvent ae) {
                final PropertyPanel propertyPanel = new PropertyPanel(property, PropertyPanel.PREF_CUSTOM_EDITOR);
                propertyPanel.setChangeImmediate(true);
                propertyPanel.setProperty(property);
    
                final DialogDescriptor dlg = new DialogDescriptor(propertyPanel, node.getDisplayName() + " " + property.getDisplayName());
    
                dlg.setButtonListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (dlg.getValue().equals(DialogDescriptor.OK_OPTION)) {
                            try {
                                propertyPanel.updateValue();
                            } catch (Exception e1) {
                            }
                            dlg.setClosingOptions(new Object[]{dlg.getValue()});
                        } else {
                            dlg.setClosingOptions(null);
                        }
                    }
                });
                Dialog createDialog = DialogDisplayer.getDefault().createDialog(dlg);
                createDialog.setVisible(true);
            }
        }
    

    Pheew.. that was alot of code! A quick explanation of this code: An action that extends AbstractAction. It has the node itself and the property as fields which are set by the constructor. And then the Action name is set to “Edit ” and the displayname of the property.

    Lets move on to the actionperformed. This is what is called by the application when the user selects the entry in the menu. What we do here is creating a new PropertyPanel which is a Netbeans class that extends JComponent. So what we get back is a Swing component. And to show this component I’m using another nice  builtin Netbeans thing called DialogDescriptor. What it does is showing a popup jframe with the component inside and an Ok and Cancel button. And as you can see I’m creating a very basic ActionListner and connect it to the dialogdescriptor and when the user press Ok all we have to do is calling propertyPanel.updateValue() and the property is updated with the information the user entered, if cancel was pressed the property is not updated.

    That’s all needed. And as you can see there is no connections to the node data in here so it’s possible to create a NodeUtilities class with a static method that generates this for every node you want. And if you have customized and created your own CustomEditor and registred with your Node that editor is what you gonna see. This is also true for any editors you have registered globally using PropertyEditorManager.registerEditor() off course.

    If you know a nicer way to do this let me know!

    Posted in Netbeans | Tagged: | 1 Comment »

    OpenJDK Project for Mac OS X

    Posted by Nicklas Löf on November 12, 2010

    This is some good news for us Java developers on Mac:

    http://www.apple.com/pr/library/2010/11/12openjdk.html

     

    Also I have started with a new blog post about dynamic population of the node menu (actions) for edit entries of the node properties, hopefully it will be finished this weekend. I have so much other things going on at the same time.. :-)

    Posted in Uncategorized | 1 Comment »

     
    Follow

    Get every new post delivered to your Inbox.