I need to create a class derived from JTextComponent
(from JTextPane
, actually) in which at least one of the default key mappings is changed. That is, in my special JTextPane, I want the ">" keystroke to perform an action and NOT add that character to the text pane as, by default all printable typed characters are treated.
To defeat the normal behavior, there are the following APIs:
JTextComponent.getKeymap()
Keymap.addActionForKeyStroke()
JTextComponent.setKeymap()
However, I find that though these methods are not static they DO affect the keymap used by all JTextComponent
s in my application. There is no simple mechanism by which a Keymap may be cloned which, presumably would solve the problem, or am I missing something.
What I am after is a way to change the keymap for my JTextPane
class but not for ALL JTextComponent
-derived classes.
Or should I be looking elsewhere?
JTextComponent is the base class for swing text components. It tries to be compatible with the java. awt. TextComponent class where it can reasonably do so. Also provided are other services for additional flexibility (beyond the pluggable UI and bean support).
A JTextPane is a subclass of JEditorPane. A JTextPane is used for a styled document with embedded images and components. A JTextPane is a text component that can be marked up with the attributes that are represented graphically and it can use a DefaultStyledDocument as the default model.
IMHO, aIt's a bit difficult to understand but the answer is here: Using the Swing Text Package by Tim Prinzing
The author of the article, Tim Prinzing, who is also, I believe, the author of JTextComponent according to source code, provides an example which I will comment:
JTextField field = new JTextField();
// get the keymap which will be the static default "look and feel" keymap
Keymap laf = field.getKeymap();
// create a new keymap whose parent is the look and feel keymap
Keymap myMap = JTextComponent.addKeymap(null, laf);
// at this point, add keystrokes you want to map to myMap
myMap.addActionForKeyStroke(getKeyStroke(VK_PERIOD, SHIFT_DOWN_MASK), myAction);
// make this the keymap for this component only. Will "include" the default keymap
field.setKeymap(myMap);
My mistake was adding my keystroke to the keymap returned by getKeymap instead of letting it to the child. IMHO, the name addKeymap() is confusing. It should probably be createKeymap().
I would go for a specific Document instead, especially if you want your mapping to be valid just for an instance and not globally.
Here is an example of capturing keys and perform appropriate actions:
JFrame f = new JFrame();
StyledDocument d = new DefaultStyledDocument() {
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (">".equals(str)) {
// Do some action
System.out.println("Run action corresponding to '" + str + "'");
} else {
super.insertString(offs, str, a);
}
}
};
JTextPane t = new JTextPane(d);
f.add(t);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With