Bullet Proof User Interfaces slides
June 29, 2009
As I mentioned back here, my collegue, Jared MacDonald, also spoke at JavaOne 2009. Besides being an entertaining speaker, he delivered a great message about applying Test Driven Development (TDD) to user interface development. TDD is oft regarded as too difficult to apply in the UI space. Jared did a great job demonstrating why that’s simply not the case.
| Bullet Proof User Interface slides (PDF) |
Until next JavaOne!
If you’ve ever extended BasicTableUI, you may have struggled a bit with it’s inability to hook into the cell rendering process. JTable has the prepareRenderer method through which you can inject yourself into the cell painting pipeline. BasicTableUI, however, has no such mechanism.
Why would we even need this capability from a BasicTableUI? In ITunesTableUI, for example, I install a special border on the containing JScrollPane, which paints the row striping (the subject of a future blog entry). In order for the striping to show through, each renderer must be non-opaque (transparent). By default, renderers are opaque, which results in a table that looks like this:
![]()
We have a couple of options to work around this. First, we could simply grab each of the default renderers and make it non-opaque. This isn’t a great solution, though, because there’s no easy way to get a list of all these renderers — we’d end up harding coding a set into our UI delegate. And if downstream consumers added their own renderers, they’d be responsible for making sure they were non-opaque.
The second (and better) option, is to create a custom CellRendererPane that essentially gives us a prepareRenderer method. CellRendererPane is the class used to stamp out each table cell onto the screen. The renderer for the cell is prepared, and then added to the CellRendererPane, which manually invokes paintComponent. Overriding paintComponent gives us the hook into the cell painting process that we’re looking for. Here’s what the custom CellRendererPane looks like:
/**
* Creates a custom {@link CellRendererPane} that sets the renderer component to
* be non-opaque if the associated row isn't selected. This custom
* {@code CellRendererPane} is needed because a table UI delegate has no prepare
* renderer like {@link JTable} has.
*/
private CellRendererPane createCustomCellRendererPane() {
return new CellRendererPane() {
@Override
public void paintComponent(Graphics graphics, Component component,
Container container, int x, int y, int w, int h,
boolean shouldValidate) {
// figure out what row we're rendering a cell for.
int rowAtPoint = table.rowAtPoint(new Point(x, y));
boolean isSelected = table.isRowSelected(rowAtPoint);
// if the component to render is a JComponent, add our tweaks.
if (component instanceof JComponent) {
JComponent jcomponent = (JComponent) component;
jcomponent.setOpaque(isSelected);
}
super.paintComponent(graphics, component, container, x, y, w, h,
shouldValidate);
}
};
}
Here’s how we create and install this custom CellRendererPane in our extension of BasicTableUI:
CustomTableUI extends BasicTableUI {
// ...
@Override
public void installUI(JComponent c) {
super.installUI(c);
table.remove(rendererPane);
rendererPane = createCustomCellRendererPane();
table.add(rendererPane);
// ...
}
}
and that lets us make all our non-selected cells non-opaque!
JWebPane screen shots
June 16, 2009
Alexey Ushakov has just posted screen shots of the JWebPane Java web browser that he showed in his BOF at JavaOne 2009 (which I talked about here). Below is a screen shot I pulled from Alexey’s latest blog post:
![]()
Seems like we’re getting closer!
Why can’t Safari get tabs right?
June 9, 2009
I thought Safari 4 beta was headed in the right direction with it’s tab location. The Safari design team had moved the tabs to the the top of the window and thus made them up-right like this:
![]()
Now I realize there was a bit of a usability problem, as the tabs were now doubling as the mechanism to move the window, but I liked the direction the UI was moving in. I greatly disliked the upside down tabs of Safari 3, because they make no visual sense — the tabs are completely disconnected from the content they are tabbing.
As you can imagine, I was dismayed when I installed the final version of Safari 4 only to see the tabs revert to their version 3 visuals:
![]()
I’m not sure why the Safari visual design team chose this broken tab metaphor to begin with as it’s never made any sense, and it’s clear that they realize this. So why keep around this broken metaphor and make us suffer for another full version?
This is not a hard visual design problem to solve. Google Chrome has a great solution that meets the visual demands of the Mac platform:
![]()
Come on Apple — lets get this fixed.
Simply Sweet Components slides
June 7, 2009
Here are the slides for my JavaOne 2009 presentation, Simply Sweet Components, TS-4559 (read the abstract). Enjoy!
| Keynote version (the format I authored the presentation in) | |
| QuickTime version (with full animations) | |
| PDF version (with notes, but no animations) |
To get the most out of the presentation, I’d recommend clicking through the QuickTime version (the one with the animations), with the PDF version up on the side (which has the notes).
JWebPane update
June 5, 2009
I was one of the few attendees of the late-night JWebPane BOF (BOF-3992). Artem Ananiev and Alexey Ushakov gave a fantastic demo of a Java web browser based on the JWebPane component (I’m trying to get ahold of a screen shot of this). I did learn that WebKit doesn’t actually provide a rendering engine, but instead provides hooks such that you can be told when and what to paint. This works out well, because JWebPane’s content can be completely painted using Java 2D and Swing.
The team was of course asked when JWebPane would be released (this was my only motivation for attending!). As expected, no date was provided, but they did suggest that it may be available by the end of the year (2009). They also said that an actual date would be put forth within the next couple of months.
One interesting tidbit of information that slipped out was that JWebPane’s release date is being aligned with JavaFX. It’s not clear to exactly why this connection to JavaFX exists, but I’m sure we’ll find out soon.
** Update: screen shots available here. **
JavaFX 1.2 brings more UI controls
June 2, 2009
JavaFX 1.2 arrived silently last night in order to coincide with the opening of JavaOne 2009. I’m happy to see many more UI controls included in this latest release of JavaFX, most notably ScrollBar, which is so painful to re-implement yourself.
Here’s a look at some of the new controls based on a Sun web-start app I found here (run it):
Here’s the full list of new UI controls:
- Button
- Label
- CheckBox
- ToggleButton
- RadioButton
- Hyperlink
- ProgressBar
- ProgressIndicator
- Slider
- ScrollBar
- ListView
- TextBox
I wasn’t expecting the controls to have a platform neutral look, though I think this was a good idea (similar to how Adobe Flex controls have an platform agnostic look).
Check out the full JavaFX 1.2 API — note how much fuller it is than in JavaFX 1.1.
I’m interested in hearing you’re thoughts on JavaFX 1.2, specifically about the new UI controls.
IntelliJ raffle winners
June 2, 2009
And the winners of the IntelliJ raffle are…
Congratulations to the winners! If you didn’t win, and are still interested in trying out IntelliJ, I encourage you to download their 30 day trial. |