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-2006 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.openide.actions;
042:
043: import org.openide.nodes.Index;
044: import org.openide.nodes.Node;
045: import org.openide.util.HelpCtx;
046: import org.openide.util.NbBundle;
047: import org.openide.util.actions.*;
048:
049: import java.lang.ref.Reference;
050: import java.lang.ref.WeakReference;
051:
052: import javax.swing.event.ChangeEvent;
053: import javax.swing.event.ChangeListener;
054:
055: /** Move an item down in a list.
056: * This action is final only for performance reasons.
057: * @see Index
058: *
059: * @author Ian Formanek, Dafe Simonek
060: */
061: public final class MoveDownAction extends NodeAction {
062: /** the key to listener to reorder of selected nodes */
063: private static final String PROP_ORDER_LISTENER = "sellistener"; // NOI18N
064:
065: /** Holds index cookie on which we are listening */
066: private Reference<Index> curIndexCookie;
067:
068: /* Initilizes the set of properties.
069: */
070: protected void initialize() {
071: super .initialize();
072:
073: // initializes the listener
074: OrderingListener sl = new OrderingListener();
075: putProperty(PROP_ORDER_LISTENER, sl);
076: }
077:
078: private Index getCurIndexCookie() {
079: return curIndexCookie == null ? null : curIndexCookie.get();
080: }
081:
082: protected void performAction(Node[] activatedNodes) {
083: // we need to check activatedNodes, because there's no
084: // guarantee that they not changed between enable() and
085: // performAction calls
086: Index cookie = getIndexCookie(activatedNodes);
087:
088: if (cookie == null) {
089: return;
090: }
091:
092: int nodeIndex = cookie.indexOf(activatedNodes[0]);
093:
094: if ((nodeIndex >= 0)
095: && (nodeIndex < (cookie.getNodesCount() - 1))) {
096: cookie.moveDown(nodeIndex);
097: }
098: }
099:
100: protected boolean asynchronous() {
101: return false;
102: }
103:
104: protected boolean enable(Node[] activatedNodes) {
105: // remove old listener, if any
106: Index idx = getCurIndexCookie();
107:
108: if (idx != null) {
109: idx
110: .removeChangeListener((ChangeListener) getProperty(PROP_ORDER_LISTENER));
111: idx = null;
112: }
113:
114: Index cookie = getIndexCookie(activatedNodes);
115:
116: if (cookie == null) {
117: return false;
118: }
119:
120: int nodeIndex = cookie.indexOf(activatedNodes[0]);
121:
122: // now start listening to reordering changes
123: cookie
124: .addChangeListener((OrderingListener) getProperty(PROP_ORDER_LISTENER));
125: curIndexCookie = new WeakReference<Index>(cookie);
126:
127: return (nodeIndex >= 0)
128: && (nodeIndex < (cookie.getNodesCount() - 1));
129: }
130:
131: public String getName() {
132: return NbBundle.getMessage(MoveDownAction.class, "MoveDown");
133: }
134:
135: public HelpCtx getHelpCtx() {
136: return new HelpCtx(MoveDownAction.class);
137: }
138:
139: /** Helper method. Returns index cookie or null, if some
140: * conditions aren't satisfied */
141: private Index getIndexCookie(Node[] activatedNodes) {
142: if ((activatedNodes == null) || (activatedNodes.length != 1)) {
143: return null;
144: }
145:
146: Node parent = activatedNodes[0].getParentNode();
147:
148: if (parent == null) {
149: return null;
150: }
151:
152: return (Index) parent.getCookie(Index.class);
153: }
154:
155: /** Listens to the ordering changes and enables/disables the
156: * action if appropriate */
157: private final class OrderingListener implements ChangeListener {
158: OrderingListener() {
159: }
160:
161: public void stateChanged(ChangeEvent e) {
162: Node[] activatedNodes = getActivatedNodes();
163: Index cookie = getIndexCookie(activatedNodes);
164:
165: if (cookie == null) {
166: setEnabled(false);
167: } else {
168: int nodeIndex = cookie.indexOf(activatedNodes[0]);
169: setEnabled((nodeIndex >= 0)
170: && (nodeIndex < (cookie.getNodesCount() - 1)));
171: }
172: }
173: }
174: }
|