|
Replies:
5
-
Last Post:
Dec 8, 2005 1:30 PM
by: idk
|
|
|
|
|
|
|
Is there a way to have a "default action map"?
Posted:
Nov 30, 2005 3:35 AM
|
|
|
I am looking for a way to add sensible behavior for ctrl-backspace and ctrl-delete to all text components.
I can modify the default input maps for all text components by getting the input maps from UIManager, e.g. UIManager.getDefaults().get("TextArea.focusInputMap");
So that's the first half of the job.
The action part is trickier: I have written custom actions DeleteToPreviousWord and DeleteToNextWord, because there are no default actions with this functionality. These actions work fine, when added to the action map of a single text component. Now, is there a way to globally add these actions to the action maps of all components?
I'll try and have a look at auxiliary look and feels, maybe that is a way.
In the mean time any suggestions are greatly welcome.
|
|
|
|
|
|
|
Re: Is there a way to have a "default action map"?
Posted:
Nov 30, 2005 6:37 AM
in response to: skelvin
|
|
|
There doesn't seem to be a clear way to do this via the API. Each maps ultimate parent appears unique. I guess I would create a factory object and get my JTextComponents from it. Then the factory object could be the thing responsible for setting up the InputMaps and ActionMaps.
getJTextField( args... ) getJTextPane( args... ) getJEditorPane( args... ) setDefaultActionMap( ActionMap ) setDefaultInputMap( InputMap )
leouser
|
|
|
|
|
|
|
|
Re: Is there a way to have a "default action map"?
Posted:
Nov 30, 2005 11:00 AM
in response to: skelvin
|
|
|
Hi,
Could you try something like this:
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.TextAction;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
initUI();
}
});
}
static void initUI() {
InputMap map = (InputMap) UIManager.getDefaults().get("TextArea.focusInputMap");
InputMap myMap = new InputMap();
map.setParent(myMap);
myMap.put(KeyStroke.getKeyStroke("ctrl pressed D"), new MyTextAction());
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextArea());
frame.pack();
frame.setVisible(true);
}
public static class MyTextAction extends TextAction {
MyTextAction() {
super("MyTextAction");
}
public void actionPerformed(ActionEvent e) {
System.out.println("Action performed on " + getTextComponent(e));
}
}
}
Thanks, Igor
|
|
|
|
|
|
|
|
Re: Is there a way to have a "default action map"?
Posted:
Nov 30, 2005 2:06 PM
in response to: idk
|
|
|
Interesting, the code may well prove to be the "default action map" for text components. Im assuming that when the widget comes into focus that action map becomes the map for the widget. Cool stuff.
leouser
|
|
|
|
|
|
|
|
Re: Is there a way to have a "default action map"?
Posted:
Dec 1, 2005 3:42 AM
in response to: idk
|
|
|
Igor, thanks a lot! It works nicely, even for JEditorPane which use an editor kit. Can you tell me why it works? Is it a general rule: If you put an action as value in the input map, then it is used directly, skipping the mapping from input-map-value-TO-action-map-key-TO-action-value?
Previously I found that after I created the first JTextArea, UIManager.getDefaults().get("Text.Area.actionMap") does indeed return a default map, that I can use to add additional actions. However that does not work for editor panes, because each is configured from their editor kit individual (no defaults).
Another attempt worked fine, but seems really hacky to me: I created and added an auxiliary LAF that overrides LookAndFeel.getDefaults() and returned an instance of a subclass of UIDefaults. That subclass overrides UIDefaults.getUI(JComponent target) to install the actions on each target (that is a text component) separately, but then returns null, so that no additional UI is created. The Multiplexing LAF is optimized to return the single original UI in that case, so that no overhead occurs after the initial creation. So you can use the auxiliary LAF as a hook to intercept the creation of any JComponent - quite funny.
Your approach is by far the best, I only wonder why it works? Can you point me to some source code in the JDK?
|
|
|
|
|
|
|
|
Re: Is there a way to have a "default action map"?
Posted:
Dec 8, 2005 1:30 PM
in response to: skelvin
|
|
|
Hi,
> I only wonder why it works?
My example uses only InputMap. It does not use ActionMap at all. It uses the actual Action as a key in InputMap. I was surprised it works too.
It so happened that text-components can deal with it. If key in InputMap is an Action this Action is used directly without going to ActionMap. (see javax.swing.text.JTextComponent.KeymapActionMap)
Guess clearer solutions would be to modify both default ActionMap and default InputMap.
see javax.swing.plaf.basic.BasicTextUI.getInputMap and getActionMap
Default ActionMap is a parent of ActionMap created from the EditorKit. (Default ActionMap is created when BasicTextUI.getActionMap is first invoked)
- Igor
|
|
|
|
|