View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package javax.swing.text;
26  
27  import java.awt.event.ActionEvent;
28  import java.awt.KeyboardFocusManager;
29  import java.awt.Component;
30  import java.util.Hashtable;
31  import java.util.Enumeration;
32  import javax.swing.Action;
33  import javax.swing.AbstractAction;
34  import javax.swing.KeyStroke;
35  
36  /**
37   * An Action implementation useful for key bindings that are
38   * shared across a number of different text components.  Because
39   * the action is shared, it must have a way of getting it's
40   * target to act upon.  This class provides support to try and
41   * find a text component to operate on.  The preferred way of
42   * getting the component to act upon is through the ActionEvent
43   * that is received.  If the Object returned by getSource can
44   * be narrowed to a text component, it will be used.  If the
45   * action event is null or can't be narrowed, the last focused
46   * text component is tried.  This is determined by being
47   * used in conjunction with a JTextController which
48   * arranges to share that information with a TextAction.
49   * <p>
50   * <strong>Warning:</strong>
51   * Serialized objects of this class will not be compatible with
52   * future Swing releases. The current serialization support is
53   * appropriate for short term storage or RMI between applications running
54   * the same version of Swing.  As of 1.4, support for long term storage
55   * of all JavaBeans&trade;
56   * has been added to the <code>java.beans</code> package.
57   * Please see {@link java.beans.XMLEncoder}.
58   *
59   * @author  Timothy Prinzing
60   */
61  public abstract class TextAction extends AbstractAction {
62  
63      /**
64       * Creates a new JTextAction object.
65       *
66       * @param name the name of the action
67       */
68      public TextAction(String name) {
69          super(name);
70      }
71  
72      /**
73       * Determines the component to use for the action.
74       * This if fetched from the source of the ActionEvent
75       * if it's not null and can be narrowed.  Otherwise,
76       * the last focused component is used.
77       *
78       * @param e the ActionEvent
79       * @return the component
80       */
81      protected final JTextComponent getTextComponent(ActionEvent e) {
82          if (e != null) {
83              Object o = e.getSource();
84              if (o instanceof JTextComponent) {
85                  return (JTextComponent) o;
86              }
87          }
88          return getFocusedComponent();
89      }
90  
91      /**
92       * Takes one list of
93       * commands and augments it with another list
94       * of commands.  The second list takes precedence
95       * over the first list; that is, when both lists
96       * contain a command with the same name, the command
97       * from the second list is used.
98       *
99       * @param list1 the first list, may be empty but not
100      *              <code>null</code>
101      * @param list2 the second list, may be empty but not
102      *              <code>null</code>
103      * @return the augmented list
104      */
105     public static final Action[] augmentList(Action[] list1, Action[] list2) {
106         Hashtable<String, Action> h = new Hashtable<String, Action>();
107         for (Action a : list1) {
108             String value = (String)a.getValue(Action.NAME);
109             h.put((value!=null ? value:""), a);
110         }
111         for (Action a : list2) {
112             String value = (String)a.getValue(Action.NAME);
113             h.put((value!=null ? value:""), a);
114         }
115         Action[] actions = new Action[h.size()];
116         int index = 0;
117         for (Enumeration e = h.elements() ; e.hasMoreElements() ;) {
118             actions[index++] = (Action) e.nextElement();
119         }
120         return actions;
121     }
122 
123     /**
124      * Fetches the text component that currently has focus.
125      * This allows actions to be shared across text components
126      * which is useful for key-bindings where a large set of
127      * actions are defined, but generally used the same way
128      * across many different components.
129      *
130      * @return the component
131      */
132     protected final JTextComponent getFocusedComponent() {
133         return JTextComponent.getFocusedComponent();
134     }
135 }