Geertjan's Blog

  • April 3, 2007

Capturing Matisse

Geertjan Wielenga
Product Manager
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:

  1. 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.

  2. From NetBeans CVS, check out one module only. It is called "Form". This module provides the Matisse GUI Builder.

  3. 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:

      <import file="../nbbuild/templates/projectized.xml"/>

      To this line:

      <import file="nbproject/build-impl.xml"/>

    • 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"?>
      <project xmlns="http://www.netbeans.org/ns/project/1">
      <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">

      To this:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://www.netbeans.org/ns/project/1">
      <data xmlns="http://www.netbeans.org/ns/nb-module-project/2">

    • Copy platform.properties from the standard NetBeans module project to the "Form" module project's "nbproject" folder.

  4. 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.

  5. 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.

  6. 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.

Join the discussion

Comments ( 6 )
  • Ahmed Mohombe Tuesday, April 3, 2007
    Very interesting :).

    It would be interesting to know if the the above approach works(or what would be required) for the "Web GUI Builder" from the WebPack, since there are much more frameworks that would benefit from a Web GUI Builder than Swing.

    Thanks in advance,

  • Peter Williams Tuesday, April 3, 2007
    Re: #4. Wouldn't matching the form source against the expected release target (e.g. if using 5.5.1 platform, use 5.5.1 form module, not trunk) eliminate this issue?
    It would also be nice to document the changes required to allow the updated module to coexist with the existing form module. (Renaming, etc.)
  • Geertjan Tuesday, April 3, 2007
    Ahmed, that's a good question and I don't know the answer. I'm more interested in Swing, and Java SE in general, than in the web world. So, you could try the same thing for the Visual Web Pack, where the standard GUI generator generates JSF. I know someone was working on something similar for Struts, via the Visual Library API, but I don't know how far they got. I think JSF is very tightly bound to the Visual Web Pack, so I doubt it can be generalized, but I could be wrong.

    Peter, yes you're right. Instead of checking out the sources from CVS, one could check out the platform sources from the download page on netbeans.org. Then one could take the Form module from those sources. However, my assumption is that one wants the same functionality as that provided by the Matisse GUI Builder's latest version, hence these instructions are tailored towards that assumption, i.e., here I'm assuming one wants to have the same functionality in one's own GUI Builder as in the 6.0 Matisse GUI Builder. But clearly life becomes more difficult when one does that, because the 6.0 build is not stable yet. Your approach would be better and safer, and cause less headaches.

  • raffaele castagno Tuesday, April 3, 2007
    Great! Just what I was looking for few days ago!
    +1 for tips to allow coexistence of Matisse and CustomMatisse.
    I'll stay tuned!
  • Abubakar Gurnah Wednesday, April 4, 2007
    Wow! nice article. I think in few years we will have java OS if we continue like this
  • guest Wednesday, April 4, 2007
    I think it would be pretty cool if a user could open a configuration dialog a and move, say, a clock like label arround, or arrange the buttons in a panel to his satisfaction, with the appropriate return (like the gnome bars but inside applications). That would kinda rule.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.