Friday Jul 27, 2012

On Vacation

...and I will not be bringing my laptop. Back on Monday, August 13th!

Thursday Jul 26, 2012

Plug A Custom BasicTabbedPaneUI into the Mavenized NetBeans Platform

Two NetBeans Platform developers, Bo Conroy and Adriana, mentioned at the end of my blog entry here that plugging in a new tabbed component factory doesn't work for them in their Maven-based NetBeans Platform application. The reason for that is that, in my example code, I used JTabbedPaneAdapter, which is an implementation class in "org.netbeans.core.windows".

So, you could do different things. (1) Create an issue to make that class public (that's something I'll be doing soon), though there may be reasons why this isn't done already. (2) Create your own implementation of "org.netbeans.swing.tabcontrol.customtabs.Tabbed", which could be a bit of work and currently isn't documented. That's something I'll be working on soon. (3) Set the "org.netbeans.core.windows" module as a friend module of your own module, which means that you're conscious that you're using an internal NetBeans Platform class and that if it changes unexpectedly you can't complain because you knew up front that you're not going to be using a public API.

This is how you do that:

  1. Find the Module Descriptor (module.xml) file in the module where you want to use an internal class: 

  2. In that file, paste this content:
    <?xml version="1.0" encoding="UTF-8"?>
    <nbm>
        <dependencies>
            <dependency>
                <id>org.netbeans.modules:org-netbeans-core-windows</id>
                <type>impl</type>
                <explicitValue>org.netbeans.core.windows/2 = 201207171143</explicitValue>
            </dependency>
        </dependencies>
    </nbm>

    The pattern for impl dependencies is XXX = IMPL_VERSION where XXX is the codenamebase and IMPL_VERSION is the implementation version from the module's manifest. (Read here.)

    The explicitValue element can be constructed by looking in the manifest of the JAR that you want to make your friend:

Then build the application and everything will work as expected:

Sources of this sample are here:

http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.2/misc/MVNTabPaneDemo

Wednesday Jul 25, 2012

Simplified Usage of the NetBeans Platform

The latest NetBeans Platform application showcased at NetBeans Zone, Zirius, the Norwegian ERP System, is illustrative of how the bare minimum of the NetBeans Platform can be used, to the point where the NetBeans Platform doesn't show through at all:

On the one hand, this means that you're not leveraging the width and breadth of all that the NetBeans Platform provides. On the other hand, it takes time to migrate an application to the NetBeans Platform and the above is a logical first stage. Though you have modularity, an update mechanism, and a loosely coupled mechanism for communication across modules via the Lookup API, you keep everything else exactly as it was before: same UI, including same toolbar and menu bar.

That's possible because you can remove everything from the NetBeans Platform and start with a clean slate, in so far as the user interface is concerned:

Above, there's a single NetBeans TopComponent, with its tabs removed. The toolbar is removed and the menu bar is removed, with some dummy menu items added via a custom menu bar. Now you can treat the TopComponent like a JPanel and simply add all your UI components within it.

The application above looks like this: 

And the sources can be downloaded here:

http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.2/misc/NBContainer

The code in the repo above was written following the instructions described in the Zirius article. Using those sources, you can very easily create strictly defined user interfaces, i.e., without the flexible NetBeans window system, with a tree view on the left and a GUI pane on the right, like this, for example, i.e., an image viewer:

Similar applications on the NetBeans Platform, i.e., leveraging low level infrastructure, while all the rest are custom UI components within a single TopComponent, can be read about in these two articles:

What's also cool about the Zirius story is that Toni and I visited that company two years ago and, clearly, the NetBeans Platform message did not fall on deaf ears!

Tuesday Jul 24, 2012

Top 10 New Features in NetBeans IDE 7.2

Start spreading the news! NetBeans IDE 7.2 is out with, as always, its clean and neat user interface:

