001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.text.actions;
042:
043: import java.awt.event.ActionEvent;
044: import java.util.Enumeration;
045: import java.util.Hashtable;
046:
047: import javax.swing.AbstractAction;
048: import javax.swing.Action;
049:
050: import org.netbeans.modules.visualweb.text.DesignerPaneBase;
051:
052: /**
053: * An Action implementation useful for key bindings that are
054: * shared across a number of different text components. Because
055: * the action is shared, it must have a way of getting it's
056: * target to act upon. This class provides support to try and
057: * find a text component to operate on. The preferred way of
058: * getting the component to act upon is through the ActionEvent
059: * that is received. If the Object returned by getSource can
060: * be narrowed to a text component, it will be used. If the
061: * action event is null or can't be narrowed, the last focused
062: * text component is tried. This is determined by being
063: * used in conjunction with a JTextController which
064: * arranges to share that information with a TextAction.
065: * <p>
066: * <strong>Warning:</strong>
067: * Serialized objects of this class will not be compatible with
068: * future Swing releases. The current serialization support is
069: * appropriate for short term storage or RMI between applications running
070: * the same version of Swing. As of 1.4, support for long term storage
071: * of all JavaBeans<sup><font size="-2">TM</font></sup>
072: * has been added to the <code>java.beans</code> package.
073: * Please see {@link java.beans.XMLEncoder}.
074: *
075: * @author Timothy Prinzing
076: * @version 1.27 01/23/03
077: */
078: public abstract class TextAction extends AbstractAction {
079: /**
080: * Creates a new JTextAction object.
081: *
082: * @param name the name of the action
083: */
084: public TextAction(String name) {
085: super (name);
086: }
087:
088: /**
089: * Determines the component to use for the action.
090: * This if fetched from the source of the ActionEvent
091: * if it's not null and can be narrowed. Otherwise,
092: * the last focused component is used.
093: *
094: * @param e the ActionEvent
095: * @return the component
096: */
097: protected final DesignerPaneBase getTextComponent(ActionEvent e) {
098: if (e != null) {
099: Object o = e.getSource();
100:
101: if (o instanceof DesignerPaneBase) {
102: return (DesignerPaneBase) o;
103: }
104: }
105:
106: return getFocusedComponent();
107: }
108:
109: /**
110: * Takes one list of
111: * commands and augments it with another list
112: * of commands. The second list is considered
113: * to be higher priority than the first list
114: * and commands with the same name will both lists
115: * will only have the dominate command found in the
116: * second list in the returned list.
117: *
118: * @param list1 the first list, may be empty but not null
119: * @param list2 the second list, may be empty but not null
120: * @return the augmented list
121: */
122: public static final Action[] augmentList(Action[] list1,
123: Action[] list2) {
124: Hashtable<String, Action> h = new Hashtable<String, Action>();
125:
126: for (int i = 0; i < list1.length; i++) {
127: Action a = list1[i];
128: String value = (String) a.getValue(Action.NAME);
129: h.put(((value != null) ? value : ""), a);
130: }
131:
132: for (int i = 0; i < list2.length; i++) {
133: Action a = list2[i];
134: String value = (String) a.getValue(Action.NAME);
135: h.put(((value != null) ? value : ""), a);
136: }
137:
138: Action[] actions = new Action[h.size()];
139: int index = 0;
140:
141: for (Enumeration<Action> e = h.elements(); e.hasMoreElements();) {
142: actions[index++] = e.nextElement();
143: }
144:
145: return actions;
146: }
147:
148: /**
149: * Fetches the text component that currently has focus.
150: * This allows actions to be shared across text components
151: * which is useful for key-bindings where a large set of
152: * actions are defined, but generally used the same way
153: * across many different components.
154: *
155: * @return the component
156: */
157: protected final DesignerPaneBase getFocusedComponent() {
158: return DesignerPaneBase.getFocusedComponent();
159: }
160: }
|