Monday Jun 30, 2014

ReheatMenus

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import org.openide.awt.MenuBar;
import org.openide.util.RequestProcessor;
import org.openide.windows.OnShowing;
import org.openide.windows.WindowManager;

/**
 * Adapted from {@code org.netbeans.core.ui.warmup.MenuWarmUpTask}.
 */
@OnShowing
public class ReheatMenus implements Runnable {
    static void launch() {
        EventQueue.invokeLater(new ReheatMenus());
    }
    private static final RequestProcessor RP = new RequestProcessor(ReheatMenus.class);
    private MenuBar bar;
    private Component[] comps;
    @Override public void run() {
        if (EventQueue.isDispatchThread()) {
            if (bar == null) {
                Frame main = WindowManager.getDefault().getMainWindow();
                assert main != null;
                if (main instanceof JFrame) {
                    JMenuBar menuBar = ((JFrame) main).getJMenuBar();
                    if (menuBar instanceof MenuBar) {
                        bar = (MenuBar) menuBar;
                        RP.post(this);
                    }
                }
            } else {
                comps = bar.getComponents();
                RP.post(this);
            }
        } else if (comps != null) {
            walkMenu(comps);
        } else {
            bar.waitFinished();
            EventQueue.invokeLater(this);
        }
    }
    private void walkMenu(Component[] items) {
        for (Component item : items) {
            if (!(item instanceof JMenu)) {
                continue;
            }
            try {
                Class<?> cls = item.getClass();
                Method m = cls.getDeclaredMethod("doInitialize");
                m.setAccessible(true);
                m.invoke(item);
                walkMenu(((JMenu) item).getMenuComponents());
            } catch (Exception x) {
                // most likely a NoSuchMethodException on a dynamic submenu
            }
        }
    }
}

Friday Jun 27, 2014

NetBeans Platform for Dummies

The latest monthly update of "NetBeans Platform for Beginners" (released earlier this year, currently 379 pages) has been published. At the end of each month, everyone who has bought the book receives a notification that a new version is available for free for everyone who has bought the book. Ever since the release of the book 4 months ago, this has been the case. Today I received the notification and had a look at the book and it's, of course, slightly more awesome than it was before.

If you're looking for a single coherent text that puts all the pieces of the NetBeans Platform together in a logical sequence, with many code samples on GitHub, then look no further. If you're wondering about the NetBeans Platform module system, file system, lookup, loose coupling solution, nodes, TopComponent, cookies/capabilities, as well as Visual Library widgets, the project system, and much much more, then this book is really really exactly what you're looking for.

Best of all, if you're missing anything, or anything isn't explained in enough detail, then you can contact the authors and they'll add more content to the book, i.e., it is a living book. Don't throw it aside if you don't like what you're reading. Instead, contact the authors and tell them what they should do to make the book be what you want it to be.

For a free sample PDF, with the initial pages, e.g., table of contents and so on, as well as the first few chapters, click here:

http://samples.leanpub.com/nbp4beginners-sample.pdf

And this is the location of the book itself:

https://leanpub.com/nbp4beginners

Seriously, buy it. Buy it today.

More details on the book:

Note: The authors of the book also offer NetBeans Platform training courses, especially in the US, since that's where they live.

Thursday Jun 26, 2014

10 Years @ NetBeans

A few days ago I received a message congratulating me for my employment anniversary of 10 years of service to Oracle. Together with a picture of the commemorative award:

It's great that my pre-Oracle years were included, i.e., I have only worked for Oracle for 4 years, since the Oracle/Sun takeover. I also like the thought that even when I wasn't working for Oracle, I was somehow still working for Oracle, in anticipation of the time when my secret work for Oracle would be rewarded with an actual contract and, some years later, a pen.

However, one constant in the past 10 years has been... NetBeans. That's what I've been working on for 10 long and varied years. What's kept it interesting is a combination of the awesome NetBeans APIs and the great worldwide NetBeans community, from Anton to Zoran. I think Java is a fantastic platform and programming language and I've done everything I can to support and promote it, as well as more recently its integration with the HTML5 platform, via the tooling that NetBeans provides. Because without tools and, indeed, being able to choose between competing tools, a language or a platform is just a big incoherent stack of specifications and other documents. It's been a fun time, here's to the next 10 years.

Wednesday Jun 25, 2014

Tuesday Jun 24, 2014

Injecting the NetBeans Platform into a Maven Application

Here we have a simple application in Maven.

It has a GUI that uses ServiceLoader.load to process a text, using two SPI implementations, one for converting the input to uppercase, the other to lowercase. The GUI module has a Main class that prints output to System.out. The Maven modules are contained in a Maven reactor module named "WordProcessor".

Here is a ZIP containing the above app.

Our task is to migrate this application to the NetBeans Platform. The nice thing about applications that use Maven is that a concept of modularity already exists. This is, of course, compile-time modularity, while the NetBeans Platform offers run-time modularity, which is one of the reasons we might have for wanting to migrate this application to the NetBeans Platform in the first place.

