Skip to content

General Purpose Editor Within Eclipse

31
Oct
2007

I’ve blogged before about the difficulties I’ve had in finding a solid, general-purpose text editor for my system.  I looked into VIM for Windows, E, SciTi and many more before finally settling on jEdit.  It’s a really good editor, if a bit rough around the edges.  A lot of people (myself included) would put it on par with TextMate in terms of features, and superior to it in some ways thanks to its cross-platform nature.

As a separate application from my IDE, jEdit performs superbly, but although this solves the problem of editing arbitrary files from file explorer, it still leaves open the problem of editing arbitrary file types within Eclipse.  What I had been doing is using jEdit as an external editor, opening it up any time I needed to open a weird file type within Eclipse.  This works fairly well, but it’s heavy on memory, not integrated with tools like Mylyn (as if there were any tools like Mylyn) and it’s just annoying, dealing with a separate app like that. 

What I really want is some sort of embedded jEdit editor canvas within a normal Eclipse editor part.  One would think this would be very possible, given SWT_AWT and its capabilities.  In fact, I was just about to crack open the jEdit source to see if I could roll something myself when an eternal axiom sprang to mind: Google is your friend.  Actually in this case, I used Eclipse-Plugins.info (which IMHO is still the best Eclipse plugins site, despite lacking an active administrator) and did a quick search for any plugins mentioning the word “jedit”.  A few minutes later, I was perusing the page for the little-known Color Editor plugin.

Color Editor is basically a simple Eclipse editor which will open any file for you.  It’s not much more sophisticated than the standard Text Editor which is the default for unknown file types.  However, what it *does* do is parse jEdit’s mode.xml files, providing semi-advanced syntax highlighting for over 150 file types.  Granted, it doesn’t have all of jEdit’s nice editing features or plugins like SuperAbrevs, but if I need that I’ll open up jEdit itself.  For most of what I do, quick-and-dirty syntax highlighting is all I need.

The problems with this plugin are mainly caused by the fact that it’s quite old and hasn’t really been updated recently.  It still defaults to the old-style jEdit colors, which are ugly as sin.  Also, it doesn’t support as granular syntax highlighting as the current version of jEdit (only 2 comment types, 2 literals, etc).  It doesn’t support easy adding of modes (you have to repackage the plugin JAR file), nor does it allow you to simply point it to the same mode catalog used by jEdit itself (which would simplify management of editor modes).  Despite all of that, it’s still a really nice idea.

The plugin works not by embedding a jEdit editor canvas using SWT_AWT, but by just using the standard Eclipse syntax highlighting techniques coupled with the jEdit mode files.  The downside to this approach is the need to write a whole bunch of mode parser code which is effectively already done within jEdit.  Also, odd bugs can leak in around the edges, since the editor is effectively reverse-engineering the jEdit editor part.  However, the approach does have a very unexpected (and pleasant) silver lining: fonts look good.

I’ve had tons of problems with jEdit’s font rendering on Windows, mainly due to the fact that Swing’s font renderer doesn’t seem to be as sophisticated as Vista’s (or at least, less capable of dealing with monospaced fonts).  But since Color Editor uses native font rendering, the text looks 100% native:

jEdit

jEdit Fonts

Eclipse Color Editor

Color Editor Fonts

I assume you can see the difference.  :-)  So, fonts look great, but if you examine the body of the method in the file a bit more, you’ll see examples of those odd bugs I was talking about.  For some reason, Color Editor thinks that the suite variable, as well as the BaseTests, DBTests, SchemaTests and TypeTests classes are all methods, rather than local variables and classes.  This is annoying, but it’s not the end of the world.  Granted, I haven’t been using this tool for all that long, but I’m guessing that instances like this are fairly rare, and not cause for immediate alarm.  You’ll also notice some evidence of the lessened flexibility in the syntax highlighting engine (fewer types of comments in this case) in the way the javadoc and single-line comments are colorized differently.

Download Color Editor Plugin from gstaff.org  (no update site available)

All you have to do is stick the JAR in your eclipse/plugins directory and start Eclipse with the -clean option (usually unnecessary, but just to be safe).  Color Editor will automatically be registered as the default editor for unknown file types.  If you want to change the default colors (as well you should), you can find the preference under Coloring Editor -> Colors (no idea why the conjugation difference between the editor name and the preference pane).  It’s a bit clumsy to try and set all of the colors to a predefined theme (I made mine look like the current jEdit defaults), but it’s all possible.

Hopefully you’ll find this a useful tool in editing those random shell scripts and who-knows-what-else which got included in the project, but for which Eclipse doesn’t have a separate plugin.

Fuse 0.4 Release

2
Jun
2007

Some of you may know that I worked (and have been working) on a little open source project with Romain Guy called Fuse, hosted under SwingLabs at java.net. (not related to the Filesystem in Userspace project) It’s a pretty neat project that was actually started by Romain to assist in the development of the Aerith demo (shown at JavaOne 2006).

The whole idea behind the project is to provide a simple, easy to use resource injection library. Resource injection is different than dependency injection for a number of reasons (explained in more detail on the project page), but suffice it to say that this is an incredibly useful little library that makes centralizing your resource configuration a piece of cake.

I started using Fuse on a regular basis at about the same time I stopped developing Fuse on a regular basis. :-) After I started my latest contract work (back in early last July), I no longer had enough time to devote to the project, so it went by the wayside almost immediately after the 0.3 release. Romain too, was working on various projects (including the book Filthy Rich Clients, coauthored with Chet Haase), so the project really would have just lain dormant for a while, except that I was actually using Fuse in the project I was working on.

This was really the first time (that I know of) that Fuse was used in a solid, large scale application. Those of you that have developed experimental libraries in the past know that you don’t really know that an API is working the way you want until it’s tested in a bona fide application. Well, that was true with Fuse too. In the process of using Fuse, I was able to isolate and fix a number of pesky little bugs that had slipped through our unit testing, as well as improve performance immensely.

Most of the changes made to Fuse were bugfixes, but the big ticket new feature is transparent caching of loaded resources. If a resource has the same value and type as one which has already been instantiated and injected, that instantiated instance will be used. Since Fuse is designed for (though hardly limited to) the injection of immutable resources, this works out really really well. I’ve noticed a huge return in performance from this simple change (alla GUI load times 2x as fast).

Most of these changes (including caching) were made gradually over the last 10 months, so there wasn’t really a clear line where we could say “this constitutes a release now.” For my project, I was just using a custom build of the CVS HEAD version of Fuse, rather than the 0.3 “stable” release. Ironically, it had gotten to the point where I was actually telling other people to use the HEAD version since I knew that it would be more stable and performant than the 0.3 release.

Eventually (as in yesterday), Romain and I decided that there was no real reason to hold off on a release any longer. While our documentation may still be woefully out of date, and while neither of us remembered enough changes for an impressive RELEASE NOTES, we still think that pushing out 0.4 was the right choice.

So, the 0.4 release is now up on the java.net servers and available for download here. If you’re interested in Fuse, or if you’re using Fuse already (especially if you’re using Fuse already), I suggest that you run over to the download site and grab the latest version. There were no API changes in this release, so it should just be a drop-in replacement for the 0.3 version you’re using now.

Oh, if you’re interested in Fuse, there’s some very good explanatory documentation on the project page. It’s a bit out of date (I don’t think it mentions auto-injection even once), but it does a good job on the concepts and provides a solid starting point for anyone wanting to try the library for themselves.

Does Swing Need Saving?

21
Feb
2007

There’s been some discussion lately regarding various scripting languages and if they are (or aren’t) the salvation for the “dying” Swing API (here, here and here). However, all of these blog entries assume one critical fact: Swing is dead or at least dying. I call that assumption into question.

Actually, I was kind of surprised that none of the Sun fan-boys beat me to the punch. Over the years, I’ve shot my mouth of quite a bit against Swing. So it surprises me greatly that I’d be the first to step forward and try to defend Swing. In fact, if you had talked to me a year ago, likely I would have been leading the charge to bury Swing and move on. Apparently, some things have changed…

The first post to hit the blogosphere, JRuby can save Swing summed up the core assumptions of all three pretty quickly:

  • Swing apps are slow to build
  • Swing layout managers suck
  • Swing apps are hard to maintain
  • Swing is too powerful
  • No native features
  • Swing apps have a bad history

To start with, assuming that using Swing from within a scripting language solves any of these problems smacks of dynamically-typed delirium. When I first read the JRuby cannot save Swing post, I assumed that it would mention this minor fact, but instead it simply berated Swing further and proposed that it is “beyond saving”. Somehow, this seems a little bit of an extreme sentiment towards one of Java’s most established frameworks. Let’s look at item number one…

Swing apps are slow to build

That depends greatly on a number of factors, not the least of which is the capabilities of the developer in question. I can build a non-trivial Swing UI in a couple hours. I’m sure Romain Guy could do it in half that. Compare that to some developers who would take hours to build a simple, three element form. It’s all relative.

Some of the blog posts propose that using a dynamic language would help with this problem. Let’s take a look:

public class TestClass {
    public static void main(String... args) {
        JFrame frame = new JFrame("Test Frame");
 
        JLabel label = new JLabel("This is the header");
        label.setFont(label.getFont().deriveFont(label.getFont().getSize2D() + 10));
        frame.add(label, BorderLayout.NORTH);
 
        JPanel buttonPanel = new JPanel();
        frame.add(buttonPanel);
 
        buttonPanel.add(new JButton("Button 1"));
        buttonPanel.add(new JButton("Button 2"));
        buttonPanel.add(new JButton("Button 3"));
 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 200);
        frame.setVisible(true);
    }
}

This took me about 3 minutes to whip together. Obviously this is a toy example, but it does illustrate the point that Swing isn’t that cryptic or bulky. Now, let’s take a look at the corresponding JRuby code:

require 'java'
 
JFrame = javax.swing.JFrame
JLabel = javax.swing.JLabel
JPanel = javax.swing.JPanel
JButton = javax.swing.JButton
 
BorderLayout = java.awt.BorderLayout
 
frame = JFrame.new 'Test Frame'
 
label = JLabel.new 'This is the header'
label.font = label.font.deriveFont(label.font.size_2D + 10)
frame.add(label, BorderLayout::NORTH)
 
button_panel = JPanel.new
frame.add button_panel
 
button_panel.add JButton.new 'Button 1'
button_panel.add JButton.new 'Button 2'
button_panel.add JButton.new 'Button 3'
 
frame.default_close_operation = JFrame::EXIT_ON_CLOSE
frame.setSize(400, 200)
frame.visible = true

Now, this took me just as long to put together as the example in Java. And I had already built the UI! Ruby is 1) a nice dynamic language, and 2) I had already done the work. Shouldn’t this have gone much faster? Also, this doesn’t seem too much clearer to me than the Java example. I mean, it’s all Swing.

One of the posts proposed that a generic (possibly XML based) overlay be created on top of Swing which would simplify development by only using Swing indirectly. Well, people have already done this (it’s called XUL), and it isn’t very popular outside of Mozilla.org But let’s move on…

Swing layout managers suck

Well maybe… It greatly depends on the type of UI you’re trying to create. If you’re trying to create a form-based UI with lots of elements then I will concede the point. The reason being that most forms are laid out in a grid-like fashion. For example, something like this:


It’s very hard to do something like this in Swing because the only two grid-based layout managers are GridLayout and GridBagLayout. GridLayout is extremely limiting, requiring all cells to be exactly the same dimensions, and GridBagLayout is powerful to a fault (as well as having some glaring weaknesses, like no absolute cell sizes).

However, this single shortcoming in the Swing layout manager menagerie (lack of a good form layout) has been rectified in Java 6. More specifically, the problem was fixed with the introduction of GroupLayout, which is the layout manager used by the NetBeans GUI builder (formerly Matisse). Although GroupLayout’s API is somewhat cryptic (not to mention Java 6 only), it’s still a very powerful layout manager, even more than GridBagLayout. There are also a whole host of third-party layout managers available for Swing which excel at form based layouts. JGoodies’s FormLayout is a popular one. I myself have even gone so far as to port a layout manager from SWT, GridLayout (which resembles GridBagLayout in power without the complexity). This brings me to my next point…

Even if there were no solid layout managers available for Swing, it’s still very easy to create your own. In fact, this process is so simple, and so revealing about the way Swing layout managers work, that I would recommend anyone who’s serious about developing with Swing to pursue custom layout managers. I’ve written several layout managers over the years. While I only use one of them on a regular basis, I greatly value the lessons learned from each and every one of them. And honestly, Swing makes the task of layout manager creation significantly easier than many other GUI toolkits (such as SWT).

Swing apps are hard to maintain

Not true. Badly designed code is hard to maintain. Badly designed code is written by bad programmers. Bad programmers are incapable of using Swing properly (and even if they did, the rest of their code would be atrocious). In fact, Swing encourages best-practice coding in a lot of ways (a highly MVC based architecture for one). If anything, Swing-based apps are easier to maintain than those created using other APIs.

Swing is too powerful

This is a problem?

No native features

Well, it depends on what you mean when you say “no native features”. Does every element in a Swing UI correspond with a native peer? No. Are Swing elements indistinguishable from their native counterparts? Eh, depends on the platform and how good your eyes are. On Windows XP, the answer is often yes. On Vista, less often. On Mac the differences are acceptable, but on Linux the GTKLookAndFeel is terrible. Don’t get me wrong, it’s better than it was, but it still needs a lot of work before it’s truly production quality.

The “native features” case in which Swing falls drastically short is in integration with the native platform’s desktop features. For example:

  • Determining and firing native apps for a particular file association
  • Retrieving corresponding icons for a certain file association
  • Determining file associations in the first place
  • Access to any sort of platform-specific feature
  • …and so on

I won’t deny that SWT is miles ahead of Swing in this regard. However, there is some dissention over a) are these really the responsibility of the GUI toolkit? and b) what’s wrong with separate libraries like JDIC? Oh well, we’ll still chalk this up as a point for “the other side” (whoever that may be).

Swing apps have a bad history

This is flat out undeniable. Swing apps have a terrible reputation. I still walk into random IT departments, mention I’m a Java developer and get lectures about how slow, ugly and unreliable Java is; when in fact, these comments are really directed at legacy Swing applications.

Swing is a hard API to use properly. This is true mainly because it is an API worth using. This difficulty that programmers have with Swing is amplified by the fact that back in the day, many GUIs were designed visually with the aid of tools like Delphi or Visual Basic’s form editor. Obviously, these tools make it a lot easier to get a “cheap and dirty” UI out the door quickly, but the result really isn’t a GUI worth maintaining. Also, it led to a lot of bad programmers thinking that they were good programmers because they were able to create mediocre prototypes. Refer to “Swing apps are hard to maintain” for more on this point.

Also, until recently, the look and feels available for use with Swing were either highly esoteric and non-native or flat out ugly (or both). Without a solid look and feel to render the components well, Swing looks terrible. However, as of Java 5 Swing got a vastly improved Luna (Windows XP) look and feel. Java 6 introduced a half-way-there GTKLookAndFeel on linux, as well as sub-pixel rendering. Swing fonts have been the focal point of a lot of criticisms primarily because they (until recently) lacked sub-pixel rendering. (sub-pixel rendering allows fonts to look “smoother” on most screens) I think that you could make an argument that Swing on Windows XP looks just as good as any native application.

To Conclude…

Swing is in no need of a rescue from more “hip” languages like Ruby or Groovy. Nor is Swing languishing in the pit of unattractiveness. Rather, Swing is alive and well, and getting stronger by the day. Swing doesn’t need saving, what Swing needs is to be given another chance by the world.