GWT Notes: TabLayoutPanel

I’ve been putting in some time over the past week building UI’s with GoogleWebToolkit and the new UIBinder.

It is all very spiffy and so much easier to use than 1.7 was. Last summer I tried to put together some moderately complex UI’s and found that doing everything in Java to be slow and tedious.

I will cautiously say that I am getting the hang of UIBinder, and that is far and away my current favorite feature from the new 2.0.0 release.

That said, there are a few minor snags.

The new LayoutPanels are for fast, browser-rendered widgets, done in standards mode. I prefer them to the old Panels they replace because they don’t use tables, instead the layout is all clean css and <div>s.

But when I started working with the TabLayoutPanel, I ran into some problems which I’ve listed below.

The TabLayoutPanel doesn’t display at all, or you get a weird collapsed layout (if you’ve added css). Remember, you  must use standards mode <!DOCTYPE html> for LayoutPanels, and you have to use RootLayoutPanel.get() instead of the old RootPanel.get().

There aren’t any default css styles. If all you see are the tabs titles with no styling… check the apidoc to see the css styles you need to add. This isn’t actually a bug, but without default css the class is pretty much worthless. (There is an issue for this.)
The tabs display, but the tab widgets (content area) don’t. You need to set the  height of the .gwt-TabLayoutPanel.
It doesn’ work in IE (what does?).  There’s a bug with TabLayoutPanel and IE, and a simple css workaround:
.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab { float: left; }

Update: See my next post, More on TabLayoutPanel for some sample css and demos.

Update 2: GWT version 2.0.1 address the problems with IE and provides a default CSS style. You still have to remember to use RootLayoutPanel, and standards mode doctype, when using a LayoutPanel.

ConcurrentModificationError Mystery

So, today I got bit by the ConcurrentModificationError. I had some code which had a bit of a bad smell but was working fine. The class is a batch process, that processes a request. Based on the request, a particular subset of accounts are processed. The method below gets the target accounts based on the request, and additionally filters out corporate accounts. And the ConcurrentModificationError happens on line 9:

	/**
	 * Get accounts to process based on BatchRequest, filtering out corporate accounts.
	 * @param request
	 */
	public void getAccounts (BatchRequest request) {

		List<Account> accounts = AccountManager.getAccounts(request);

		for (Account oneAccount : accounts) {
			if (isCorporateAccount(oneAccounts)) {
				accounts.remove(oneAccount);
			}
		}

	}

The List which the AccountManager is passing back has a fail-fast iterator, which detects that it is being modified in line 11, and thus failing. The mystery is–this has been working in production for months. Today, on UAT we tested a second batch job with very similar data (for all intents and purposes it is completely the same request, just a different group of accounts) and on the second pass only, the ConcurrentModificationError gets thrown. The first pass through it is fine.

Color me confused. It should work both times, or fail both times. And yes, the data is basically the same–I triple checked that today. But it works the first time, and fails the second.

Rather than spend more time wondering why it works once and fails the second time, I figure I should just eliminate the possibility of the ConcurrentModificationException entirely.  I had to make changes to the AccountManager module, which I hadn’t had the chance to change before. But it is definitely a cleaner solution. By adding a signature to the AccountManager.getAccounts(BatchRequest request, boolean includeCorporateAccounts) I was able to simplify the code to something like this:


	private static final boolean EXCLUDE_CORPORATE_ACCTS_FLAG = false;

	/**
	 * Get accounts to process based on BatchRequest, filtering out corporate accounts.
	 * @param request
	 */
	public void getAccounts (BatchRequest request) {

		return AccountManager.getAccounts(request, EXCLUDE_CORPORATE_ACCTS_FLAG);

	}

JADclipse and Eclipse 3.5

JADclipse and Eclipse 3.5
Yesterday was the second time in as many months where I was really, really glad I had a decompiler handy. When you need a decompiler, it turns out, you really need one.
Despite the fact that it was written in 2001, Pavel Kouznetsov’s JAD decompiler is fast and works more than well enough. There’s an Eclipse plugin for it, JADclipse, which takes the JAD output and sticks it into the Class File Viewer.
Both of these projects are no longer maintained, as far as I can tell. The JAD website is gone, and the plugin update site for JADclipse doesn’t work anymore.
However, with a bit of searching, I came across this archive of JAD executables, and
Mike Schrag has graciously hosted update sites for JADclipse. JADclipse itself was created for Eclipse 3.3, but the plugin works with Eclipse 3.4 and I can confirm it works with Eclipse 3.5. Use Mike’s 3.4 update site and you’ll be just fine.