The most immediate approach one can think of when migrating this application is to create a new Maven-based NetBeans Platform application and copy and paste the content of our modules into the new modules in our new application. But, since both applications are Maven based, maybe we should explore (1) reconfiguring the reactor module to use the NetBeans Maven plugin, (2) adding a new Maven module that will provide the NetBeans Platform application archetype, (3) changing the POM files of the existing Maven projects to make them NetBeans modules, and (4) adding another Maven module to provide the NetBeans Platform branding module.

This approach I call "injecting the NetBeans Platform", versus the standard approach which is "migrating to the NetBeans Platform". The injection approach might make sense in large Maven applications, since you don't want to spend weeks copying and pasting classes, etc, from a non-NetBeans Maven module into a NetBeans Maven module. Instead, you'd simply like to Mavenize your existing application by adding a few new Maven artifacts here and there, changing some POM files, and basically sugaring your existing Maven application with NetBeans Platform content. (It's comparable to the mountain coming to Mohammed, instead of Mohammed going to the mountain; where the mountain is the NetBeans Platform and Mohammed is your application. Yes, a true miracle.)

Note: I am not recommending this approach, I am not advising against it either. I am simply providing it as one approach to consider when porting a Maven based application to the NetBeans Platform.

Here's how to do it.

Part 1: Reconfiguring the Reactor POM

Open the POM of the reactor, i.e., the WordProcessor main project application, i.e., the one that contains the other Maven modules. Add the Maven repo that contains the Maven NetBeans Platform modules:

<repositories>
    <!--
    Repository hosting NetBeans modules, especially APIs.
    Versions are based on IDE releases, e.g.: RELEASE691
    To create your own repository, use: nbm:populate-repository
    -->
    <repository>
        <id>netbeans</id>
        <name>NetBeans</name>
        <url>http://bits.netbeans.org/nexus/content/groups/netbeans/</url>
    </repository>
</repositories>

Next, add this build section:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>nbm-maven-plugin</artifactId>
                <version>3.13</version>
                <extensions>true</extensions>
                <configuration>
                    <brandingToken>${brandingToken}</brandingToken>
                    <cluster>${brandingToken}</cluster>
                </configuration>
            </plugin>
            <plugin>
                <!-- NetBeans 6.9+ requires JDK 6, starting NetBeans 7.4 source 1.7 is required -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
        </plugin>
        </plugins>
    </pluginManagement>
</build>

Finally, change the properties of the reactor's POM to include netbeans.version and brandingToken:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <netbeans.version>RELEASE80</netbeans.version>
        <brandingToken>wordprocessor</brandingToken>
</properties>

Part 2: Injecting the NetBeans Platform Application

Next, we're going to create a special NetBeans Maven module, one that has goals for running and debugging the NetBeans Platform application. We'll start by creating just an ordinary Maven NetBeans module and we'll then change its POM to use the 'nbm-application' packaging type, instead of 'nbm'. Start like this, to make sure the Maven module will end up being part of the reactor:

Next, choose "NetBeans Module" in the Maven category:

Name the Maven module "Application", or anything else you like, but to me "Application" is clearest. You could, for example, instead, name it "NetBeans", to indicate that it represents the NetBeans Platform in your Maven application.

When you finish the wizard above, you should now see a new Maven module named "Application", with a purple icon. There's also a warning badge that tells you you need to associate a NetBeans Platform with the project. Right-click the Application module, choose "Resolve Project Problems", click Resolve, and then click "Define Property". Now a 'settings.xml' file is added to the "Project Files" node of the reactor. You might now need to close and open the whole project, just to refresh it, you might also need to build it, but in the end the warning icon should be gone as shown here:

Now let's change the POM of the Application module so that the Application module gets an orange icon in the Projects window, instead of a purple one, indicating that it is a NetBeans Platform application module, instead of a NetBeans module.

In the POM, change the packaging type from "nbm" to "nbm-application". And immediately the icon changes from purple to orange.

Change the dependencies section to the following:

<dependencies>
   <dependency>
      <groupId>org.netbeans.cluster</groupId>
      <artifactId>platform</artifactId>
      <version>${netbeans.version}</version>
      <type>pom</type>
   </dependency>
</dependencies>

Change the build section to this:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>nbm-maven-plugin</artifactId>
        </plugin>
        <!-- Permits NbModuleSuite to be run in integration-test phase: -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.2</version>
            <configuration>
                <systemPropertyVariables>
                    <all.clusters>${all.clusters}</all.clusters>
                    <branding.token>${brandingToken}</branding.token>
                </systemPropertyVariables>
            </configuration>
        </plugin>
    </plugins>
</build>

Add this profiles section:

<profiles>
    <profile>
        <id>deployment</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>nbm-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>extra</id>
                            <goals>
                                <goal>autoupdate</goal>
                                <goal>webstart-app</goal>
                                <goal>build-installers</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Finally, add this properties section:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <all.clusters>${project.build.directory}/${brandingToken}</all.clusters>
</properties>

Build the reactor and everything should be good:

Here is a ZIP containing the above app.

Right-click the Application and choose Run. The NetBeans Platform starts up. However, the four Maven modules with which we started are not loaded into the application. That's because we need to make them Maven NetBeans modules and add them as dependencies to the Application. That's the focus of the next step.

Part 3: Converting Maven Modules to NetBeans Maven Modules

Open the POM of the "GUI" module. Change its packaging from "jar" to "nbm". The icon should now become purple, indicating that it is a Maven NetBeans module.

Next, add this build section:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>nbm-maven-plugin</artifactId>
            <extensions>true</extensions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <useDefaultManifestFile>true</useDefaultManifestFile>
            </configuration>
        </plugin>
    </plugins>
</build>

Now we need to make sure that the GUI module will be loaded into the NetBeans Platform application when you run the Application module. Open the GUI module in the Projects window. Right-click on the Dependencies node in the Application project, choose Add Dependency, then in the Open Projects tab you should see the GUI project, with its purple icon, select it and choose Add. It is now added as a dependency of the Application project, while the three other Maven modules (which are not yet NetBeans Maven modules) are shown as transitive dependencies, i.e., greyed out.

Switch to the Files window. Below the 'main' folder, on the same level as 'java', create a folder named 'nbm', containing a manifest.mf file with this content:

Manifest-Version: 1.0

Clean and build the reactor. Use the New Window Component wizard to create a new TopComponent with any name and any location, etc, i.e., anywhere at all. You should not encounter any problems. Run the application and you should see your window.

Add this to the end of the TopComponent constructor, to prove that your original code, i.e., the code that's in the Main class in the GUI module, still works, i.e., the ServiceLoader loads your SPI implementations correctly:

JTextArea ta = new JTextArea();
ServiceLoader<Processor> sl = ServiceLoader.load(Processor.class);
for (Processor p : sl) {
    ta.append(p.process("input to be processed"));
}
setLayout(new BorderLayout());
add(ta, BorderLayout.CENTER);

You should see the output from your processors appear in the text area in the TopComponent you created. In other words, right now, we have only moved one Maven module to a NetBeans Maven module. The other Maven modules could stay the way they are, i.e., you don't have to move them to NetBeans modules. On the other hand, if you want to integrate them more closely into the NetBeans module system, e.g., to have support for hiding classes from other modules and to provide support the NetBeans versioning features, you could move those modules to the NetBeans modules, too. But, as you can see, you have a choice. The only Maven modules you have no choice about are those that need to integrate with the NetBeans Platform in some way, e.g., the window system or menubar, etc.

Part 4: Integrating the NetBeans Branding Module

Our final step is to add another NetBeans Maven module, as described in detail in part 2. Name it, for example, "Branding". Once the module has been created, go to the Files window, and go to src/main/java. There, create a new folder, i.e., on the same level as 'nbm', named 'nbm-branding'. Now go back to the Projects window and you should be able to right-click on the Branding module and choose a menu item right near the end, above 'Properties', named 'Branding', where you can set splash screen, icons, etc. Add the Branding module as a dependency to the Application module, as done for the GUI module in the previous section.

Here is a ZIP containing the above app.

Hurray, your Maven application has now been injected with the NetBeans Platform. At this point you're not completely finished, there's probably other things to do, but at least you now have a starting point. Continue from this point onwards to code against the NetBeans APIs, etc. Interested to know what readers out there think about this approach.

Monday Jun 23, 2014

Floatable Toolbars on the NetBeans Platform

So you're creating your awesome application on the NetBeans Platform...

But... you want the toolbars to be floatable. 

Notice that above there are now suddenly new 'floatable' markers to the left of each toolbar, indicating that you can drag the toolbar out of the toolbar container, as has been done for two toolbars here:


Here's how:

import org.openide.awt.Toolbar;
import org.openide.awt.ToolbarPool;
import org.openide.windows.OnShowing;

@OnShowing
public class Startable implements Runnable {
    @Override
    public void run() {
        ToolbarPool tb = ToolbarPool.getDefault();
        Toolbar[] toolbars = tb.getToolbars();
        for (Toolbar toolbar : toolbars) {
            toolbar.setFloatable(true);
        }
    }
}

Note that this only works, to my knowledge anyway, with Nimbus. At least, I tried with Metal and I didn't see the handles for dragging and hence probably the same is true for other look and feels. To return a toolbar to the toolbar container, click the "x", i.e., the close button top left in the dialog that contains it. Also, there's a "Reset Toolbars" menu item in the toolbar which you probably want to remove/hide if you're using the solution above because it causes strange behavior in the above scenario.

Sunday Jun 22, 2014

NetBeans Platform as a RESTful Web Service Client

OK, let's now port the RESTful web service client created yesterday to the NetBeans Platform. Create a new NetBeans Platform application and create within it a new module. Next, create a new TopComponent via the New Window Component wizard.

Then go to the Project Properties dialog of the module. In Libraries | Wrapped JARs, include the JARs shown below.

Some of the JARs above come from the New Window Component wizard, i.e., the Window System API JAR and Nodes API JAR, among others, are added because you used the New Window Component wizard.

All the others are there because they were there at the end of the blog entry yesterday. I.e., I had generated a RESTful Web Service Client in NetBeans IDE, which added multiple JARs to the classpath of the Java SE application. These are the JARs that I added to the module as described above.

Better would be to create a separate library wrapper module, etc. Instead of including all the JARs in your functionality JAR. But the point of this exercise is simply to get the code below to work, which it does, once all the JARs above have been added as described above.

public CustomerExplorerTopComponent() {
    initComponents();
    setName(Bundle.CTL_CustomerExplorerTopComponent());
    setToolTipText(Bundle.HINT_CustomerExplorerTopComponent());
    setLayout(new BorderLayout());
    JList list = new JList();
    DefaultListModel dlm = new DefaultListModel();
    SalesdataJerseyClient client = new SalesdataJerseyClient();
//        CustomerFacadeREST_JerseyClient client = new CustomerFacadeREST_JerseyClient();
    GenericType<List<Salesdata>> gType = new GenericType<List<Salesdata>>() {};
//        GenericType<List<Customer>> gType = new GenericType<List<Customer>>() {};
    Response response = client.findAll_XML(Response.class);
    List<Salesdata> sds = response.readEntity(gType);
    for (Salesdata sd : sds) {
        dlm.addElement(sd.getSalesyear());
    }
    list.setModel(dlm);
    add(list, BorderLayout.CENTER);
}

The above code is the constructor of the TopComponent created at the start of this blog entry, i.e., I have included code for trying out some of the RESTful Web Service Client code that I ported to the functionality module. I.e., I copied the entity classes and I copied the RESTful Web Service Client into the module and then typed the code above into the constructor of the TopComponent. For example, anyone using the NetBeans Sample Derby database can try out the "CustomerFacadeREST_JerseyClient" shown above (as well as yesterday), together with RESTful Web Services generated from that same database, with this result:


Note that probably not all the JARs shown in the first screenshot above are needed. But, if those are present, the above definitely works. Now you can start weeding out the ones, could be about 5 or so I guess, that are maybe not needed after all. Via trial and error, which would have been simpler when using Maven of course, I have managed to get the list down to this:


Saturday Jun 21, 2014

RESTful Web Service Clients

Here's a small snippet that's useful for hooking into the generated code for creating RESTful web service clients in NetBeans IDE. I.e., you start by exposing the database via RESTful web services, then you create a RESTful web service client, which gives you a new Java class with a bunch of methods for interacting with the web services.

Now, how do you print out all the, for example, customers via your RESTful web service client? Here's how, where "CustomerFacadeREST_JerseyClient" is the name of the generated RESTful web service client:

public static void main(String[] args) {
    CustomerFacadeREST_JerseyClient client = new CustomerFacadeREST_JerseyClient();
    GenericType<List<Customer>> gType = new GenericType<List<Customer>>() {};
    Response response = client.findAll_XML(Response.class);
    List<Customer> customers = response.readEntity(gType);
    for (Customer c : customers) {
        System.out.println(c.getCustomerId() + " / " + c.getName());
    }
}

And here's a step by step silent YouTube movie that shows you how to get to the place where the code snippet above can be used, i.e., how to expose a database via RESTful web services and consume them via a generated RESTful web service client:

Friday Jun 20, 2014

Fixed: MessageBodyReader not found for media type

I've been plagued with this error over the past few days:

Exception in thread "main" org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class com.mycompany.customerclientmaven.Customer, genericType=class com.mycompany.customerclientmaven.Customer.
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:173)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:768)

