The Source for Java Technology Collaboration
User: Password:



Michael Nascimento Santos's Blog

Community: Java Tools Archives


Making your components work nicer inside Matisse

Posted by mister__m on February 20, 2008 at 07:20 AM | Permalink | Comments (4)

A co-worker had been developing some nice-looking custom components for a customer project. It was tightly integrated with the backend logic, though, so he tried to use it with Matisse, there were several issues, from class loading errors to slowness, since the component was trying to do its "real task" inside the designer.

So, when he told me that, I immediately recalled a trick I came to know way back in 1999, while I was struggling with Java and Swing for the first time. The java.beans package comes with a class named Beans that comes with a bunch of static utility methods. One of them, isDesignTime(), let your component find out if it's being used in preview mode.

He changed the component constructor to check for design time and skip the "black magic" section. It worked like a charm and he said it was the best tip I gave him last year. So now I've finally had the time to blog again, I thought it would be an interesting tip to share :-)



Desktop development made easier with genesis

Posted by mister__m on June 21, 2007 at 02:43 PM | Permalink | Comments (4)

It's been quite a while since the last time I mentioned genesis here. One of the reasons is I've been working on it a lot and there isn't much time left to blog about it. Hopefully I will be able to do so more often.

We have just released genesis 3.0 after almost two years and a half of development. genesis is all about making the development of enterprise desktop applications easier. To accomplish that, genesis provides UI-related features and also a neat way of building and integrating with the back-end of your application. For now, let's focus on the desktop itself.

genesis 3.0 comes with full support for Swing, SWT and Thinlet. It supports binding, validation, actions and conditions. Let us say that for the desktop it tries to address nearly the same problem space as JSR-295 (Beans Binding), JSR-296 (Swing Application Framework) @Actions and JSR-303 (Bean Validation), but there are enough conceptual differences between them (besides supporting SWT and Thinlet out of the box, of course). I've already explained the basic UI binding functionality last year, so here I will try to show why the genesis approach is better.

First, genesis works with an UI model, instead of plain binding. This means your JavaBean represents the UI data plus the presentation logic behind it. It makes your presentation logic UI toolkit-independent, testable and self-contained. It also doesn't require PropertyChangeListeners at all. Consider the most basic binding example in genesis docs:

@Form
public class LoginForm {
   private String user;
   private String password;

   public String getUser() {
      return user;
   }

   public void setUser(String user) {
      this.user = user;
   }

   public String getPassword() {
      return password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

   @Action
   public void login() {
      System.out.println(getUser());
      System.out.println(getPassword());
   }

   @Action
   public void clear() {
      setUser(null);
      setPassword(null);
   }
}

If you were to do the same with JSRs 295 and 296, you would have to create a JavaBean with PropertyChangeListener support, fire property changes on setters and also create two @Action methods in your view that access your bean. As the number of properties, beans and actions involved in a view increases, your code with genesis would still be self-contained and testable, while JSR-295 would require individual bindings to be produced and your actions would be tightly coupled with Swing, manipulating your beans as value objects.

genesis also comes with some unique features of its own, such as declarative conditions. Let's analyze the classic dependent comboboxes issue: whenever the selected country changes, the state list should be reloaded. Here is what it takes to implement this with genesis:

@Form
public class StateSelectionForm {
   private Country country;
   private State state;

   @DataProvider(widgetName="countryTable", objectField="country")
   public List populateCountries() {
      return // business logic to retrieve countries
   }

   public Country getCountry() {
      return country;
   }

   public void setCountry(Country country) {
      this.country = country;
   }

   @DataProvider(widgetName="stateTable", objectField="state")
   @CallWhen("genesis.hasChanged('form:country')")
   public List populateStates() {
      return // business logic to retrieve states
      // Notice getCountry() will return the selected country
   }

   public State getState() {
      return state;
   }

