2

I want to change the ActionMap of Swing JTextFields in my entire Application by replacing a few actions by my custom implmentations. For an explanation why you can refer to the following post:

How do I make the caret of a JTextComponent skip selected text?

This works well if I do this:

ActionMap map = (ActionMap)UIManager.get("TextField.actionMap");
map.put(DefaultEditorKit.backwardAction, new MyCustomAction());

The only remaining problem now is that so far I have only gotten this to work, when I execute that code after the first instantiation of a JTextField. However, ideally I would like to integrate this code in a custom look and feel or some other central place that does not have to know about the application. Calling

UIManager.getDefaults()

first does not change anything. The map returned by UIManager.get("TextField.actionMap") is still null afterwards.

Right now I am Stuck with putting a dummy new JTextField() in some initialization method of my application and then manipulate the action map which is very ugly.

Community
  • 1
  • 1
user1573546
  • 523
  • 5
  • 13
  • You can create your own `JTextField`(say `MyTextField`) by extending `JTextField` and change the `ActionMap` over there..And then use that overridden version of class throughout your program.. – Vishal K Mar 23 '13 at 08:11
  • The only thing I can think of off the top my head is creating your own UI delegate, but, this would require to have one for each platform you intend to support – MadProgrammer Mar 23 '13 at 08:14
  • very good question, [there are implemented a few veriy interesting TextActions, have to waiting for real answer](http://stackoverflow.com/questions/10075147/how-to-use-textaction) – mKorbel Mar 23 '13 at 08:21

1 Answers1

2

The shared parent actionMap is created at the moment when the first instance of a XXTextComponent gets its uidelegate. The method is in BasicTextUI:

/**
 * Fetch an action map to use.
 */
ActionMap getActionMap() {
    String mapName = getPropertyPrefix() + ".actionMap";
    ActionMap map = (ActionMap)UIManager.get(mapName);

    // JW: we are the first in this LAF
    if (map == null) {
        // JW: create map
        map = createActionMap();
        if (map != null) {
            // JW: store in LAF defaults
            UIManager.getLookAndFeelDefaults().put(mapName, map);
        }
    }
    ....
}

So if you want to add to that map, you have to do so after setting a LAF and after creating an instance.

There's no way around, even though it feels ugly.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • +1, `There's no way around, even though it feels ugly.` That was the conclusion I came to yesterday as well. I was hoping you had more positive insight. – camickr Mar 23 '13 at 20:43