This is what you get when you're running a RESTful web service client, e.g., you've created RESTful web services that expose customers, etc. Now you want to access those services. 

In your client code you have statements like this:

resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);

Everything compiles fine. Then you run the application and see the stack trace above.

Much googling later brought me to this which works out of the box:

http://code.google.com/p/genson

Genson is a data-binding and streaming library for JSON. It implements the extension points MessageBodyReader and MessageBodyWriter of JAX-RS and declares its implementation with Java's service loader mechanism. That in turn allows Jersey (and other RESTful web service libraries) to automatically detect Genson and use it for JSON parsing/writing.

For Maven, it's as simple as adding this, otherwise download the JAR and add it to your classpath yourself.

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>0.99</version>
</dependency

Wednesday Jun 18, 2014

Belgrade Brings UML Back to NetBeans IDE

The Open Source Development Center in Belgrade, Serbia, recently presented the current state of their work on UML tooling for NetBeans IDE.

Below you see Milan Djoric showing a pretty complex looking UML graph which he generated from a Java application. Indeed, reverse engineering of UML graphs is supported, as well as tools for creating UML graphs from scratch.

Together with Ilija Ivanovic, who also presented during the session above, as well as Stefan Petrovic, the team is doing great work. They've narrowed the scope to class diagrams, specifically. The tools they're creating let you create a new UML project, via a new UML project type, after which you can draw class diagrams, via items that can be dragged from the palette and dropped, and arranged on a Visual Library scene in a TopComponent. From the diagram, you can generate Java source files into an existing project in the IDE and regenerate them when the diagram changes. And, from the Java source files, you can generate/regenerate the diagram.

