aboutsummaryrefslogtreecommitdiff
path: root/libjava/javax/swing/JComponent.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/javax/swing/JComponent.java')
-rw-r--r--libjava/javax/swing/JComponent.java308
1 files changed, 261 insertions, 47 deletions
diff --git a/libjava/javax/swing/JComponent.java b/libjava/javax/swing/JComponent.java
index e8f01d0..eadf855 100644
--- a/libjava/javax/swing/JComponent.java
+++ b/libjava/javax/swing/JComponent.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package javax.swing;
+import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -48,11 +49,13 @@ import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.ImageObserver;
@@ -192,22 +195,12 @@ public abstract class JComponent extends Container implements Serializable
Border border;
/**
- * A tooltip associated with this component.
- *
- * @see #setToolTip
- * @see #getToolTip
- * @see #toolTipText
- */
- JToolTip toolTip;
-
- /**
- * The text to show in the tooltip associated with this component.
+ * The text to show in the tooltip associated with this component.
*
* @see #setToolTipText
* @see #getToolTipText
- * @see #toolTip
*/
- String toolTipText;
+ String toolTipText;
/**
* <p>Whether to double buffer this component when painting. This flag
@@ -325,6 +318,11 @@ public abstract class JComponent extends Container implements Serializable
* first client property.
*/
private Hashtable clientProperties;
+
+ private InputMap inputMap_whenFocused;
+ private InputMap inputMap_whenAncestorOfFocused;
+ private InputMap inputMap_whenInFocusedWindow;
+ private ActionMap actionMap;
/**
* A lock held during recursive painting; this is used to serialize
@@ -757,18 +755,6 @@ public abstract class JComponent extends Container implements Serializable
return null;
}
- /**
- * Get the ActionListener (typically an {@link Action} object) which is
- * associated with a particular keystroke.
- *
- * @param aKeyStroke The keystroke to retrieve the action of
- *
- * @return The action associated with the specified keystroke
- */
- public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke)
- {
- return null;
- }
/**
* Get the value of the {@link #alignmentX} property.
@@ -875,24 +861,6 @@ public abstract class JComponent extends Container implements Serializable
return g;
}
- /**
- * Return the condition that determines whether a registered action
- * occurs in response to the specified keystroke.
- *
- * @param aKeyStroke The keystroke to return the condition of
- *
- * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
- * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
- * #WHEN_IN_FOCUSED_WINDOW}
- *
- * @see #registerKeyboardAction
- * @see #unregisterKeyboardAction
- * @see #resetKeyboardActiond
- */
- public int getConditionForKeyStroke(KeyStroke aKeyStroke)
- {
- return UNDEFINED_CONDITION;
- }
/**
* Get the value of the {@link #debugGraphicsOptions} property.
@@ -1113,11 +1081,9 @@ public abstract class JComponent extends Container implements Serializable
*/
public JToolTip createToolTip()
{
- if (toolTip == null)
- {
- toolTip = new JToolTip();
+ JToolTip toolTip = new JToolTip();
+ toolTip.setComponent(this);
toolTip.setTipText(toolTipText);
- }
return toolTip;
}
@@ -1145,7 +1111,22 @@ public abstract class JComponent extends Container implements Serializable
*/
public void setToolTipText(String text)
{
+ if (text == null)
+ {
+ ToolTipManager.sharedInstance().unregisterComponent(this);
+ toolTipText = null;
+ return;
+ }
+
+ // XXX: The tip text doesn't get updated unless you set it to null
+ // and then to something not-null. This is consistent with the behaviour
+ // of Sun's ToolTipManager.
+
+ String oldText = toolTipText;
toolTipText = text;
+
+ if (oldText == null)
+ ToolTipManager.sharedInstance().registerComponent(this);
}
/**
@@ -1172,7 +1153,7 @@ public abstract class JComponent extends Container implements Serializable
*/
public String getToolTipText(MouseEvent event)
{
- return toolTipText;
+ return getToolTipText();
}
/**
@@ -1519,6 +1500,51 @@ public abstract class JComponent extends Container implements Serializable
registerKeyboardAction(act, null, stroke, cond);
}
+ /*
+ * There is some charmingly undocumented behavior sun seems to be using
+ * to simulate the old register/unregister keyboard binding API. It's not
+ * clear to me why this matters, but we shall endeavour to follow suit.
+ *
+ * Two main thing seem to be happening when you do registerKeyboardAction():
+ *
+ * - no actionMap() entry gets created, just an entry in inputMap()
+ *
+ * - the inputMap() entry is a proxy class which invokes the the
+ * binding's actionListener as a target, and which clobbers the command
+ * name sent in the ActionEvent, providing the binding command name
+ * instead.
+ *
+ * This much you can work out just by asking the input and action maps
+ * what they contain after making bindings, and watching the event which
+ * gets delivered to the recipient. Beyond that, it seems to be a
+ * sun-private solution so I will only immitate it as much as it matters
+ * to external observers.
+ */
+
+ 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);
+ }
+ }
+
+
/**
* An obsolete method to register a keyboard action on this component.
* You should use <code>getInputMap</code> and <code>getActionMap</code>
@@ -1543,9 +1569,186 @@ public abstract class JComponent extends Container implements Serializable
KeyStroke stroke,
int cond)
{
+ getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
+ }
+
+
+
+ public final void setInputMap(int condition, InputMap map)
+ {
+ enableEvents(AWTEvent.KEY_EVENT_MASK);
+ switch (condition)
+ {
+ case WHEN_FOCUSED:
+ inputMap_whenFocused = map;
+ break;
+
+ case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+ inputMap_whenAncestorOfFocused = map;
+ break;
+
+ case WHEN_IN_FOCUSED_WINDOW:
+ inputMap_whenInFocusedWindow = map;
+ break;
+
+ case UNDEFINED_CONDITION:
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public final InputMap getInputMap(int condition)
+ {
+ enableEvents(AWTEvent.KEY_EVENT_MASK);
+ switch (condition)
+ {
+ case WHEN_FOCUSED:
+ if (inputMap_whenFocused == null)
+ inputMap_whenFocused = new InputMap();
+ return inputMap_whenFocused;
+
+ case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+ if (inputMap_whenAncestorOfFocused == null)
+ inputMap_whenAncestorOfFocused = new InputMap();
+ return inputMap_whenAncestorOfFocused;
+
+ case WHEN_IN_FOCUSED_WINDOW:
+ if (inputMap_whenInFocusedWindow == null)
+ inputMap_whenInFocusedWindow = new InputMap();
+ return inputMap_whenInFocusedWindow;
+
+ case UNDEFINED_CONDITION:
+ default:
+ return null;
+ }
+ }
+
+ public final InputMap getInputMap()
+ {
+ return getInputMap(WHEN_FOCUSED);
+ }
+
+ public final ActionMap getActionMap()
+ {
+ if (actionMap == null)
+ actionMap = new ActionMap();
+ return actionMap;
+ }
+
+ public final void setActionMap(ActionMap map)
+ {
+ actionMap = map;
}
/**
+ * @deprecated As of 1.3 KeyStrokes can be registered with multiple
+ * simultaneous conditions.
+ *
+ * Return the condition that determines whether a registered action
+ * occurs in response to the specified keystroke.
+ *
+ * @param aKeyStroke The keystroke to return the condition of
+ *
+ * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
+ * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
+ * #WHEN_IN_FOCUSED_WINDOW}
+ *
+ * @see #registerKeyboardAction
+ * @see #unregisterKeyboardAction
+ * @see #resetKeyboardActiond
+ */
+ public int getConditionForKeyStroke(KeyStroke ks)
+ {
+ if (inputMap_whenFocused != null
+ && inputMap_whenFocused.get(ks) != null)
+ return WHEN_FOCUSED;
+ else if (inputMap_whenAncestorOfFocused != null
+ && inputMap_whenAncestorOfFocused.get(ks) != null)
+ return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
+ else if (inputMap_whenInFocusedWindow != null
+ && inputMap_whenInFocusedWindow.get(ks) != null)
+ return WHEN_IN_FOCUSED_WINDOW;
+ else
+ return UNDEFINED_CONDITION;
+ }
+
+ /**
+ * @deprecated Use {@link #getActionMap()}
+ *
+ * Get the ActionListener (typically an {@link Action} object) which is
+ * associated with a particular keystroke.
+ *
+ * @param aKeyStroke The keystroke to retrieve the action of
+ *
+ * @return The action associated with the specified keystroke
+ */
+ public ActionListener getActionForKeyStroke(KeyStroke ks)
+ {
+ Object cmd = getInputMap().get(ks);
+ if (cmd != null)
+ {
+ if (cmd instanceof ActionListenerProxy)
+ return (ActionListenerProxy) cmd;
+ else if (cmd instanceof String)
+ return getActionMap().get(cmd);
+ }
+ return null;
+ }
+
+ /**
+ * A hook for subclasses which want to customize event processing.
+ */
+ protected void processComponentKeyEvent(KeyEvent e)
+ {
+ }
+
+ /**
+ * Override the default key dispatch system from Component to hook into
+ * the swing {@link InputMap} / {@link ActionMap} system.
+ *
+ * See <a
+ * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
+ * report</a> for more details, it's somewhat complex.
+ */
+ protected void processKeyEvent(KeyEvent e)
+ {
+ processComponentKeyEvent(e);
+
+ // FIXME: this needs to be elaborated significantly, to do all the
+ // focus / ancestor / window searching for the various binding modes.
+ if (! e.isConsumed() &&
+ processKeyBinding(KeyStroke.getKeyStrokeForEvent(e),
+ e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
+ e.consume();
+ }
+
+ protected boolean processKeyBinding(KeyStroke ks,
+ KeyEvent e,
+ int condition,
+ boolean pressed)
+ {
+ if (isEnabled())
+ {
+ Action act = null;
+ InputMap map = getInputMap(condition);
+ if (map != null)
+ {
+ Object cmd = map.get(ks);
+ if (cmd != null)
+ {
+ if (cmd instanceof ActionListenerProxy)
+ act = (Action) cmd;
+ else
+ act = (Action) getActionMap().get(cmd);
+ }
+ }
+ if (act != null && act.isEnabled())
+ return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
+ }
+ return false;
+ }
+
+ /**
* Remove a keyboard action registry.
*
* @param stroke The keystroke to unregister
@@ -1568,6 +1771,14 @@ public abstract class JComponent extends Container implements Serializable
*/
public void resetKeyboardActions()
{
+ if (inputMap_whenFocused != null)
+ inputMap_whenFocused.clear();
+ if (inputMap_whenAncestorOfFocused != null)
+ inputMap_whenAncestorOfFocused.clear();
+ if (inputMap_whenInFocusedWindow != null)
+ inputMap_whenInFocusedWindow.clear();
+ if (actionMap != null)
+ actionMap.clear();
}
@@ -1875,11 +2086,14 @@ public abstract class JComponent extends Container implements Serializable
if (ui != null)
ui.uninstallUI(this);
+ ComponentUI oldUI = ui;
ui = newUI;
if (ui != null)
ui.installUI(this);
+ firePropertyChange("UI", oldUI, newUI);
+
revalidate();
repaint();
}