Thursday, February 18, 2010

JTextArea vs. Tab focus cycle

When inside a JTextArea, the Tab key inserts a tab character instead of going to the next field. The reason is obvious - but in several situations it is not desirable, in particular when it would not make sense to insert tab characters, for example in a text area meant for editing keywords.

Lets just spill the solution right away:
JTextArea text = new JTextArea();
text.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
text.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);

There is also a built-in solution, which is that Ctrl-[Shift-]Tab still works. Actually, those keys always work. Those keys are also the solution when you suddenly find yourself focus-stuck within a JTable. I first thought that a JTable constituted a a "focus cycle root", but it doesn't - it is just the same effect as with the JTextArea problem here outlined (and can be "fixed" the same way).

However, Ctrl-Tag does not quite give the feeling one typically is after, and in particular not when one use the JTextArea more as a solution to text that typically is less than a line big, but can become multiline. Such a field thus looks like a JTextField, but the Tab character suddenly have a completely different meaning.

I Googled a lot, and there are lots of solutions (or rather hacks), but didn't find the above solution, which seems to be the most straightforward after Java 1.5. The huge heap of questions and solutions should, IMHO, give a hint to the Swing team that a specific method for a JTextArea to not suck up Tab events should be made available.

The null means that it will take the focus keys from its parent.

Thursday, February 11, 2010

Anonymous class implementing interface

Why is this not allowed:
JPanel panel = new JPanel(...) implements Scrollable {
    ...
};

I've ended up trying to write something like that several times - and each time I start to wonder what is wrong! A problem is of course that you could not directly access the methods of the implemented interface, but you could still have instanceof'ed and cast'ed it. Some interfaces are also just used for marking, e.g. Cloneable.

It is allowed with a local class:
class ScrollableJPanel extends JPanel implements Scrollable {
    ScrollableJPanel() {
        super(...);
    }
    ...
}
JPanel panel = new ScrollableJPanel();
The restriction seems arbitrary.

PS: Oh my god Blogger sucks. I have GOT to get away from this crappy blogging software. How is it possible to not have made any progress the last 5 years?!