Home > aen's Blog

Hocus Focus

smee, build 7

Managing keyboard focus aboard the starship Java can be a hairy adventure to the uninformed, even with a relatively simple UI. Today I discovered I really need to get more familiar with focus management in Swing!

I focused mainly on keyboard support today, mostly centered around a small new feature: tile-based scrolling. CTRL+T will toggle the tile scroll on and off. I also added a menu item for it in the View menu.

When scrolling in tile mode, the upper left of the viewport should always be aligned on a tile. Except when in the lower right hand corner, where it is allowed to be offset in the interest of allowing you to view full tiles when the viewport isn't exactly divisible by the tile size.

You'll also note that if you scroll around normally and then toggle on tile scrolling, the viewport will snap to tile boundaries.

The arrow keys will scroll in tile increments, and holding down CTRL while pressing an arrow key will page in the given direction. This seems a little more intuitive to me than Page Up, Page Down, Home, and End.

I also made the New Map dialog accept the ENTER key. Almost everything can be done purely through the keyboard now!

There are still some issues with scrolling all the way to the lower right in tile scroll mode, but they'll have to wait for another day.

I was building up quite a lot of key binding code in the Main class, so I refactored it out into it's own KeyBindings class. This was done primarly for clarity's sake.

You'll find a few todo's here and there if you browse through build 7. One particular annoyance I encountered was that the zoom slider and the scroll pane for the tile selector kept stealing my focus and overriding all my key bindings! To get around this, I added a focus listener to each that shifted focus back to the viewport when either received focus.

I was initially attaching all my key bindings to the viewport's InputMap and ActionMap, but some of my bindngs weren't triggering. After thinking about it a little, I realized I actually wanted to attach all of my bindings to panel encompassing the viewport and all the other components, so I could take proper advantage of the JComponent.WHEN_IN_FOCUSED_WINDOW flavor of input map.

Due to popular request, tomorrow I'll be upgrading the undo functionality to support composite actions. That is to say, all tiles plotted from mouse press to mouse release will be treated as discrete undoable actions.

Today's carpal tunnel will be tomorrow's fond memory!