Here's the top 10 features you'll find in this release:

  • Static code analysis support, in particular, FindBugs integration.
  • Smoother startup and faster project scanning.
  • New, better, and faster tools throughout the Java Editor.
  • Enhancements for Java EE developers, such as JPA code completion and PrimeFaces 3.2.
  • Better JavaFX tools, in particular, JavaFX Scene Builder integration.
  • Even more NetBeans love for Maven.
  • Tools and templates for TestNG.
  • New PHP frameworks integrated, together with more editor tools.
  • Groovy & Grails faster and more tools.
  • NetBeans C++ powered up and yet more support than before.

Go get it while the buzz is buzzing!

Monday Jul 23, 2012

BackupGoo: For When Clouds Start Leaking

Here's a great little backup tool, named BackupGoo, for your Google-related artifacts, i.e., mail, docs, contacts, and calendar:

I had everything set up in seconds, on my Ubuntu machine, as well as on my Windows machine. Great application. Gets you ready for those days when the clouds are leaky:

And here's the structure of the application, familiar to anyone using or creating applications on the NetBeans Platform:

Would be cool if the NetBeans Platform's Favorites window would be included in BackupGoo, which would let you browse into the folder of backed up files and then you'd be able to read those files within BackupGoo using the NetBeans Platform's text editor. 

Sunday Jul 22, 2012

org.netbeans.spi.project.ui.ProjectOpenedHook

If you want something to happen when a project conforming to your project type opens or closes, put an instance of org.netbeans.spi.project.ui.ProjectOpenedHook into your project type's lookup. The methods "projectOpened" and "projectClosed" are called when a project of your type opens or closes in your application's GUI.

However, let's make it more interesting! Let's say you want to integrate a tool into NetBeans IDE, for example, that will process ANY project as soon as it is opened. For that purpose, you're able to add objects into the lookup of project types over which you have no control.

Here's an example. Whenever any NetBeans project opens, a balloon message is created, i.e., shown in the bottom right of the IDE, with the possibility to search Google for information relating to the project.

The code, but note that below the ProjectOpenedHook is added to the lookup of four NetBeans projects, though it could be added to many others too, for each the annotation needs to include the related project ID:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.net.URLEncoder;
import org.netbeans.api.project.Project;
import org.netbeans.spi.project.LookupProvider;
import org.netbeans.spi.project.ui.ProjectOpenedHook;
import org.openide.awt.HtmlBrowser.URLDisplayer;
import org.openide.awt.NotificationDisplayer;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;

@LookupProvider.Registration(projectType = {
    "org-netbeans-modules-web-project",
    "org-netbeans-modules-java-j2seproject",
    "org-netbeans-modules-apisupport-project",
    "org-netbeans-modules-apisupport-project-suite"
})
public class DefaultProjectOpenedHook implements LookupProvider {

    @Override
    public Lookup createAdditionalLookup(final Lookup lookup) {
        
        Project p = lookup.lookup(Project.class);
        final String name = p.getProjectDirectory().getName();
        
        return Lookups.fixed(new ProjectOpenedHook() {
            @Override
            protected void projectOpened() {
                NotificationDisplayer.getDefault().notify(
                        //display name:
                        "Opened " + name,
                        //icon:
                        ImageUtilities.loadImageIcon("org/netbeans.png", false),
                        //description:
                        "Search Google for " + name + "!",
                        //action listener:
                        new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                try {
                                    String searchText = URLEncoder.encode(name, "UTF-8");
                                    URLDisplayer.getDefault().showURL(
                                            new URL("http://www.google.com/search?hl=en&q="
                                            + searchText + "&btnG=Google+Search"));
                                } catch (Exception eee) {
                                    return;//nothing much to do
                                }

                            }
                });
            }

            @Override
            protected void projectClosed() {
            }
            
        });
        
    }

}

Saturday Jul 21, 2012

Wrapper Project for NetBeans Projects

A great question in this blog by swpalmer recently:

I have a need for a custom project type that is mostly just a parent for existing NB project types for Java(Ant or Maven, soon Gradle) and C++. Think of it like a one project for a Java library that uses JNI and the project for the native library that implements the native methods that go with it. Add a little bit of metadata and some custom packaging steps (currently written with Gradle) and that would be my new project type.

Would making a new parent project type that has subprojects of existing NB project types be an easy thing to implement?

Well, here's a simple example. Imagine you have folders for your customers, each containing multiple NetBeans projects. Would be cool to be able to open all those projects together, as part of a new project defined by some recognized structure in the customer folder:

Then, once open, you can do typical things you'd like to be able to do to multiple projects belonging to a shared container of some kind, such as open the individual projects for separate editing:

Notice that, though the icon is retained from the original NetBeans project, the logical view isn't. I don't think there's a way around that.

The way this works is that the "createLogicalView" override of the Project implementation returns a Node that defines its children as FilterNode.Children, with the icons overridden. That defines the logical view. The ability to open the NetBeans project together with the main project is done via a SubprojectProvider in the Lookup of the main project, which recognizes subfolders containing an "nbproject" folder as a subproject of the main project.

Best of all, I can now create Actions which lookup all the subprojects and then do something with the group of subprojects. Maybe, for example, all the subprojects can be built together or run together or something like that. A higher level container like this can open up a lot of possibilities and isn't hard to create, if you combine the instructions in the above paragraph with the instructions in this tutorial:

http://platform.netbeans.org/tutorials/nbm-projecttype.html

Finally, if the customer project in the screenshots above were to be a Gradle project, then I think the question with which this blog entry started would be resolved. 

Friday Jul 20, 2012

New Tutorial: Integrating JavaFX Charts into the NetBeans RCP (Part 2)

Recently the NetBeans Platform JavaFX Integration Tutorial was released. There were still some open issues, though, as described here in Part 1 of this series. Gail and Paul Anderson, from Anderson Software Group, picked up the gauntlet and fixed these problems, as well as introducing additional JavaFX charts to the application:

I'll be updating the tutorial soon with the new code and fixes provided by Gail and Paul! All the code is already available here:

http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.2/misc/StockTraderClient

They'll also be delivering a tutorial on JavaFX and the NetBeans Platform at JavaOne 2012 in October this year:

"TUT4801 - Make Your Clients Richer: JavaFX and the NetBeans Platform"
The NetBeans platform is known for its comprehensive window framework and loosely coupled architecture. JavaFX offers a rich set of visually appealing GUI components. This tutorial shows you how to use both to enhance the user experience in desktop client applications. In the tutorial, you will learn how to integrate JavaFX into a NetBeans application. You will start with a basic application that generates data. You will then create a NetBeans module that includes a dynamic JavaFX chart component. This chart component leverages JavaFX bindings to visually animate data as the values change. The result includes an application with a sophisticated out-of-the-box GUI coupled with flashy, JavaFX-powered animations.

That's a two hour topic, i.e., a tutorial, they will do on this subject. Looking forward to it!

Thursday Jul 19, 2012

NetBeans Support for Gradle Multi-project Builds

The start of multi-project build support (described here) for the NetBeans Gradle plugin. For the projects that are part of the multi-project build, a separate project type is defined, which is registered in the lookup of the main Gradle project. Now each of the projects can be opened and worked on independently of the main project, in the same way as with suites/modules in NetBeans Platform development or the EJB modules in a NetBeans Java EE application project, for example.

Above, you see the Netflix Curator on GitHub, which Tim Boudreau suggested might be a good largish real world application for trying out the NetBeans plugin for Gradle.

As a consequence, I learned a lot about sub project type support in the NetBeans Platform. (Well, actually this is part of the APIs exposed by NetBeans IDE and not the NetBeans Platform.) Read about it here, which is where I documented it in the NetBeans Platform 7.2 Project Type tutorial:

http://platform.netbeans.org/tutorials/nbm-projecttype.html