Yesterday was the second time in as many months where I was really, really glad I had a decompiler handy. When you need a decompiler, it turns out, you really need one.

Despite the fact that it was written in 2001, Pavel Kouznetsov’s JAD decompiler is fast and works more than well enough. There’s an Eclipse plugin for it, JADclipse, which takes the JAD output and sticks it into the Class File Viewer.

Both of these projects are no longer maintained, as far as I can tell. The JAD website is gone, and the plugin update site for JADclipse doesn’t work anymore.

However, with a bit of searching, I came across this archive of JAD executables, and Mike Schrag has graciously hosted update sites for JADclipse. JADclipse itself was created for Eclipse 3.3, but the plugin works with Eclipse 3.4 and I can confirm it works with Eclipse 3.5. Use Mike’s 3.4 update site and you’ll be just fine.

Update September 2010: Mike has symlinked in folders for Eclipse 3.5 and 3.6, but they are exactly the same as the 3.3 release of jadclipse.

P.S. — if you are having trouble with the install, be sure to Eclipse -clean as it suggests on the sourceforge JADclipse page.

good to be a Java programmer

It’s an exciting time to be a Java programmer.

That’s a big change of opinion for me. I started my career with interpreted languages (Usertalk, Python, Perl) and Java seemed really verbose and unproductive.  And it’s still verbose.

But a great set of tools make me really productive.The tool infrastructure  has come such a long way. Eclipse is a great IDE, and if you don’t like it IntelliJ and Netbeans are as good or better. And the ecosystem around the IDEs is incredible. I’m an Eclipse user, and I’ve talked in the past about Mylyn and how much better that makes me. The intellisense features make the huge Java APIs manageable, and the refactoring tools give me enough freedom to make significant code changes without worrying about copy/paste mistakes.

The tool chain for build, dependency management, testing, and continuous integration has improved. Ant is a great workhorse tool. Hudson pretty much the best CI tool ever, and I’ve even come around (slowly) on Maven. Maven, when it works, works really well. It is hard to imagine working on the project I am working on now without a tool like maven to help manage every aspect of the build.

Part of productivity is code reuse. There is a ton of great code (Apache commons, anyone) that has been battle-tested and debugged and often even documented available. Sourceforge and Google code and Codehaus and java.net all provide tons of libraries and tools.

Some of the best parts about Java is that coders have reacted violently against the unwieldly, badly designed APIs that where thrust upon us in the early days. Most coders knew enough to stay away from EJB, unless they were being paid the big bucks to inflict Big E enterprise on the masochistic companies that insisted on it. But a few coders also figured out alternatives: Spring and Hibernate being just two examples.  The fact that the community has been able to leave behind some of the mistakes and move forward–and that the driving force of that is open source driven, speaks well to the health of Java now and in the future.

It’s weird how the plumbing has become sexy. By far the most exciting development of the past two years is the growth of other languages on the JVM. And that is because the JVM and Hotspot JIT compiler is so good. And it means that I can build on my investment in learning Java, the Java tools, and my IDE. Learning a new language, and I get to keep my productivity gains in the toolchain and environment.

So now it’s time for my list of  reasons to be excited about Java right now. It’s been a busy time for Java geeks, with JavaOne last week, and Google I/O the week before, and Eclipsecon roughly a month ago.

  • Android — I can write mobile apps in a language I already know. whooo! It’s not as sexy as the iPhone, nor is it as crowded a place for a developer. And the mobile market is huge. I don’t mind being in a smaller portion of such a vast market.
  • New languages blooming on the JVM. JRuby is fantastic, and fast. I am learning Groovy now, which I expect to take my productivity up several notches. JPython and Scala are in view too.
  • New focus on graphics and desktop. JavaFX has a lot of challenges, and I’m not quite willing to invest yet, but I am watching closely. There are some really reasonable ways to do UI in Java or Groovy now.  And don’t forget Processing, and it’s focus on practicality, ease of use, and real world data crunching and visualization apps.
  • Google on Java. Wow, the presentations from Google I/O were a real eye opener. AppEngine will let me deploy a java web app with the push of a button. You can’t get easier or more efficient than that. Guice looks like DI I can believe in. And some of the lower profile stuff, like http://code.google.com/p/google-collections/, could wind up having a huge effect on my day to day coding.

Okay, if you’re still with me, thanks for reading. Bottom line, it’s a good time to know Java. The tools have matured, there is a lot of opportunity, and who knows? maybe even the Oracle acquisition of Sun will work out good as well.