If your curiosity is combined with a sense of adventure, you can download and build the sources of these new tools here:

https://java.net/projects/nb-uml-plugin/sources/nb-umlplugin/show/branches/phase2

They're under heavy development. "Buyer" beware. I put the sources together, generated NBMs, and installed them into NetBeans IDE 8.0. Not a problem at all and then reverse engineered the class diagram below from the Anagram Game sample. Click to enlarge the image below. (I scrunched up the widgets a bit to make the screenshot. It looks a lot better when enlarged below, though the image above gives an even better picture of the graph at full scale.)

The team mentioned that they're using a solution via Jung that Tim Boudreau created and blogged about here for the arrangement of the widgets in the scene. In his presentation, Milan Djoric said that he learned an unexpectedly massive amount of things about areas he never knew about before, including compiler APIs and reflection APIs.

I would suggest the following usability changes be done before the plugin is released: move the satellite view into the Navigator, move the Explorer Window into the Navigator, and add the "Reverse Engineer" action to the right-click popup of projects (i.e., not only to the Source menu, where it is now). Also, Undo/Redo needs to be added and the Delete key should delete widgets, in addition to the right-click popup menu that already does this.

Great work, guys. Really excellent. Looking forward to the official release.

Tuesday Jun 17, 2014

Neuroph/JMonkeyEngine SDK Mashup