   public void setState(State state) {
      this.state = state;
   }
}

So genesis will automatically invoke the stateTable @DataProvider whenever the selected country changes.

There are many other features and things to explore and I hope I can show them here in the next few days. The Brazilian Portuguese users list is quite active these days and there is of course an English users list. Check out genesis and let me know what you think.

Writing applications that can be embedded in IDEs

Posted by mister__m on July 27, 2005 at 11:21 AM | Permalink | Comments (1)

Well, every time I think I'll be able to blog more often, something happens. So, I will try not to apologize about it and get straight to the point. :-)

A cool thing I did recently was to write a set of NetBeans plugins that adds support for Thinlet in the IDE, called ThinNB. One important feature that it provides is a visual editor for Thinlet xml files. In order to implement it, instead of reinventing the wheel, I've decided to base my work on ThinG, a standalone application created by Dirk Möbius that already did that. There were a few changes I had to do it so it could be embedded in NetBeans and that probably would need to be done to most applications if they were to be converted into IDE plugins, so it is worth talking about them.

ThinG's code is actually well-written, so I didn't have to refactor it in order to expose a single class to my plugin, but this might not be true for other applications. If you are writing an application that might be used as a plugin in the future, make sure everything is properly encapsulated and that the right methods are exposed through your "main" class (which does not have to be the one with the public static void main(String[]) method).

The changes I did concerned four main areas:

  • Appearance
  • I/O System
  • Settings
  • Logging

Appearance

If you are running in embedded mode, there is already a menu bar, a status bar and a toolbar being displayed. It is important these features can be turned off in your application when running in this mode. What I did was to add a boolean parameter to the main class constructor and used it in the section that assembled the UI.

Besides that, since many useful status bar messages were generated by ThinG, I wanted those to be shown at NetBeans's status bar. I solved this problem by creating a simple StatusBar interface with a single method, setText(String) and writing two implementations: one that simples use the Thinlet widget when running as a standalone application and another one that uses NetBeans APIs to display it in the IDE.

If there were menus or toolbar buttons that needed to be made available to the end user, it would probably be necessary to write some listener interfaces so it was possible to enable/disable them as required.

I/O System

If you intend to use your application inside an IDE, it is better to think twice before using java.io, specially java.io.File. IDEs have their own I/O abstraction for some reasons, such as adding listeners to files, performing I/O "transactions" or working with virtual filesystems.

Fortunately, ThinG didn't use java.io.File a lot and I could create a simple interface, thing.spi.FileWrapper, to abstract what was actually being used from java.io.File. Again, I wrote two implementations of it, one that is part of ThinG itself and one that lives in the NetBeans plugin.

Settings

There is a decision to be made about sharing settings: do you want both the IDE and the standalone application to share the same settings or to keep them separate? If you pick option one and your application uses the Preferences API, it is quite straightforward to implement it.

If you want to follow the second path, you just need to define yet another interface for that purpose. Since I wanted to add a few settings and hide one from the end user, I ended up creating a thing.spi.Settings interface.

Logging

I am not sure this is true for other IDEs, but NetBeans has its own API for logging. In order to integrate with it, whether your application use java.util.logging or Commons Logging, you just need to provide an adapter class that "translates" between the logging APIs. Since this issue is basically NetBeans-specific, please take a look at net.java.dev.thinnbeditor.ThinletVisualEditorInstall and net.java.dev.thinnbeditor.logging.LoggerAdapter if you want to know more about it.

Conclusion

ThinG is now both a standalone and an embeddable application after a few changes. It shouldn't be hard to use it as a plugin for Eclipse, IDEA or JDeveloper now, for example. I hope the principles I've explained here can help other people out there as well.



Thinlet plugins for NetBeans

Posted by mister__m on June 06, 2005 at 10:47 AM | Permalink | Comments (0)

Module development for NetBeans is something I've always been interested in, but never had the time to do. This time, however, I was able to; the ThinNB project at java.net adds Thinlet support for the NetBeans IDE.

From the ThinNB project home page, "ThinNB is actually two things: an umbrella project for the ThinNB family of NetBeans modules and also the module responsible for installing the ThinNB Update Center in the IDE." It recognizes Thinlet xml files, adds a new template for a xml file with a panel as it root node, allow files to be previewed inside the IDE, adds support to an embedded visual editor - a modified version of ThinG - and also installs an Update Center in the IDE so it is possible to obtain new releases of the modules in a more natural way.

You can go to the home page to see some screenshots, get information about its features and also read the download and installation instructions. Enjoy it!





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds