Changing the mouse cursor in Swing for the entire application

It is quite easy to change the mouse cursor in a Java Swing application, but most documentation and examples available only demonstrate how to change the cursor for a specific component. However, in an application I am developing – which has a fairly complex component hierarchy – I needed to ensure that the cursor would remain the one I set no matter where the mouse were (the most common example is the “busy / waiting” cursor, although that was not my case).

To change the cursor in a application wide fashion, you have to access the Glass Pane and set its cursor, and then make the glass pane visible – otherwise, it has no effect at all.

Take the following code as example:

int cursorType = Cursor.S_RESIZE_CURSOR;
Component glassPane = ((RootPaneContainer)someComponent.getTopLevelAncestor()).getGlassPane();
glassPane.setCursor(Cursor.getPredefinedCursor(cursorType));
glassPane.setVisible(cursorType != Cursor.DEFAULT_CURSOR);

In the previous code, “someComponent” is any JComponent you have, it doesn’t matter which one (can be a JLabel, JButton, JPanel.. just take one). The trick is to access the RootPaneContainer, and then get the glass pane from it.

The last part is to make the glass pane visible only when the cursor is not the default one. That’s all.

The status of Swing in 2011

I always have been a Web developer in my career – well, most of the time, as since the iPad was released I have been doing some heavy development on iOS, specially in the field of digital readers. Nevertheless, is the Web platform that I am most familiar with. Being a solution centric professional, it was not surprise that last month I was requested to develop a new tool that could run on Mac and Windows desktops, in order to allow newspaper and magazine publishers to create rich content issues for mobile devices and possible web readers.

The company I work for was a long time user of Microsoft solutions (only because that when they started over 11 years ago, it was easier to find Action Script developers that could do some ASP coding, thus the migration to the .NET platform was some kind of natural for them), but for the past couple of years the transition to Rails and now Java is taking place over .NET (which is something to be discussed another time), and using Java for the new tool seemed the best way to go through, as Java is a very mature platform, with plenty of developers and documentation available, and not to have to maintain totally different base codes of Mac and Windows was a very good argument.

However, I didn’t have so many good opinions about Swing (the Java GUI Toolkit), even though it is the standard approach to do desktop programming with Java. Sure that there are other toolkits out there, like SWT and QT, but I had to consider that other people would be working on the software later, doing bug fixing and general improvements, thus if it required extra training it could be a problem.

All my experience with Swing was limited to some small programs or books I read, but it was enough to let me know that:
- I’d need to deal with layout managers
- That layout managers can get quite complex or verbose very easily (or both)
- That Swing didn’t have any major upgrade for years (if any)
- I had a clue that there weren’t so many third party components
- And definitely that I wasn’t willing to do hand coding of the GUIs. A GUI designer was vital.

I have mixed feelings about layout managers. I understand why they were created, but you had to know them all in order to make a fairly complex program, as each one of them accomplish a very specific task. Also, any documentation (including books) date back to 2004 or 2005 at most, which leads one to think that it was abandoned, but this feeling goes away after some time, as Swing has almost all (if not all) major components one may need to create any program, and it is possible to create your own components if needed. Swing is mature as well, and the fact it does not get a major upgrade in years may only means that there isn’t that many stuff to have.

Ok, I may being a little too optimistic here, as certainly the API could be improved a lot and more components could be available by default, but Sun was never good at designing easy to use APIs, far from that, and the failed Java FX thing only proves that the guys over there had no clue at all of what to do.

When searching for documentation, you often will find articles dated back to ’98, ’02. This frequently helps to keep alive that feeling that you are dealing with a dinosaur and using something that will die soon – even it will not (I hope). Sure that any example code that it’s not for Java 1.1 is very welcome when you know nothing.

The complexity of doing even simple things is something you will face constantly. The Java API was never known for its friendliness – it appears that very different teams at Sun, that did not talk to each other, were developing the base class library, thus creating a lot of inconsistency across the API -, but Swing goes a step further to make your life harder. Maybe it’s because I am more confortable with web programming, but I have done a lot of WinForms and Silverlight (.NET) coding, and by far Swing is harder. Take for example Drag and Drop over a JList or (worst) a JTree: it is insanely hard to make it work, even after reading hundreds of source code lines from open source projects and discussion forums. The event dispatching system is another thing that the more I read the less I understand, and many times I found myself doing some sort of implementation of the observer pattern instead of sticking with Swing’s own classes (I ended with a somewhat simple but very effective ‘EventCentral’ class).

As for third party components, there are some, but not many, not to mention those that does not work very well. Conversely, the WinForms API of .NET (here I go again, sorry) still get plenty of stuff today, although not as many as it did once, and you can’t stop thinking about it occasionally.

In conclusion, at the end of the day Swing it’s the only choice you have if you are going to use Java for desktop development, and albeit it has a lot of bugs and a weak, non-active community, it gets the job done. I have looked at SWT and JavaFX, but the former it still even more restricted, and the latter’s first release was a fiasco, but apparently Oracle is trying to respawn it with a 2.0 version.

Omit unexpected XML Elements with XStream

XStream is a great library to create XML from objects and vice-versa, and one of the many areas I use it is to store configurations. One problem is that XStream has the hability to ignore fields when serializing objects, but not the opposite – e.g., if it finds a tag that does not have a corresponding property in your class, it will throw an exception.

It is not clear to me why they still don’t have anything to handle such situation, which is fairly common to happen. For example, you may have a XML and only needs a small fraction of its data, or maybe you changed the way you store configurations and removed some properties. In both cases you will have to map the entire object graph, even if you don’t want it. Their FAQ page states this:

If a field is removed from the class, deserializing an old version that contains the field will cause an exception. Leaving the field in place but declaring it as transient will avoid the exception, but XStream will not try to deserialize it.

I find this behavior pretty odd and annoying, but luckily there is a workaround: the XStream class has a protected method named wrapMapper(MapperWrapper next) that subclasses may implement in order to tell the library if a given class or property should be considered. In this method you can add verifications for the fields or classes that you don’t want to bother, and return false for them.

Check out a working example:

XStream x = new XStream() {
	@Override
	protected MapperWrapper wrapMapper(MapperWrapper next) {
		return new MapperWrapper(next) {
			@Override
			@SuppressWarnings("rawtypes")
			public boolean shouldSerializeMember(Class definedIn, String fieldName) {
				if (fieldName.equals("shouldCopyWithProject")) {
					return false;
				}

				return super.shouldSerializeMember(definedIn, fieldName);
			}
		};
	}
};

In the previous example, I had a field named “shouldCopyWithProject” that was removed in newer versions of my application, but such refactoring resulted in crashes when opening the files from older versions of the app, so I had to handle the situation manually.

It would be great if XStream had a cleaner solution for this, but I think it is very unlikely to happen. Nevertheless, the approach here described works very well.

Update

As Chris have pointed out in the comments, it is much easier to just use the omitField(class, fieldName) method, as in

// .....
XStream x = new XStream();
x.omitField(A.class, "shouldCopyWithProject");
// .....

I came across this method several times, but for some reason I thought it only worked for serialization. Anyway, thanks to Chris for simplifying our lives :)

Character encoding issues with Jetty 8

After deploying a webapp to the production server, all pages showed character encoding problems (aka, an accented letter would display “strange” data instead). In my development box it worked like a charm, but I couldn’t get it to work in the live server. I had all files saved as UTF-8, as well calls to  ”<%@ page contentType=”text/html;charset=UTF-8″ pageEncoding=”UTF-8″ %>” in JSP files, “<page-encoding>UTF-8</page-encoding>” in WEB.xml etc…, but nevertheless, it simply didn’t work. I even used an encoding filter as suggested by a friend, without any luck.

What actually solved the problem (if I can call it that way) was a Jetty downgrade from version 8 to version 7. Simple as that. I don’t know what changed in version 8, and maybe it is just a matter of changing a setting somewhere, but until I find which one, sticking with Jetty 7 works great.