I recently attended a presentation where Milos Randjic demonstrated JMonkeyEngine SDK visualization within Neuroph, together with Tihomir Radosvljavic, who is working on the development of an AI Engine that will be used to integrate Neuroph and JMonkeyEngine SDK. Both Milos and Tihomir are working with Zoran Sevarac (Duke's Choice Award Winner, Java Champion, NetBeans Dream Team member) at the Open Source Development Center at the University of Belgrade in Serbia.

To give an impression of the result of the integrated visualization, here's two screenshots I got from Zoran:

I mentioned this on Twitter, where Sean Phillips, a Duke's Choice Award winner and NASA contractor, then asked how this is achieved. Well, of course, both these applications are based on the NetBeans Platform. That makes it possible to share modules with each other, as the Neuroph team has done, in discussion with the JMonkeyEngine SDK team.

But the question is "how". There are several answers imaginable, here they are.

  • Reuse the Sources. Both of the two projects are open source. So you can download the JMonkeyEngine SDK sources, copy NetBeans modules from there into your own, e.g., Neuroph sources. This is the approach that the Neuroph team took and it is definitely only a good idea if you want to change the sources somehow. I.e., if you want to tweak the sources in some way. But the better approach would be to ask the JMonkeyEngine SDK team to tweak their sources themselves, if making this request makes sense. The Neuroph team mentioned that their main challenge was to make the JMonkeyEngine SDK sources compilable within Neuroph. Ideally you wouldn't have this problem because you'd use one of the other approaches below.

  • Create Library Wrappers. Instead of copying source files, here you take the JARs and wrap them into an existing NetBeans module or create a new library wrapper module that contains the JARs. In general, this is a good approach if you're wanting to incorporate a few JARs that don't already belong to a NetBeans Platform application. Via the library wrapper module project template in the IDE, you can browse to the JARs you need on disk and then you'll have a new module that contains your JARs. Or you can go to the Project Properties dialog of an existing NetBeans module, open the Libraries tab, and you'll see a tab for browsing to the JARs you need on disk.

  • Create Clusters. If you're incorporating JARs that come from another NetBeans Platform application, that is, as in the case of JMonkeyEngine SDK, a set of JARs created and organized as part of a NetBeans Platform application, you can add the entire NetBeans Platform application as a new cluster, i.e., a set of related modules that will be organized into a separate folder in the installation directory, such as 'platform' and 'ide', as described here, as well as here. From the cluster, you can select which specific JARs, which might only be two or three, that you need to include in your application. The user will install your application and then have a new folder named "jme" (or "jmonkeyengine" or whatever the cluster name is that you define) containing the JARs from JMonkeyEngine SDK that you can then treat as APIs, i.e., use their classes as you would any other JARs in your application. You'll also benefit from the public/private package-level settings, e.g., you'll only have access to those packages that have been explicitly declared public.

The latter is the preferred approach that the Neuroph team should take, except if they need to get at the sources somehow, which is not desirable.

As an alternative to incorporating JMonkeyEngine SDK, the team also considered using JavaFX 3D instead. But they decided to pursue the JMonkeyEngine SDK approach, rather than use JavaFX in their existing Java Swing application.

Monday Jun 16, 2014

Maltego on NetBeans by PinkMatter Featured in Latest Java Magazine

Open-source intelligence and forensics software Maltego, built on the NetBeans Platform, by PinkMatter is the feature article in the latest Java Magazine:

Congratulations, Chris Bohme and team, it's a great article and Maltego is clearly very mature and useful. And the article is detailed and entertaining too!

The article can be read here:

http://www.oraclejavamagazine-digital.com/javamagazine_open/20140506#pg29

Further info:

In the NetBeans Platform world, Chris from PinkMatter is especially famous for the NetBeans Platform ribbon bar, as well as the tabbed toolbar, which he contributed to the community:

https://platform.netbeans.org/tutorials/nbm-ribbonbar.html

http://netbeans.dzone.com/how-create-tabbed-toolbar-on-nb

Thanks again for these great innovations, Chris.

Friday Jun 13, 2014

How To Know Which Node You Dropped On

A great question from Chris Esposito from Boeing, who wants to know how to know on which Node a drop has taken place. For the context, read this blog entry. For the answer, as almost always in the NetBeans Platform: "Use the Lookup." I.e., put the object, in this case a String representing a name, into the Lookup of the Node on which you're going to be dropping. Then, when you do the drop on a Node, you can check what is in its Lookup. Or, expressed in code:

@Override
protected Node createNodeForKey(String name) {
    Node node = new AbstractNode(Children.LEAF, Lookups.singleton(name)) {
        @Override
        public PasteType getDropType(Transferable t, int arg1, int arg2) {
            final Node draggedNode = NodeTransfer.node(t, arg1);
            return new PasteType() {
                @Override
                public Transferable paste() throws IOException {
                    names.add(draggedNode.getDisplayName());
                    refresh(true);
                    String theDraggedNode = draggedNode.getDisplayName();
                    String theNodeOnWhichTheDropOccurred = getLookup().lookup(String.class);
                    String message = "You dropped "
                            + theDraggedNode + " on "
                            + theNodeOnWhichTheDropOccurred + "!";
                    StatusDisplayer.getDefault().setStatusText(message);
                    return null;
                }
            };
        }
    };
    node.setDisplayName(name);
    return node;
}

So, now, instead of simply adding the dropped Node to the end of the list, you can add it right after the Node which you dropped it on:

@Override
protected Node createNodeForKey(String name) {
    Node node = new AbstractNode(Children.LEAF, Lookups.singleton(name)) {
        @Override
        public PasteType getDropType(Transferable t, int arg1, int arg2) {
            final Node draggedNode = NodeTransfer.node(t, arg1);
            return new PasteType() {
                @Override
                public Transferable paste() throws IOException {
                    String theDraggedNode = draggedNode.getDisplayName();
                    String theNodeOnWhichTheDropOccurred = getLookup().lookup(String.class);
                    int i = names.indexOf(theNodeOnWhichTheDropOccurred);
                    names.add(i+1, draggedNode.getDisplayName());
                    refresh(true);
                    String message = "You dropped "
                            + theDraggedNode + " on "
                            + theNodeOnWhichTheDropOccurred + "!";
                    StatusDisplayer.getDefault().setStatusText(message);
                    return null;
                }
            };
        }
    };
    node.setDisplayName(name);
    return node;
}

Result:

Thursday Jun 12, 2014

Unzipping in Java and FileUtil.copy

Via NetBeans File Systems API, which provides FileUtil.copy below, which means a dependency on NetBeans Utilities API:
private void unzipEpubFile(String folder, File file) throws IOException {
    final AtomicBoolean canceled = new AtomicBoolean();
    //define and start progress bar here...
//        ProgressHandle handle = 
//                ProgressHandleFactory.createHandle(
//                        Bundle.MSG_unpacking(zip.getName()), 
//                        new Cancellable() {
//            @Override
//            public boolean cancel() {
//                return canceled.compareAndSet(false, true);
//            }
//        });
    //then unzip 'file' into 'root":
    try {
        List folders = new ArrayList<>();
        try (InputStream is = new FileInputStream(file)) {
            ZipInputStream zis = new ZipInputStream(is);
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                if (canceled.get()) {
                    return;
                }
                String n = entry.getName();
                File f = new File(folder, n);
                if (n.endsWith("/")) {
                    if (!f.isDirectory()) {
                        if (!f.mkdirs()) {
                            throw new IOException("could not make " + f);
                        }
                        if (entry.getTime() > 0) {
                            if (!f.setLastModified(entry.getTime())) {
                                // oh well
                            }
                        }
                    }
                    folders.add(f);
                } else {
                    //handle.progress(Bundle.MSG_creating(n));
                    File p = f.getParentFile();
                    if (!p.isDirectory() && !p.mkdirs()) {
                        throw new IOException("could not make " + p);
                    }
                    try (OutputStream os = new FileOutputStream(f)) {
                        FileUtil.copy(zis, os);
                    }
                    if (entry.getTime() > 0) {
                        if (!f.setLastModified(entry.getTime())) {
                            // oh well
                        }
                    }
                }
            }
        }
        //handle.switchToDeterminate(folders.size());
        if (canceled.get()) {
        }
    } finally {
        //stop progress bar
    }
}

Mostly from NetBeans IDE sources for working with projects and ZIP files.

Wednesday Jun 11, 2014

On JavaOne 2014

With JavaOne 2014 acceptance notifications going out, it's time to contemplate this cartoon, thanks to @omniprof pointing me to phdcomics.com recently:

Oddly familiar. :-) 

Tuesday Jun 10, 2014

Fosfor EPUB Reader

Instead of creating a fullblown NetBeans Platform application for doing WYSIWYG editing for EPUB, similar to Sigil, I decided to focus purely on the very narrow scope of EPUB reading. The scope is narrower and, since the application will be a lot less ambitious and smaller, a pure JavaFX implementation makes sense.

When you somehow get, e.g., buy, an EPUB file, you typically read it on a tablet or mobile device. However, some people in the world, e.g., me, still have laptops. Therefore, I'm creating a small JavaFX application that unzips EPUB files, into a temp directory, and then loads them into a JavaFX WebView.

Arabic support:

For an application like this, simplicity is the most important thing. Very few buttons, very few options, preferably no configuration of anything. Just let the user open the EPUB file and read it, that's it, nothing fancy.

CSS stylesheets and images are correctly read. It's exactly what it looks like, a reader for EPUB files. The back and forward buttons are working and you can also switch to the table of contents.

When it is complete, which it pretty much is right now, publishers of EPUB files can make this small app available from their site, to simplify life for their readers, since it will run easily and well on all operating systems.

Monday Jun 09, 2014

Cross Domain Enterprise Solutions on the NetBeans Platform

Bray 2.0 is a tool based on the NetBeans Platform that assists in creating valid Data Flow Configuration (DFC) files.

The DFC Specification was developed to provide a standardized way for defining, validating, and approving data flows for use on cross-domain guarding solutions. A DFC document specifies key entities such as security domains, guards that facilitate data between security domains, data flows that describe how data travels between security domains, filters that transform and validate the data and more.

The Bray product is in development at Fulcrum IT (http://www.fulcrumco.com).

The DFC Specification and Bray were developed in support of the US Department of Defense.

Bray 2.0 marks the first release of Bray on the NetBeans Platform and utilizes a number of features that are core to the NetBeans Platform:

  • Modular plugability. Bray consumers can integrate their own tools, file types, and more into the product with relative ease.

  • Robust UI. The NetBeans Platform intuitive UI makes it easy to access and manipulate multiple aspects of a DFC.

  • Explorer. The Explorer is a key component that makes the DFC XML easy to traverse, edit, and find errors.

  • Context-sensitive help. JavaHelp can be readily integrated for the product as well as all the UI within.

  • Editors. Any external file can be added to a DFC. Users can register their own editors or use the provided NetBeans editors to edit files.

  • Printing. The NetBeans Platform Print API makes it easy to determine what should be printed and how.  

A screenshot:


Bray 2.0 provides a lot of key features in developing valid, robust DFC files: 

  • XML validation. A DFC can be validated against the DFC schema specification.

  • DFC Check List. An interactive, minimal guide for creating a complete DFC.

  • Summary Window. The Summary Window functions like the Navigator in NetBeans IDE. The current "item of interest" is checked against various business rules and provides the ability to quickly find and fix errors.

  • Change Log. Bray audits every change to a DFC and places them in a change log for users to peruse.

  • Comments. Users can optionally add comments for other users to see.

  • Digital signatures. DFC files can be digitally signed. A signature history and signature validation is provided in Bray.

  • Pluggable security schemes. Bray ships with plain text and IC-ISM security schemes. If needed, users can integrate additional ones. 

...and more to come! New features for Bray are constantly in development including use of the NetBeans Visual Library, language support, and more.

More screenshots:

 The final screenshot above is the splash screen!

Sunday Jun 08, 2014

Integrating Amazon EC2 in Java via NetBeans IDE

Next, having looked at how to integrate from Java with Amazon Associates and Amazon S3, let's take a look at Amazon EC2, the elastic compute cloud which provides remote computing services. I started by launching an instance of Ubuntu Server 14.04 on Amazon EC2, which looks a bit like this in the on-line AWS Management Console, though I whitened out most of the details:

Now that I have at least one running instance available on Amazon EC2, it makes sense to use the services that are integrated into NetBeans IDE: 

I created a new application with one class, named "AmazonEC2Demo". Then I dragged the "describeInstances" service that you see above, with the mouse, into the class. Then the IDE automatically created all the other files you see below, i.e., 4 Java classes and one properties file:

In the properties file, register the access ID and secret keys. These are read by the other generated Java classes. Signing and authentication are done automatically by the code that is generated, i.e., there's nothing generic you need to do and you can immediately begin working on your domain-specific code.

Finally, you're now able to rewrite the code in "AmazonEC2Demo" to connect to Amazon EC2 and obtain information about your running instance:

public class AmazonEC2Demo {
    public static void main(String[] args) {
        String instanceId1 = "i-something";
        RestResponse result;
        try {
            result = AmazonEC2Service.describeInstances(instanceId1);
            System.out.println(result.getDataAsString());
        } catch (IOException ex) {
            Logger.getLogger(AmazonEC2Demo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

From the above, you'll receive a chunk of XML with data about the running instance, it's name, status, dates, etc. In other words, you're now ready to integrate Amazon EC2 features directly into the applications you're writing, without very much work to get started. Within about 5 minutes, you're working on your business logic, rather than on the generic code that anyone needs when integrating with Amazon EC2.

Saturday Jun 07, 2014

Integrating Amazon S3 in Java via NetBeans IDE

To continue from yesterday, let's set up a scenario that enables us to make use of this drag/drop service in NetBeans IDE:

The above service is applicable to Amazon S3, an Amazon storage provider that is typically used to store large binary files. In Amazon S3, every object stored is contained in a bucket. Buckets partition the namespace of objects stored in Amazon S3. More on buckets here. Let's use the tools in NetBeans IDE to create a Java application that accesses our Amazon S3 buckets.

Create a Java application named "AmazonBuckets" with a main class named "AmazonBuckets". Open the main class and then drag the above service into the main method of the class. Now, NetBeans IDE will create all the other classes and the properties file that you see in the screenshot below.

The first thing to do is to open the properties file above and enter the access key and secret:

access_key=SOMETHING
secret=SOMETHINGELSE

Now you're all set up. Make sure to, of course, actually have some buckets available:

Then rewrite the Java class to parse the XML that is returned via the generated code:

package amazonbuckets;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.netbeans.saas.amazon.AmazonS3Service;
import org.netbeans.saas.RestResponse;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class AmazonBuckets {
    public static void main(String[] args) {
        try {
            RestResponse result = AmazonS3Service.getBuckets();
            String dataAsString = result.getDataAsString();
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(
                    new InputSource(new ByteArrayInputStream(dataAsString.getBytes("utf-8"))));
            NodeList bucketList = doc.getElementsByTagName("Bucket");
            for (int i = 0; i < bucketList.getLength(); i++) {
                Node node = bucketList.item(i);
                System.out.println("Bucket Name: " + node.getFirstChild().getTextContent());
            }
        } catch (IOException | ParserConfigurationException | SAXException | DOMException ex) {
        }
    }
}

That's all. This is simpler to setup than the scenario described yesterday.

Also notice that there are other Amazon S3 services you can interact with from your Java code, again after generating a heap of code after drag/drop into a Java source file:

I tried the above, e.g., I created a new Amazon S3 bucket after dragging "createBucket", adding my credentials in the properties file, and then running the code that had been created. I.e., without adding a single line of code I was able to programmatically create new buckets.

The above outlines a handy set of tools and techniques to use if you want to let your users store and access data in Amazon S3 buckets directly from the application you've created for them.

Friday Jun 06, 2014

Getting Started with Amazon Web Services in NetBeans IDE

When you need to connect to Amazon Web Services, NetBeans IDE gives you a nice start. You can drag and drop the "itemSearch" service into a Java source file and then various Amazon files are generated for you.

From there, you need to do a little bit of work because the request to Amazon needs to be signed before it can be used.

Here are some references and places that got me started:

You definitely need to sign up to the Amazon Associates program and also register/create an Access Key ID, which will also get you a Secret Key, as well.

Here's a simple Main class that I created that hooks into the generated RestConnection/RestResponse code created by NetBeans IDE:

public static void main(String[] args) {
    try {
        String searchIndex = "Books";
        String keywords = "Romeo and Juliet";
        RestResponse result = AmazonAssociatesService.itemSearch(searchIndex, keywords);
        String dataAsString = result.getDataAsString();
        int start = dataAsString.indexOf("<Author>")+8;
        int end = dataAsString.indexOf("</Author>");
        System.out.println(dataAsString.substring(start,end));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

Then I deleted the generated properties file and the authenticator and changed the generated AmazonAssociatesService.java file to the following:

public class AmazonAssociatesService {
    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (Throwable th) {
        }
    }
    public static RestResponse itemSearch(String searchIndex, String keywords) throws IOException {
        SignedRequestsHelper helper;
        RestConnection conn = null;
        Map queryMap = new HashMap();
        queryMap.put("Service", "AWSECommerceService");
        queryMap.put("AssociateTag", "myAssociateTag");
        queryMap.put("AWSAccessKeyId", "myAccessKeyId");
        queryMap.put("Operation", "ItemSearch");
        queryMap.put("SearchIndex", searchIndex);
        queryMap.put("Keywords", keywords);
        try {
            helper = SignedRequestsHelper.getInstance(
                    "ecs.amazonaws.com",
                    "
myAccessKeyId",
                    "mySecretKey");
            String sign = helper.sign(queryMap);
            conn = new RestConnection(sign);
        } catch (IllegalArgumentException | UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException ex) {
        }
        sleep(1000);
        return conn.get(null);
    }
}

Finally, I copied this class into my application, which you can see is referred to above:

http://code.google.com/p/amazon-product-advertising-api-sample/source/browse/src/com/amazon/advertising/api/sample/SignedRequestsHelper.java

Here's the completed app, mostly generated via the drag/drop shown at the start, but slightly edited as shown above:


That's all, now everything works as you'd expect.

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
« June 2014 »
SunMonTueWedThuFriSat
14
15
19
28
29
     
       
Today