Wednesday Jul 18, 2012

Extending the Lookup of a Java SE Project

Here I have the start of some kind of visualizer for Java SE projects in NetBeans IDE. A project is passed in and then the visualizer does something with it:

public class MyJavaSEVisualizer {

    public MyJavaSEVisualizer(Project p) {
        // do something with the project to visualize it
    }
    
}

Next, I have some action. In this case, the action is invoked from the File menu. The action is only enabled if a project is in the lookup. The action then retrieves the visualizer from the lookup of the project:

@ActionID(category = "File", id = "org.jse.lookup.SomeAction")
@ActionRegistration(displayName = "#CTL_SomeAction")
@ActionReference(path = "Menu/File", position = 0)
@Messages("CTL_SomeAction=Some")
public final class SomeAction implements ActionListener {
    
    private final Project context;

    public SomeAction(Project p) {
        this.context = p;
    }

    
    @Override
    public void actionPerformed(ActionEvent e) {
        MyJavaSEVisualizer mjsev = context.getLookup().lookup(MyJavaSEVisualizer.class);
        if(mjsev != null){
            JOptionPane.showMessageDialog(null, "this is a Java SE project");
            // now call a method on mjsev...
        } else {
            JOptionPane.showMessageDialog(null, "this is NOT a Java SE project");
            // now don't call a method on mjsev...
        }
    }
    
}

But how does the visualizer end up in the lookup of the project? Like this, i.e., without changing the source of Java SE projects, but by extending the lookup of Java SE projects, i.e., the lookup of projects can be defined to be pluggable and, in the case of NetBeans IDE projects, projects have been defined in that way:

@LookupProvider.Registration(projectType = "org-netbeans-modules-java-j2seproject")
public class MyJavaSEVisualizerLookupProvider implements LookupProvider  {

    @Override
    public Lookup createAdditionalLookup(Lookup lookup) {
        return Lookups.fixed(new MyJavaSEVisualizer(lookup.lookup(Project.class)));
    }
    
}

Tuesday Jul 17, 2012

Gradle Classpath Support in NetBeans

This may be my greatest achievement as a NetBeans Platform programmer, ever. Since my girlfriend is not a programmer, she's not going to be able to join with me in celebrating this happy news. (Well, she can celebrate, but without full appreciation.)

So I turn to the on-line community of developers everywhere: I've created a Gradle project type for NetBeans IDE, with classpath support. That means that not only the JDK, but also the dependencies declared in the Gradle build file are on the classpath of the project:

The JARs in the Libraries node above are defined in the Gradle build file, refer to the screenshot in yesterday's blog entry for details. Those JARs are put on the classpath, thanks to the NetBeans plugin, and can then be coded against, as you can see above.

Still a lot needs to be done before this is usable. Changes in the Gradle build file need to be reflected in the hierarchies in the explorer view; the user should be able to map Gradle tasks to project commands; the user should be able to change the JDK; and many other similar project-level features need to be implemented, while it would also be cool to have the Package View support integrated into this project type.

But, for now, this is a great step forward. It would be great to have a few people out there who'd like to try out this early (and also later) version of the plugin, but bear in mind that only very few features work. Well, you can run all your tasks and the classpath works, so that's all the basic stuff ready to be used by anyone using Gradle.

A small cool thing I like is the fact that the project node hierarchy is pluggable. So, you could create an external module and provide a new node in the project view above, but more about that another time. 

Many thanks to the Grails project (which owes some gratitude to the Ruby project, among others), which is where almost all of the Gradle classpath code comes from. 

Monday Jul 16, 2012

More Serious Attempt at a NetBeans Gradle Plugin

After a few small skirmishes in this area, here's a more serious attack:

What you see above is that a Gradle build file can be expanded, exposing its tasks, which can be double-clicked to be invoked. Also, the JAR dependencies of the project are visualized and can be browsed just like any other JAR file in NetBeans. When a change is made in the file, the task hierarchy and the dependency hierarchy are automatically rebuilt.

Any folder that has a file named 'build.gradle', on the highest level within the folder, is recognized as a Gradle project and can be opened:

All of the features above are then automatically available. There's also a file template for creating a new Gradle build file from scratch, for an existing project that doesn't yet have Gradle support. 

The final step, at least for this version of the plugin that provides basic Gradle support, is to work with the class path. I'll need to look at how this is done for the Grails project type, as well as, maybe the Maven project type. Not only the Java classes in 'src' should be on the classpath, but also the Java classes in the JARs retrieved via the declared dependencies.

The sources are here, anyone is free to do whatever they want with them:

http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.2/misc/GradleProjectType

Sunday Jul 15, 2012

Notes on Gradle and NetBeans

This checks all subfolders of a folder for a file named "build.gradle". If such a file exists, the project type is created:

@org.openide.util.lookup.ServiceProvider(service = ProjectFactory.class)
public class GradleProjectFactory implements ProjectFactory {

    public final String GRADLE_BUILD_FILE = "build.gradle";

    //Specifies when a project is a project, i.e.,
    //if in the project directory "build.gradle" is present:
    @Override
    public boolean isProject(FileObject projectDirectory) {
        for (FileObject fo : projectDirectory.getChildren()) {
            if (fo.getNameExt().equals(GRADLE_BUILD_FILE)) {
                return true;
            }
        }
        return false;
    }

    ...
    ...
    ...

Actually, simpler is like this:

    @Override
    public boolean isProject(FileObject projectDirectory) {
        return projectDirectory.getFileObject(GRADLE_BUILD_FILE) != null;
    }

For the rest of the project type, go here:

http://platform.netbeans.org/tutorials/nbm-projecttype.html

For the start of a NetBeans Gradle plugin, which anyone out there is welcome to continue working on, go here:

http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.1/misc/GradleSupport

After you install the plugin, go to the Options window and register your Gradle installation.

Friday Jul 13, 2012

New Tutorial: Integrating Workflows into the NetBeans RCP

A common business requirement can be summed up in the term "workflow application". That is, a guided sequence of steps, at the end of which a business scenario is completed, with some kind of output, such as a report or an analysis result. In this scenario, a wizard, i.e., a multi-step dialog, is not enough; rather, all the windows in the application belong to one or more roles (also known as perspectives), which can be shown/hidden simultaneously, depending on the currently selected role.

One example of such an application is this one:

And here's another one:

The infrastructure of these applications is surprisingly simple to create, especially if you follow this brand new tutorial:

http://platform.netbeans.org/tutorials/nbm-workflow.html

As always, feedback is more than welcome. 

Thursday Jul 12, 2012

New Tutorial: Integrating JavaFX Charts into the NetBeans RCP (Part 1)

The "NetBeans Platform JavaFX Integration" tutorial provides step-by-step instructions for integrating JavaFX features into a NetBeans Platform application. Since the NetBeans Platform is typically used as a basis for corporate applications, the JavaFX chart components are ideal candidates for integration into NetBeans Platform applications. JavaFX, as a whole, is focused on bringing special effects to Java. In the context of charts, JavaFX provides a set of predefined charts, each of which can be animated, which is particularly useful to show changes in values presented in a chart.

The tutorial can be found here:

http://platform.netbeans.org/tutorials/nbm-javafx.html

The end result:

Best of all, and you're unlikely to believe this until you try the tutorial: you're not going to need to code anything at all to get the above result. It's all simply a question of refactoring some of the JavaFX samples such that they run within NetBeans Platform window components. I.e., basically all you'll be doing is copying and pasting code from existing samples into windows, the code for which is generated from templates. A little bit of tweaking here and there, as you'll see in the tutorial, but about 98% of the code already exists and you just need to move it into the right places.

In the first part of the tutorial, you set up and run one of the standard JavaFX samples that comes with NetBeans IDE:

The above is a very nice sample, since it not only shows a JavaFX chart, but also a Swing JTable. The two are connected such that when a value changes in the table, the JavaFX chart changes and, importantly, is animated while it changes.

In the tutorial, you then create a new Java desktop application on the NetBeans Platform and move the code from the sample into a new window:

Next, you split the table from the JavaFX chart, i.e., in the screenshot below they're now in two separate windows, thus making the application more modular, since each window in this application is found within a separate module.

Finally, you're shown how to add additional JavaFX charts into the application and how to synchronize them so that all charts are animated simultaneously:

Naturally, the windows can be undocked and moved around (even outside the application frame, onto a different monitor, for example), since the NetBeans Platform has its own window system.

Quite a bit of additional content needs to be added to the tutorial. For example, the area chart in the tutorial isn't synchronized with the table and the other charts yet. Some explanatory text needs to be added to explain how the original sample works, i.e., what's in the table, what's in the chart, and how do they interact with each other. Also, the table needs to be fixed so that the header isn't excluded, as is currently the case. Another topic to be dealt with is how all this can be done in a Maven based NetBeans Platform application. And also the tutorial needs to be tried out on all operating systems, with any differences (e.g., on Mac) to be added into the tutorial. Finally, it needs to be explained how the same application can be distributed to different operating systems, i.e., how to handle native libraries for different operating systems. The tutorial itself is created on Windows and, at least initially, supports the Windows use case, though the long list of native libraries shouldn't be needed, just a subset of them, I just didn't know which ones were actually needed and included all of them.

Feedback welcome and it would be cool to hear from NetBeans Platform (and other Java desktop) developers everywhere about the cool things they're experimenting on in the context of JavaFX!

Wednesday Jul 11, 2012

Semantic Moving in NetBeans IDE 7.2

So, you're using NetBeans IDE and you have a bunch of code, such as the "getName" method below, that you'd like to move up:

So, you press Alt-Shift-Up, which is great the first time, because as you can see above there's an empty line above the method I'm moving. However, if I press Alt-Shift-Up a second time, you end up inside the next method, which breaks your code, as you can see below:

So, in NetBeans IDE 7.2, you can use "Alt-Shift-Page Up" instead. When you do so, the action you're performing is aware of the context of what you're moving, as well as the context around it. Therefore, if I press "Alt-Shift-Page Up" twice, below, the method ends up above (instead of inside, i.e., it jumps right over) the method that it would otherwise have entered:

What's also cool is that you don't need to select the entire method. Below, I have one whole method, plus the start of the next method. When I use "Alt-Shift-Page Up" now, then both complete methods will move as a whole, together:

The point is that the code will never break, i.e., no compile errors will occur, if you use "Page Up" instead of "Up", together with Alt-Shift. (Same thing with "Alt-Shift-Page Down" instead of "Alt-Shift-Down".)

Tuesday Jul 10, 2012

@OnStart & @OnStop

In applications based on NetBeans Platform 7.2, you'll be able to replace all your ModuleInstall classes with this code:

import org.openide.modules.OnStart;
import org.openide.modules.OnStop;

@OnStart
public final class Installer implements Runnable {

    @Override
    public void run() {
        System.out.println("enable something...");
    }

    @OnStop
    public static final class Down implements Runnable {
        @Override
        public void run() {
            System.out.println("disable something...");
        }
    }
    
}

Build the module and the annotations result in named services, thanks to @NamedServiceDefinition:

Aside from no longer needing to register the ModuleInstall class in the manifest, performance of startup will be enhanced, if you use the above approach:

https://netbeans.org/bugzilla/show_bug.cgi?id=200636

Monday Jul 09, 2012

Less than 50 Lines of Code to Create a Java Palette in NetBeans

Want to drag and drop Java code snippets into the palette, in the same way as can be done for HTML files? If so, create a new module and add a class with the content below and you're done. You'll be able to select a piece of Java code, drag it into the palette (Ctrl-Shift-8 to open it), where you'll be able to set a name, tooltip, and icons for the snippet, and then you'll be able to drag it out of the palette into any Java files you like.

The palette content is persisted across restarts of the IDE.

package org.netbeans.modules.javasourcefilepalette;

import java.io.IOException;
import javax.swing.Action;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
import org.netbeans.spi.palette.DragAndDropHandler;
import org.netbeans.spi.palette.PaletteActions;
import org.netbeans.spi.palette.PaletteController;
import org.netbeans.spi.palette.PaletteFactory;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.datatransfer.ExTransferable;

public class JavaSourceFileLayerPaletteFactory {

