Let's say you have some programming language for which you want to create a drag-and-drop code generator. What's the best of these in the world? The award winning Matisse GUI Builder, of course. Why spend days, weeks, and months creating a new GUI Builder, if one already exists? Currently, Matisse isn't built to be extended or customized. (Hopefully it will in the future, so that Ruby and Groovy programmers, for example, will be able to use it to create their GUIs.) So, currently, assuming we want to use the Matisse GUI Builder for our own language, there are two questions we need to answer. Firstly, how to incorporate it into our own application; secondly, how to change it just enough to serve our purposes while at the same time leveraging as much of the original code as possible.
In this blog entry, I'll discuss an approach to answering the first question. I've been investigating a simple way of extracting the Matisse GUI Builder so as to reuse it for Groovy. Here is the simple approach I've taken. It works and is surprisingly unmessy. The good thing is that the Matisse GUI Builder is provided by one single NetBeans module. It has many dependencies on other modules, but that's unsurprising and not a problem at all. In this procedure, we'll get the NetBeans module via CVS from the NetBeans sources, tweak some of the project files slightly so that we can open the module outside of the NetBeans sources, build the module, tweak the dependencies as necessary, make a very small change to the sources so that we can try out our new version of the Matisse GUI Builder, and then install it in the IDE.
Note: After installing the customized Matisse GUI Builder, you will not be able to use the default Matisse GUI Builder provided by NetBeans IDE. (Until you remove the user directory and restart NetBeans IDE, which will remove the module from your user directory and return NetBeans IDE to its defualt state, with the default Matisse GUI Builder.)
Here are the steps to take:
- Get the very latest 6.0 development build. Why? Well, you will be checking out the Matisse GUI Builder from the NetBeans sources. These sources are being updated continually. In order to build the module after you check it out, you will need to have the latest modules available to the NetBeans Platform where your customized Matisse GUI Builder will be installed. Therefore, the NetBeans Platform needs to have the very latest versions of modules, with the very latest classes and so on. Therefore, it might even make sense to check out all the NetBeans sources, and build NetBeans IDE from those sources, so that you have the very latest versions of everything available. If you want to take a risk, check out the most recent daily development build of 6.0. But possibly you will run into problems later if the module that provides the Matisse GUI Builder cannot find the dependencies it needs, because they are not available to the NetBeans Platform you are using.
- From NetBeans CVS, check out one module only. It is called "Form". This module provides the Matisse GUI Builder.
- Because "Form" is a module in the NetBeans sources, you can only open it if you have checked out all the other NetBeans sources. For example, it makes use of an Ant script that is not in the module, but in some other folder (the central "nbbuild" folder) in the sources.
However, if you (like me) checked out only the "Form" module, here's what you need to do to change the project files so that the module will be recognized as a standard NetBeans module:
- Create a normal NetBeans module project. We will copy artifacts from there to our "Form" module.
- Open both module projects in the Favorites window. We will now transfer project pieces from the standard NetBeans module to the one that comes from the NetBeans sources.
- Change this line in the "Form" module's build.xml:
To this line:
- Copy build-impl.xml from the standard NetBeans module project to the "Form" module's "nbproject" folder.
- In project.xml, change the first lines from this:
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
- Copy platform.properties from the standard NetBeans module project to the "Form" module project's "nbproject" folder.
- Now comes the trickiest bit. Although you can now open the "Form" module, even when it is not within the NetBeans sources (assuming you followed the steps above), you might encounter problems when building the module. If the platform against which you are building the "Form" module is not the very latest, there is a chance that there will be conflicts between what the "Form" module expects and what your platform can provide, as explained in the first step above. In any case, you will probably need to remove some dependencies and then re-add them, to refresh the dependency versions. This may take some time. But don't give up hope, because the end result will be worth your trouble.
- At this stage, once you're able to build the module, you should feel pretty good about yourself. Why? Well, now you have Matisse, completely ready for integration in your own application. You can now begin investigating the internals of Matisse, then you can try to make some exploratory tweaks to see the results, and begin analyzing where you will need to do your own work to customize Matisse for your own purposes.
Here's one example. If you go to the org.netbeans.modules.form.resources.templates.SwingForms package, you can change the templates used for generating the Swing forms. Below I've added a cheerful Hello World message to the code that is generated when you create a JFrame in Matisse:
For Groovy, templates such as the above would need to be changed to provide Groovy SwingBuilder code instead of Swing code. A very interesting class to look at is org.netbeans.modules.form.JavaCodeGenerator. That's where a lot of the action happens.
- Finally, once you're ready for distribution, increment the version number of the "Form" module.
Using the above guidelines, you can empower your own language, whatever it is. When I explore the internals of Matisse a bit more, I will try and come up with some tips and tricks and some specific areas to look at that might be useful to others.