IDE Feature Matrix
This is how I feel about Java IDEs.

This code darkens the entire screen, allowing you to create lightbox effects when showing dialogs. For example, here is the normal screen:
And here is how the screen looks with a glass pane and dialog:
There are GWT component libraries that do this sort of thing, for example GlassPanel, but I prefer to minimize external dependencies. Instead, I decided to try this code example by Evaldas Taroza.
I made a few changes to the original code:
ResizeHandler instead of WindowResizeListener, which is deprecated.First, here is the CSS file:
.gcomp-GlassPanel {
background-color: black;
filter: alpha(opacity=50);
opacity: .50;
}
Next, here is the JavaDoc comment, listed separately because syntax highlighting wasn’t working here on my blog.
/**
* This panel is positioned absolutely and covers the whole client
* area of the browser. It can be used to disable everything
* underneath it with appropriate z-index.
* <p/>
* For instance a dialog can attach it to the root panel during
* opening, and remove it during closing.
* <p/>
* CSS:<br>
* .gcomp-GlassPanel
* <p/>
* Example:<br>
* Add and remove this widget whenever you want, and style it as
* follows:
* <pre>
* .gcomp-GlassPanel{
* background-color: black;
* filter:alpha(opacity=50);
* opacity:.50;
* }
* </pre>
*/
And here is the code…
public class GlassPanel extends Composite implements ResizeHandler {
public static final String STYLE = "gcomp-GlassPanel";
private SimplePanel panel = new SimplePanel();
public GlassPanel() {
initWidget(panel);
panel.setStylePrimaryName(STYLE);
Window.addResizeHandler(this);
resize();
}
public void onResize(ResizeEvent event) {
resize();
}
public void show() {
// Override the styles explicitly, because it's needed
// every time the widget is detached
Element elem = panel.getElement();
DOM.setStyleAttribute(elem, "left", "0");
DOM.setStyleAttribute(elem, "top", "0");
DOM.setStyleAttribute(elem, "position", "absolute");
RootPanel.get().add(this);
}
public void hide() {
RootPanel.get().remove(this);
}
private void resize() {
panel.setSize(Window.getClientWidth() + "px",
Window.getClientHeight() + "px");
}
}
I’ve only done minimal testing, on the latest Firefox and IE7.
Adam Bien presents the Generic DTO convention, where your DTOs wrap around Java Map instances.
If you are considering a generic DTO approach, you might want to investigate Protocol Buffers. Though you will have to create and maintain .proto files, you’ll gain language independence and (presumably) performance.
This article shows how to configure Guice with server side code in Google Web Toolkit (GWT) applications1. I use Guice 2.0 with GWT 1.7.0.
Steps include:
RemoteServiceServletGuiceServletContextListenerServletModuleRemoteService relative paths to GWT.rpcGuiceFilter and your context listener in web.xmlRemoteServiceServletPhew! That seems like a long list, but I want to ensure I list every step. This approach is based on the excellent GuiceRemoteServiceServlet by Pavel Jbanov. His initial work pointed me in the right direction, making this much easier.
Grab guice-2.0.zip from the Guice downloads page. This ZIP contains all of the required JARs. You may also want guice-2.0-src.zip.
To use Guice with GWT, you’ll need two JARs: guice.jar and guice-servlet.jar. Just drop these into your war/WEB-INF/lib directory.
RemoteServiceServletThis code comes almost verbatim from Pevel Jbanov’s blog, with the modifications mentioned in the first comment on that page. Here is the source:
@Singleton
public class GuiceRemoteServiceServlet extends RemoteServiceServlet {
@Inject
private Injector injector;
@Override
public String processCall(String payload) throws SerializationException {
try {
RPCRequest req = RPC.decodeRequest(payload, null, this);
RemoteService service = getServiceInstance(
req.getMethod().getDeclaringClass());
return RPC.invokeAndEncodeResponse(service, req.getMethod(),
req.getParameters(), req.getSerializationPolicy());
} catch (IncompatibleRemoteServiceException ex) {
log("IncompatibleRemoteServiceException in the processCall(String) method.",
ex);
return RPC.encodeResponseForFailure(null, ex);
}
}
@SuppressWarnings({"unchecked"})
private RemoteService getServiceInstance(Class serviceClass) {
return (RemoteService) injector.getInstance(serviceClass);
}
}
All GWT RPC requests will go through this single servlet. Thus, your remote service implementation classes will not have to extend RemoteServiceServlet.
GuiceFilter will inject the InjectorGuiceServletContextListenerThis step creates a Guice-friendly servlet context listener.
public class MyGuiceContextListener extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(
new MyServletModule(),
new AnotherOneOfMyModules(), etc...);
}
}
You can hook up as many Guice modules as you want. The first, MyServletModule, replaces much of what traditionally goes in web.xml.
ServletModuleIn order to use constructor injection with servlets, Guice must construct your servlet instances. Thus, you no longer list each servlet in web.xml. Here is a simple module:
public class MyServletModule extends ServletModule {
@Override
protected void configureServlets() {
serve("/MyApp/GWT.rpc").with(GuiceRemoteServiceServlet.class);
// cannot use @ImplementedBy
bind(MyService.class).to(MyServiceImpl.class);
}
}
Go check out the Guice ServletModule documentation for a full explanation.
You cannot use @ImplementedBy on the MyService interface. That’s because MyService is in GWT client code, and the MyServiceImpl is in GWT server code. Instead, the binding is configured in MyServletModule as shown.
Remember — this replaces most of what you typically place in web.xml.
RemoteService relative paths to GWT.rpcAll of your GWT remote services will dispatch to the GuiceRemoteServiceServlet shown earlier.
@RemoteServiceRelativePath("GWT.rpc")
public interface MyService extends RemoteService {
...
}
In old-style GWT, you list your remote service implementations in the GWT module XML file (MyApp.gwt.xml). If you have any servlets listed there, you can remove them. Your GWT module should look something like this:
<module rename-to='MyApp'> <inherits name='com.google.gwt.user.User'/> etc... <entry-point class='com.abc.whatever.client.MyEntryPoint'/> </module>
Your web.xml should list the Guice filter and your custom Guice context listener.
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.yourcompany.server.MyGuiceContextListener</listener-class>
</listener>
<!-- NOTE: List all Servlets in MyServletModule for Guice injection -->
<welcome-file-list>
<welcome-file>Css.html</welcome-file>
</welcome-file-list>
</web-app>
Your GWT remote service implementations do not have to extend RemoteServiceServlet any more.
Old code:
public class MyServiceImpl
extends RemoteServiceServlet implements MyService {
...
}
New code:
public class MyServiceImpl implements MyService {
private final AnInterface anInterface;
// Guice injection here!
@Inject
public MyServiceImpl(AnInterface anInterface) {
this.anInterface = anInterface;
}
...
}
Once all of the above pieces are in place, you can use normal Guice dependency injection in all of your GWT remote service implementation classes. This includes both constructor and setter injection.
Please let me know if you find any mistakes, and I’ll be sure to update this article.
1 To use Guice with GWT client code, check out the GIN project. (I have not tried GIN)
Changed: RPCRequest req = RPC.decodeRequest(payload);
To this: RPCRequest req = RPC.decodeRequest(payload, null, this);
I ran in to this problem again today, only I forgot that I had blogged about it in the past, so I had to research and find the solution a second time.
In summary, if JConsole or Java VisualVM aren’t able to connect to local processes, your %TMP%\hsperfdata_[username] directory needs to match the capitalization of your Windows username. In my case, I renamed hsperfdata_eburke to hsperfdata_EBurke, solving the problem.
Here is a little Java program that creates a JComboBox with three identical “Green” items:
public class ComboDemo extends JFrame {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ComboDemo().setVisible(true);
}
});
}
public ComboDemo() {
super("Duplicates are Dumb");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComboBox combo = new JComboBox(new String[] {
"Red", "Green", "Blue", "Green", "Yellow", "Green"
});
add(new JLabel("Choose your favorite color:"), BorderLayout.NORTH);
add(combo, BorderLayout.SOUTH);
pack();
}
}
As you can see, the user really has no way to know which “Green” is the correct selection:

Some people want to display multiple identical items in combo boxes. I’ve had customers ask me for this feature — and I refused. If memory serves correctly, they were having keyboard navigation problems because focus would get stuck on the first of the duplicate items. Their database contained duplicate descriptions, and they wanted me to fix the alleged focus “bug” in the combo box rather than eliminate the duplicate descriptions in the database. (eventually, reason prevailed and we made the descriptions unique).
This has even been reported as a bug, and the ensuing comments are interesting to read. For example:
Good God sun!!! Just because you dont’ see why people would use the same string more than once in a JComboBox, it doesn’t mean that it isn’t need people like us!! Fix it please!!!
Yikes…imagine a GUI with these choices:
a) Yes
b) Yes
c) No
Um…
Apple’s Swing implementation has an interesting approach. When you click on one of the identical items, they are all selected:

This seems like a reasonable way for JComboBox to behave when given unreasonable data.
I’m starting a new GWT project at work, so I wanted to select the best IDE for the job. I installed the very latest versions of these IDEs along with their respective GWT plugins:
I’ll warn you right now that this is not an in-depth review or comparison. I looked just deep enough to satisfy my own curiosity and to choose a tool for my own coding.
Eclipse has an advantage in that Google supplies the Google Plugin for Eclipse, ensuring the plugin generates the exact same directory layout as the GWT command line tools. After installing Eclipse and the plugin, I generated a sample GWT project and it ran perfectly in hosted mode.
This is where things went badly, however. As you may know, GWT services consist of two interfaces and a class:
For my first (and only) trick, I performed a Rename refactoring on MyService. Eclipse renamed that interface, but not the other interface or implementation class. Instead, Eclipse immediately lit up with errors, forcing me to manually rename the Async interface and Impl class. Epic fail.
NetBeans also supports GWT through the gwt4nb plugin. I generated a project and noted it creates a slightly different directory layout, but nothing that would introduce problems.
Like Eclipse, NetBeans failed the Rename refactoring test. Unlike Eclipse, however, NetBeans did not immediately indicate errors in the mismatched class and interface names. Thus, errors would only manifest later at runtime. I gave up very quickly.
Unlike the other two IDEs, IDEA’s plugin does not yet support the new directory layout introduced in GWT 1.6. I initially assumed this would be a big problem, since you also see deprecation warnings when you launch your app in hosted mode.
In reality, however, the directory layout differences only manifest themselves in the output directories. The source directories are the same, so a simple Ant buildfile can produce a more standard GWT 1.7 WAR-style layout.
Of the three IDEs, IDEA is the only one to properly implement the Rename refactoring. When you rename your Service interface, the other interface and class both rename in unison.
Also, IDEA does a kick-ass job of keeping CSS styles in sync with styles referenced in GWT code. As I discovered today, when I define a style name in Java code, IDEA shows it in red and can automatically insert a new style class into my CSS file. I also refactored a <div> identifier in my HTML file, and IDEA correctly refactored the String reference in the Java source code!
I’ve used IDEA for years, and was initially put off by the fact that IDEA 8.1 does not yet fully support the new GWT 1.6 and 1.7 directory layout. In practice, this is a non-issue, and IDEA 9 will support the latest GWT conventions. IDEA’s first rate refactoring, along with tight integration with CSS classes and HTML identifiers really set it apart from the other IDEs.
Java SE 6 Update 14 (gotta love those names) is now available. According to the release notes, a new “Garbage First (G1) Garbage Collector” is enabled. To use it:
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC
Do so with caution, however. As @kimchy noted on Twitter, the release notes include this statement:
Although G1 is available for use in this release, note that production use of G1 is only permitted where a Java support contract has been purchased.
What do you think?
Today I learned something new about Leopard. On the command line, my default JDK was 1.5. I was about to edit a symlink under /System/Library/Frameworks/JavaVM.framework/Versions to change to 1.6, but instead learned about the Java Preferences app.
In Spotlight, find “Java Preferences” and launch it. Or, find it directly under Applications/Utilities/Java. It looks like this:

Just drag and drop to rearrange items in the lists. The JDK at the top of the list becomes your default.
While this worked, Ant still used the old Java 1.5. I fixed this by adding a line to ~/.bash_profile:
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home