    private static PaletteController palette = null;

    @MimeRegistration(mimeType = "text/x-java", service = PaletteController.class)
    public static PaletteController createPalette() {
        try {
            if (null == palette) {
                return PaletteFactory.createPalette(
                //Folder:      
                "JavaPalette", 
                //Palette Actions:
                new PaletteActions() {
                    @Override public Action[] getImportActions() {return null;}
                    @Override public Action[] getCustomPaletteActions() {return null;}
                    @Override public Action[] getCustomCategoryActions(Lookup lkp) {return null;}
                    @Override public Action[] getCustomItemActions(Lookup lkp) {return null;}
                    @Override public Action getPreferredAction(Lookup lkp) {return null;}
                }, 
                //Palette Filter:  
                null, 
                //Drag and Drop Handler:  
                new DragAndDropHandler(true) {
                    @Override public void customize(ExTransferable et, Lookup lkp) {}
                });
            }
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        return null;
    }

}

In my layer file, I have this content:

<folder name="JavaPalette">
    <folder name="Snippets"/>
</folder>

That's all. Run the module. Open a Java source file and the palette will automatically open. Drag some code into the palette and a dialog will pop up asking for some details like display name and icons. Then the snippet will be in the palette and you'll be able to drag and drop it anywhere you like. Use the Palette Manager, which is automatically integrated, to add new categories and show/hide palette items.

Related blog entry, for which the above is a big simplification: Drag/Drop Snippets into Palette .

Sunday Jul 08, 2012

Java Hint in NetBeans for Identifying JOptionPanes

I tend to have "JOptionPane.showMessageDialogs" scattered through my code, for debugging purposes. Now I have a way to identify all of them and remove them one by one, since some of them are there for users of the application so shouldn't be removed, via the Refactoring window:


Identifying instances of code that I'm interested in is really trivial:

import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.java.hints.ConstraintVariableType;
import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
import org.netbeans.spi.java.hints.Hint;
import org.netbeans.spi.java.hints.HintContext;
import org.netbeans.spi.java.hints.TriggerPattern;
import org.openide.util.NbBundle.Messages;

@Hint(
        displayName = "#DN_ShowMessageDialogChecker",
        description = "#DESC_ShowMessageDialogChecker",
        category = "general")
@Messages({
    "DN_ShowMessageDialogChecker=Found \"ShowMessageDialog\"",
    "DESC_ShowMessageDialogChecker=Checks for JOptionPane.showMes"
})
public class ShowMessageDialogChecker {

    @TriggerPattern(value = "$1.showMessageDialog", constraints =
    @ConstraintVariableType(variable = "$1", type = "javax.swing.JOptionPane"))
    @Messages("ERR_ShowMessageDialogChecker=Are you sure you need this statement?")
    public static ErrorDescription computeWarning(HintContext ctx) {
        return ErrorDescriptionFactory.forName(
                ctx,
                ctx.getPath(),
                Bundle.ERR_ShowMessageDialogChecker());
    }
    
}

Stick the above class, which seriously isn't much code at all, in a module and run it, with this result:

Bit trickier to do the fix, i.e., add a bit of code to let the user remove the statement, but I looked in the NetBeans sources and used the System.out fix, which does the same thing: 

import com.sun.source.tree.BlockTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.util.TreePath;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.java.source.WorkingCopy;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.java.hints.ConstraintVariableType;
import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
import org.netbeans.spi.java.hints.Hint;
import org.netbeans.spi.java.hints.HintContext;
import org.netbeans.spi.java.hints.JavaFix;
import org.netbeans.spi.java.hints.TriggerPattern;
import org.openide.util.NbBundle.Messages;

@Hint(
        displayName = "#DN_ShowMessageDialogChecker",
        description = "#DESC_ShowMessageDialogChecker",
        category = "general")
@Messages({
    "DN_ShowMessageDialogChecker=Found \"ShowMessageDialog\"",
    "DESC_ShowMessageDialogChecker=Checks for JOptionPane.showMes"
})
public class ShowMessageDialogChecker {

    @TriggerPattern(value = "$1.showMessageDialog", constraints =
    @ConstraintVariableType(variable = "$1", type = "javax.swing.JOptionPane"))
    @Messages("ERR_ShowMessageDialogChecker=Are you sure you need this statement?")
    public static ErrorDescription computeWarning(HintContext ctx) {
        Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath()).toEditorFix();
        return ErrorDescriptionFactory.forName(
                ctx,
                ctx.getPath(),
                Bundle.ERR_ShowMessageDialogChecker(),
                fix);
    }

    private static final class FixImpl extends JavaFix {

        public FixImpl(CompilationInfo info, TreePath tp) {
            super(info, tp);
        }

        @Override
        @Messages("FIX_ShowMessageDialogChecker=Remove the statement")
        protected String getText() {
            return Bundle.FIX_ShowMessageDialogChecker();
        }

        @Override
        protected void performRewrite(TransformationContext tc) throws Exception {
            WorkingCopy wc = tc.getWorkingCopy();
            TreePath statementPath = tc.getPath();
            TreePath blockPath = tc.getPath().getParentPath();
            while (!(blockPath.getLeaf() instanceof BlockTree)) {
                statementPath = blockPath;
                blockPath = blockPath.getParentPath();
                if (blockPath == null) {
                    return;
                }
            }
            BlockTree blockTree = (BlockTree) blockPath.getLeaf();
            List<? extends StatementTree> statements = blockTree.getStatements();
            List<StatementTree> newStatements = new ArrayList<StatementTree>();
            for (Iterator<? extends StatementTree> it = statements.iterator(); it.hasNext();) {
                StatementTree statement = it.next();
                if (statement != statementPath.getLeaf()) {
                    newStatements.add(statement);
                }
            }
            BlockTree newBlockTree = wc.getTreeMaker().Block(newStatements, blockTree.isStatic());
            wc.rewrite(blockTree, newBlockTree);
        }
        
    }
    
}

Aside from now being able to use "Inspect & Refactor" to identify and fix all instances of JOptionPane.showMessageDialog at the same time, you can also do the fixes per instance within the editor:

Saturday Jul 07, 2012

Management Software in Java for Networked Bus Systems

Telemotive AG develops complex networked bus systems such as Ethernet, MOST, CAN, FlexRay, LIN and Bluetooth as well as in-house product developments in infotainment, entertainment, and telematics related to driver assistance, connectivity, diagnosis, and e-mobility.

Devices such as those developed by Telemotive typically come with management software, so that the device can be configured. (Just like an internet router comes with management software too.) The blue AdmiraL is a development and analysis device for the APIX (Automotive Pixel Link) technology. Here is its management tool:

The blue PiraT is an optimised multi-data logger, developed by Telemotive specifically for the automotive industry. With the blue PiraT the communication of bus systems and control units are monitored and relevant data can be recorded very precisely. And here is how the tool is managed:

Both applications are created in Java and, as clearly indicated in many ways in the screenshots above, are based on the NetBeans Platform.

More details can be found on the Telemotive site.

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
« July 2012 »
SunMonTueWedThuFriSat
14
28
29
30
31
    
       
Today