Key Bindings for text components are all fixed.
2005-12-20 Lillian Angel <[EMAIL PROTECTED]>
* javax/swing/plaf/basic/BasicLookAndFeel.java
(initClassDefaults): Fixed typo.
(initComponentDefaults): Removed keyBindings defaults for
Text*. Added focusInputMap for Text*.
* javax/swing/plaf/basic/BasicTextUI.java
(installKeyBoardActions): Added code to load the focusInputMap
and install all the actions for each key.
(ActionListenerProxy): New class implemented.
(converModifiers): New method to convert the modifiers.
(getActionMap): Removed function. Not needed.
(createActionMap): Likewise.
* javax/swing/text/JTextComponent.java
(JTextComponent): Removed code to load the keymap.
On Wed, 2005-12-21 at 13:50 +0100, Roman Kennke wrote:
> Hi Lillian,
>
> I would prefer the more efficient (and more correct?) solution and fix
> the viewToModel() methods. I don't really care if it doesn't work yet
> because of the viewToModel() methods not working properly, this way we
> have some more reasons to fix those.
>
> Also, in JTextComponent you directly create KeyBindings for the new
> Actions. This doesn't sound right, IMO this should be done by the UI
> (BasicTextUI). The UIDefaults should have an array of InputMap-like
> bindings (e.g. in TextField.focusInputMap) that should then be loaded
> into an InputMap (using LookAndFeel.loadKeyBindings()) and installed in
> the text component (using SwingUtilities.replaceUIInputMap()). Direct
> key bindings are not what we want.
>
> Could you please fix that? (At least the keybinding thing?) Also note
> that there is a getActionMap() method in BasicTextUI that really
> shouldn't be there. We should figure out how to properly install an
> ActionMap on the text component, I would think that we fetch
> getActions() from JTextComponent and create an ActionMap out of it by
> fetching the NAME from the Action instances and put them into an
> ActionMap using the NAME as key.
>
> Cheers, Roman
>
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.69
diff -u -r1.69 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java 17 Dec 2005 01:35:38 -0000 1.69
+++ javax/swing/plaf/basic/BasicLookAndFeel.java 21 Dec 2005 16:45:50 -0000
@@ -220,7 +220,7 @@
"TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI",
"TextAreaUI", "javax.swing.plaf.basic.BasicTextAreaUI",
"TextFieldUI", "javax.swing.plaf.basic.BasicTextFieldUI",
- "TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI",
+ "TextUI", "javax.swing.plaf.basic.BasicTextUI",
"ToggleButtonUI", "javax.swing.plaf.basic.BasicToggleButtonUI",
"ToolBarSeparatorUI", "javax.swing.plaf.basic.BasicToolBarSeparatorUI",
"ToolBarUI", "javax.swing.plaf.basic.BasicToolBarUI",
@@ -1052,28 +1052,32 @@
"TableHeader.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"TableHeader.foreground", new ColorUIResource(new ColorUIResource(0, 0, 0)),
- "TextArea.background", new ColorUIResource(light),
- "TextArea.border",
- new BorderUIResource(BasicBorders.getMarginBorder()),
+ "TextArea.background", new ColorUIResource(light),
+ "TextArea.border", new BorderUIResource(BasicBorders.getMarginBorder()),
"TextArea.caretBlinkRate", new Integer(500),
"TextArea.caretForeground", new ColorUIResource(Color.black),
"TextArea.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12),
"TextArea.foreground", new ColorUIResource(Color.black),
"TextArea.inactiveForeground", new ColorUIResource(Color.gray),
- "TextArea.keyBindings", new JTextComponent.KeyBinding[] {
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP,
- 0), "caret-up"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,
- 0), "caret-down"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,
- 0), "page-up"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,
- 0), "page-down"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
- 0), "insert-break"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
- 0), "insert-tab")
- },
+ "TextArea.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
+ "UP", "caret-up",
+ "DOWN", "caret-down",
+ "PAGE_UP", "page-up",
+ "PAGE_DOWN", "page-down",
+ "ENTER", "insert-break",
+ "TAB", "insert-tab",
+ "LEFT", "caret-backward",
+ "RIGHT", "caret-forward",
+ "BACK_SPACE", "delete-previous",
+ "ctrl X", "cut-to-clipboard",
+ "ctrl C", "copy-to-clipboard",
+ "ctrl V", "paste-from-clipboard",
+ "shift LEFT", "selection-backward",
+ "shift RIGHT", "selection-forward",
+ "HOME", "caret-begin-line",
+ "END", "caret-end-line",
+ "DELETE", "delete-next"
+ }),
"TextArea.margin", new InsetsUIResource(0, 0, 0, 0),
"TextArea.selectionBackground", new ColorUIResource(Color.black),
"TextArea.selectionForeground", new ColorUIResource(Color.white),
@@ -1089,17 +1093,20 @@
"TextField.inactiveForeground", new ColorUIResource(Color.GRAY),
"TextField.light", new ColorUIResource(highLight),
"TextField.highlight", new ColorUIResource(light),
- "TextField.keyBindings", new JTextComponent.KeyBinding[] {
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
- 0),
- "notify-field-accept"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
- InputEvent.SHIFT_DOWN_MASK),
- "selection-backward"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
- InputEvent.SHIFT_DOWN_MASK),
- "selection-forward"),
- },
+ "TextField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
+ "ENTER", "notify-field-accept",
+ "LEFT", "caret-backward",
+ "RIGHT", "caret-forward",
+ "BACK_SPACE", "delete-previous",
+ "ctrl X", "cut-to-clipboard",
+ "ctrl C", "copy-to-clipboard",
+ "ctrl V", "paste-from-clipboard",
+ "shift LEFT", "selection-backward",
+ "shift RIGHT", "selection-forward",
+ "HOME", "caret-begin-line",
+ "END", "caret-end-line",
+ "DELETE", "delete-next"
+ }),
"TextField.margin", new InsetsUIResource(0, 0, 0, 0),
"TextField.selectionBackground", new ColorUIResource(Color.black),
"TextField.selectionForeground", new ColorUIResource(Color.white),
@@ -1110,20 +1117,25 @@
"TextPane.font", new FontUIResource("Serif", Font.PLAIN, 12),
"TextPane.foreground", new ColorUIResource(Color.black),
"TextPane.inactiveForeground", new ColorUIResource(Color.gray),
- "TextPane.keyBindings", new JTextComponent.KeyBinding[] {
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP,
- 0), "caret-up"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,
- 0), "caret-down"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,
- 0), "page-up"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,
- 0), "page-down"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
- 0), "insert-break"),
- new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
- 0), "insert-tab")
- },
+ "TextPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
+ "UP", "caret-up",
+ "DOWN", "caret-down",
+ "PAGE_DOWN", "page-down",
+ "PAGE_UP", "page-up",
+ "ENTER", "insert-break",
+ "TAB", "insert-tab",
+ "LEFT", "caret-backward",
+ "RIGHT", "caret-forward",
+ "BACK_SPACE", "delete-previous",
+ "ctrl X", "cut-to-clipboard",
+ "ctrl C", "copy-to-clipboard",
+ "ctrl V", "paste-from-clipboard",
+ "shift LEFT", "selection-backward",
+ "shift RIGHT", "selection-forward",
+ "HOME", "caret-begin-line",
+ "END", "caret-end-line",
+ "DELETE", "delete-next"
+ }),
"TextPane.margin", new InsetsUIResource(3, 3, 3, 3),
"TextPane.selectionBackground", new ColorUIResource(Color.black),
"TextPane.selectionForeground", new ColorUIResource(Color.white),
@@ -1178,8 +1190,6 @@
}),
"Tree.background", new ColorUIResource(new Color(255, 255, 255)),
"Tree.changeSelectionWithFocus", Boolean.TRUE,
-// "Tree.closedIcon", new IconUIResource(new ImageIcon("icons/TreeClosed.png")),
-// "Tree.collapsedIcon", new IconUIResource(new ImageIcon("icons/TreeCollapsed.png")),
"Tree.drawsFocusBorderAroundIcon", Boolean.FALSE,
"Tree.editorBorder", new BorderUIResource.LineBorderUIResource(Color.lightGray),
"Tree.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
Index: javax/swing/plaf/basic/BasicTextUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTextUI.java,v
retrieving revision 1.57
diff -u -r1.57 BasicTextUI.java
--- javax/swing/plaf/basic/BasicTextUI.java 23 Nov 2005 11:59:30 -0000 1.57
+++ javax/swing/plaf/basic/BasicTextUI.java 21 Dec 2005 16:45:51 -0000
@@ -46,15 +46,20 @@
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
+import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
@@ -62,6 +67,7 @@
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ActionMapUIResource;
+import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.BadLocationException;
@@ -636,7 +642,7 @@
* Installs the keyboard actions on the text components.
*/
protected void installKeyboardActions()
- {
+ {
// load any bindings for the older Keymap interface
Keymap km = JTextComponent.getKeymap(getKeymapName());
if (km == null)
@@ -644,10 +650,104 @@
textComponent.setKeymap(km);
// load any bindings for the newer InputMap / ActionMap interface
- SwingUtilities.replaceUIInputMap(textComponent,
- JComponent.WHEN_FOCUSED,
+ SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED,
getInputMap(JComponent.WHEN_FOCUSED));
- SwingUtilities.replaceUIActionMap(textComponent, getActionMap());
+ SwingUtilities.replaceUIActionMap(textComponent, textComponent.getActionMap());
+
+ InputMap focusInputMap = textComponent.getInputMap(JComponent.WHEN_FOCUSED);
+ InputMapUIResource parentInputMap = new InputMapUIResource();
+ ActionMap parentActionMap = new ActionMapUIResource();
+ Object keys[] = focusInputMap.allKeys();
+
+ for (int i = 0; i < keys.length; i++)
+ {
+ String act = (String) focusInputMap.get((KeyStroke) keys[i]);
+ Action[] actions = textComponent.getActions();
+ for (int j = 0; j < actions.length; j++)
+ {
+ Action currAction = actions[j];
+ if (currAction != null
+ && (currAction.getValue(Action.NAME).equals(act)))
+ parentActionMap.put(act, new ActionListenerProxy(currAction, act));
+ }
+
+ parentInputMap.put(KeyStroke.getKeyStroke(((KeyStroke) keys[i]).getKeyCode(),
+ convertModifiers(((KeyStroke) keys[i]).getModifiers())),
+ act);
+ parentInputMap.put(KeyStroke.getKeyStroke(((KeyStroke) keys[i]).getKeyCode(),
+ ((KeyStroke) keys[i]).getModifiers()),
+ act);
+ }
+
+ parentInputMap.setParent(textComponent.getInputMap(JComponent.WHEN_FOCUSED).getParent());
+ parentActionMap.setParent(textComponent.getActionMap().getParent());
+ textComponent.getInputMap(JComponent.WHEN_FOCUSED).setParent(parentInputMap);
+ textComponent.getActionMap().setParent(parentActionMap);
+ }
+
+ /**
+ * This class is used to mimic the behaviour of the JDK when registering
+ * keyboard actions. It is the same as the private class used in JComponent
+ * for the same reason. This class receives an action event and dispatches it
+ * to the true receiver after altering the actionCommand property of the
+ * event.
+ */
+ private static class ActionListenerProxy extends AbstractAction
+ {
+ ActionListener target;
+
+ String bindingCommandName;
+
+ public ActionListenerProxy(ActionListener li, String cmd)
+ {
+ target = li;
+ bindingCommandName = cmd;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ ActionEvent derivedEvent = new ActionEvent(e.getSource(), e.getID(),
+ bindingCommandName,
+ e.getModifiers());
+ target.actionPerformed(derivedEvent);
+ }
+ }
+
+ /**
+ * Converts the modifiers.
+ *
+ * @param mod -
+ * modifier to convert
+ * @returns the new modifier
+ */
+ private int convertModifiers(int mod)
+ {
+ if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.SHIFT_MASK;
+ mod &= ~KeyEvent.SHIFT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.CTRL_MASK;
+ mod &= ~KeyEvent.CTRL_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.META_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.META_MASK;
+ mod &= ~KeyEvent.META_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_MASK;
+ mod &= ~KeyEvent.ALT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_GRAPH_MASK;
+ mod &= ~KeyEvent.ALT_GRAPH_DOWN_MASK;
+ }
+ return mod;
}
/**
@@ -674,46 +774,6 @@
}
/**
- * Returns the ActionMap to be installed on the text component.
- *
- * @return the ActionMap to be installed on the text component
- */
- // FIXME: The UIDefaults have no entries for .actionMap, so this should
- // be handled somehow different.
- ActionMap getActionMap()
- {
- String prefix = getPropertyPrefix();
- ActionMap am = (ActionMap) UIManager.get(prefix + ".actionMap");
- if (am == null)
- {
- am = createActionMap();
- // FIXME: Putting something in the UIDefaults map is certainly wrong.
- // However, the whole method seems wrong and must be replaced by
- // something that is less wrong.
- UIManager.put(prefix + ".actionMap", am);
- }
- return am;
- }
-
- /**
- * Creates an ActionMap to be installed on the text component.
- *
- * @return an ActionMap to be installed on the text component
- */
- ActionMap createActionMap()
- {
- Action[] actions = textComponent.getActions();
- ActionMap am = new ActionMapUIResource();
- for (int i = 0; i < actions.length; ++i)
- {
- String name = (String) actions[i].getValue(Action.NAME);
- if (name != null)
- am.put(name, actions[i]);
- }
- return am;
- }
-
- /**
* Uninstalls this TextUI from the text component.
*
* @param component the text component to uninstall the UI from
Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v
retrieving revision 1.47
diff -u -r1.47 JTextComponent.java
--- javax/swing/text/JTextComponent.java 20 Dec 2005 22:42:04 -0000 1.47
+++ javax/swing/text/JTextComponent.java 21 Dec 2005 16:45:51 -0000
@@ -906,53 +906,16 @@
public JTextComponent()
{
Keymap defkeymap = getKeymap(DEFAULT_KEYMAP);
- boolean creatingKeymap = false;
if (defkeymap == null)
{
defkeymap = addKeymap(DEFAULT_KEYMAP, null);
defkeymap.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction());
- creatingKeymap = true;
}
setFocusable(true);
setEditable(true);
enableEvents(AWTEvent.KEY_EVENT_MASK);
updateUI();
-
- // need to do this after updateUI()
- if (creatingKeymap)
- loadKeymap(
- defkeymap,
- new KeyBinding[] {
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
- DefaultEditorKit.backwardAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
- DefaultEditorKit.forwardAction),
- new KeyBinding(KeyStroke.getKeyStroke("typed \b"),
- DefaultEditorKit.deletePrevCharAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_X,
- KeyEvent.CTRL_DOWN_MASK),
- DefaultEditorKit.cutAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_C,
- KeyEvent.CTRL_DOWN_MASK),
- DefaultEditorKit.copyAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_V,
- KeyEvent.CTRL_DOWN_MASK),
- DefaultEditorKit.pasteAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
- KeyEvent.SHIFT_DOWN_MASK),
- DefaultEditorKit.selectionBackwardAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
- KeyEvent.SHIFT_DOWN_MASK),
- DefaultEditorKit.selectionForwardAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0),
- DefaultEditorKit.beginLineAction),
- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0),
- DefaultEditorKit.endLineAction),
- new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"),
- DefaultEditorKit.deleteNextCharAction)
- },
- getActions());
}
public void setDocument(Document newDoc)
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches