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.netbeans.modules.refactoring.spi.impl;
042:
043: import java.awt.Point;
044: import java.awt.Rectangle;
045: import java.awt.event.KeyEvent;
046: import java.awt.event.KeyListener;
047: import java.awt.event.MouseEvent;
048: import java.awt.event.MouseListener;
049: import javax.swing.JTree;
050: import javax.swing.tree.DefaultTreeModel;
051: import javax.swing.tree.TreePath;
052: import org.netbeans.modules.refactoring.api.RefactoringElement;
053: import org.netbeans.modules.refactoring.api.impl.APIAccessor;
054: import org.netbeans.modules.refactoring.spi.ui.TreeElement;
055:
056: /**
057: * This listener controls click and double click on the CheckNodes. In addition
058: * to it provides support for keyboard node checking/unchecking and opening
059: * document.
060: *
061: * todo (#pf): Improve behaviour and comments.
062: *
063: * @author Pavel Flaska
064: */
065: class CheckNodeListener implements MouseListener, KeyListener {
066: private final boolean isQuery;
067:
068: public CheckNodeListener(boolean isQuery) {
069: this .isQuery = isQuery;
070: }
071:
072: public void mouseClicked(MouseEvent e) {
073: // todo (#pf): we need to solve problem between click and double
074: // click - click should be possible only on the check box area
075: // and double click should be bordered by title text.
076: // we need a test how to detect where the mouse pointer is
077: JTree tree = (JTree) e.getSource();
078: Point p = e.getPoint();
079: int x = e.getX();
080: int y = e.getY();
081: int row = tree.getRowForLocation(x, y);
082: TreePath path = tree.getPathForRow(row);
083:
084: // if path exists and mouse is clicked exactly once
085: if (path != null) {
086: CheckNode node = (CheckNode) path.getLastPathComponent();
087: if (isQuery) {
088: if (e.getClickCount() == 2) {
089: Object o = node.getUserObject();
090: if (o instanceof TreeElement) {
091: o = ((TreeElement) o).getUserObject();
092: if (o instanceof RefactoringElement) {
093: findInSource(node);
094: }
095: } else {
096: if (tree.isCollapsed(row))
097: tree.expandRow(row);
098: else
099: tree.collapseRow(row);
100: }
101: } else if (e.getClickCount() == 1) {
102: Object o = node.getUserObject();
103: if (o instanceof TreeElement) {
104: o = ((TreeElement) o).getUserObject();
105: if (o instanceof RefactoringElement) {
106: openDiff(node);
107: }
108: }
109: }
110: } else {
111: Rectangle chRect = CheckRenderer.getCheckBoxRectangle();
112: Rectangle rowRect = tree.getPathBounds(path);
113: chRect.setLocation(chRect.x + rowRect.x, chRect.y
114: + rowRect.y);
115: if (e.getClickCount() == 1 && chRect.contains(p)
116: && !node.isDisabled()) {
117: boolean isSelected = !(node.isSelected());
118: node.setSelected(isSelected);
119: if (node.getSelectionMode() == CheckNode.DIG_IN_SELECTION) {
120: if (isSelected)
121: tree.expandPath(path);
122: else
123: tree.collapsePath(path);
124: }
125: Object o = node.getUserObject();
126: if (o instanceof TreeElement) {
127: o = ((TreeElement) o).getUserObject();
128: if (o instanceof RefactoringElement) {
129: openDiff(node);
130: }
131: }
132: ((DefaultTreeModel) tree.getModel())
133: .nodeChanged(node);
134: if (row == 0) {
135: tree.revalidate();
136: tree.repaint();
137: }
138: }
139: // double click, open the document
140: else if (e.getClickCount() == 2
141: && chRect.contains(p) == false) {
142: Object o = node.getUserObject();
143: if (o instanceof TreeElement) {
144: o = ((TreeElement) o).getUserObject();
145: if (o instanceof RefactoringElement) {
146: findInSource(node);
147: }
148: } else {
149: if (tree.isCollapsed(row))
150: tree.expandRow(row);
151: else
152: tree.collapseRow(row);
153: }
154: } else if (e.getClickCount() == 1
155: && chRect.contains(p) == false) {
156: Object o = node.getUserObject();
157: if (o instanceof TreeElement) {
158: o = ((TreeElement) o).getUserObject();
159: if (o instanceof RefactoringElement) {
160: openDiff(node);
161: }
162: }
163: }
164: }
165: }
166: }
167:
168: public void keyTyped(KeyEvent e) {
169: }
170:
171: public void keyReleased(KeyEvent e) {
172: // Enter key was pressed, find the reference in document
173: if (e.getKeyCode() == KeyEvent.VK_ENTER) {
174: JTree tree = (JTree) e.getSource();
175: TreePath path = tree.getSelectionPath();
176: if (path != null) {
177: CheckNode node = (CheckNode) path
178: .getLastPathComponent();
179: findInSource(node);
180: }
181: }
182: }
183:
184: public void mouseEntered(MouseEvent e) {
185: }
186:
187: public void mouseExited(MouseEvent e) {
188: }
189:
190: public void mousePressed(MouseEvent e) {
191: }
192:
193: public void mouseReleased(MouseEvent e) {
194: }
195:
196: public void keyPressed(KeyEvent e) {
197: if (e.getKeyChar() == ' ') {
198: JTree tree = (JTree) e.getSource();
199: TreePath path = tree.getSelectionPath();
200: if (path != null) {
201: CheckNode node = (CheckNode) path
202: .getLastPathComponent();
203: node.setSelected(!node.isSelected());
204: e.consume();
205: }
206: }
207: }
208:
209: static void findInSource(CheckNode node) {
210: Object o = node.getUserObject();
211: if (o instanceof TreeElement) {
212: o = ((TreeElement) o).getUserObject();
213: if (o instanceof RefactoringElement) {
214: APIAccessor.DEFAULT
215: .getRefactoringElementImplementation(
216: (RefactoringElement) o).openInEditor();
217: }
218: }
219: }
220:
221: static void openDiff(CheckNode node) {
222: Object o = node.getUserObject();
223: if (o instanceof TreeElement) {
224: o = ((TreeElement) o).getUserObject();
225: if (o instanceof RefactoringElement) {
226: APIAccessor.DEFAULT
227: .getRefactoringElementImplementation(
228: (RefactoringElement) o).showPreview();
229: }
230: }
231: }
232:
233: } // end CheckNodeListener
|