001: //$Header$
002: /*
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: */
019:
020: package org.apache.jmeter.report.gui.tree;
021:
022: import java.awt.Container;
023: import java.awt.event.ActionEvent;
024: import java.awt.event.ActionListener;
025: import java.awt.event.KeyEvent;
026: import java.awt.event.KeyListener;
027: import java.awt.event.MouseEvent;
028: import java.awt.event.MouseListener;
029: import java.awt.event.MouseMotionListener;
030:
031: import javax.swing.JLabel;
032: import javax.swing.JMenuItem;
033: import javax.swing.JPopupMenu;
034: import javax.swing.JTree;
035: import javax.swing.event.TreeSelectionEvent;
036: import javax.swing.event.TreeSelectionListener;
037: import javax.swing.tree.TreeNode;
038: import javax.swing.tree.TreePath;
039:
040: import org.apache.jmeter.control.gui.ReportGui;
041: import org.apache.jmeter.gui.ReportGuiPackage;
042: import org.apache.jmeter.gui.ReportMainFrame;
043: import org.apache.jmeter.report.gui.action.ReportDragNDrop;
044: import org.apache.jmeter.util.JMeterUtils;
045: import org.apache.jorphan.logging.LoggingManager;
046: import org.apache.log.Logger;
047:
048: /**
049: * @author Peter Lin
050: * @version $Revision: 493793 $ Last updated: $Date: 2007-01-07 18:19:27 +0000 (Sun, 07 Jan 2007) $
051: */
052: public class ReportTreeListener implements TreeSelectionListener,
053: MouseListener, KeyListener, MouseMotionListener {
054: transient private static Logger log = LoggingManager
055: .getLoggerForClass();
056:
057: // Container endWindow;
058: // JPopupMenu pop;
059: private TreePath currentPath;
060:
061: private ActionListener actionHandler;
062:
063: private ReportTreeModel model;
064:
065: private JTree tree;
066:
067: private boolean dragging = false;
068:
069: private ReportTreeNode[] draggedNodes;
070:
071: private JLabel dragIcon = new JLabel(JMeterUtils
072: .getImage("leafnode.gif"));
073:
074: /**
075: * Constructor for the JMeterTreeListener object.
076: */
077: public ReportTreeListener(ReportTreeModel model) {
078: this .model = model;
079: dragIcon.validate();
080: dragIcon.setVisible(true);
081: }
082:
083: public ReportTreeListener() {
084: dragIcon.validate();
085: dragIcon.setVisible(true);
086: }
087:
088: public void setModel(ReportTreeModel m) {
089: model = m;
090: }
091:
092: /**
093: * Sets the ActionHandler attribute of the JMeterTreeListener object.
094: *
095: * @param ah
096: * the new ActionHandler value
097: */
098: public void setActionHandler(ActionListener ah) {
099: actionHandler = ah;
100: }
101:
102: /**
103: * Sets the JTree attribute of the JMeterTreeListener object.
104: *
105: * @param tree
106: * the new JTree value
107: */
108: public void setJTree(JTree tree) {
109: this .tree = tree;
110: }
111:
112: /**
113: * Sets the EndWindow attribute of the JMeterTreeListener object.
114: *
115: * @param window
116: * the new EndWindow value
117: */
118: public void setEndWindow(Container window) {
119: // endWindow = window;
120: }
121:
122: /**
123: * Gets the JTree attribute of the JMeterTreeListener object.
124: *
125: * @return tree the current JTree value.
126: */
127: public JTree getJTree() {
128: return tree;
129: }
130:
131: /**
132: * Gets the CurrentNode attribute of the JMeterTreeListener object.
133: *
134: * @return the CurrentNode value
135: */
136: public ReportTreeNode getCurrentNode() {
137: if (currentPath != null) {
138: if (currentPath.getLastPathComponent() != null) {
139: return (ReportTreeNode) currentPath
140: .getLastPathComponent();
141: } else {
142: return (ReportTreeNode) currentPath.getParentPath()
143: .getLastPathComponent();
144: }
145: } else {
146: return (ReportTreeNode) model.getRoot();
147: }
148: }
149:
150: public ReportTreeNode[] getSelectedNodes() {
151: TreePath[] paths = tree.getSelectionPaths();
152: if (paths == null) {
153: return new ReportTreeNode[] { getCurrentNode() };
154: }
155: ReportTreeNode[] nodes = new ReportTreeNode[paths.length];
156: for (int i = 0; i < paths.length; i++) {
157: nodes[i] = (ReportTreeNode) paths[i].getLastPathComponent();
158: }
159:
160: return nodes;
161: }
162:
163: public TreePath removedSelectedNode() {
164: currentPath = currentPath.getParentPath();
165: return currentPath;
166: }
167:
168: public void valueChanged(TreeSelectionEvent e) {
169: log.debug("value changed, updating currentPath");
170: currentPath = e.getNewLeadSelectionPath();
171: actionHandler.actionPerformed(new ActionEvent(this , 3333,
172: "edit"));
173: }
174:
175: public void mouseClicked(MouseEvent ev) {
176: }
177:
178: public void mouseReleased(MouseEvent e) {
179: if (dragging
180: && isValidDragAction(draggedNodes, getCurrentNode())) {
181: dragging = false;
182: JPopupMenu dragNdrop = new JPopupMenu();
183: JMenuItem item = new JMenuItem(JMeterUtils
184: .getResString("Insert Before"));
185: item.addActionListener(actionHandler);
186: item.setActionCommand(ReportDragNDrop.INSERT_BEFORE);
187: dragNdrop.add(item);
188: item = new JMenuItem(JMeterUtils
189: .getResString("Insert After"));
190: item.addActionListener(actionHandler);
191: item.setActionCommand(ReportDragNDrop.INSERT_AFTER);
192: dragNdrop.add(item);
193: item = new JMenuItem(JMeterUtils
194: .getResString("Add as Child"));
195: item.addActionListener(actionHandler);
196: item.setActionCommand(ReportDragNDrop.ADD);
197: dragNdrop.add(item);
198: dragNdrop.addSeparator();
199: item = new JMenuItem(JMeterUtils.getResString("Cancel"));
200: dragNdrop.add(item);
201: displayPopUp(e, dragNdrop);
202: } else {
203: ReportGuiPackage.getInstance().getMainFrame().repaint();
204: }
205: dragging = false;
206: }
207:
208: public ReportTreeNode[] getDraggedNodes() {
209: return draggedNodes;
210: }
211:
212: /**
213: * Tests if the node is being dragged into one of it's own sub-nodes, or
214: * into itself.
215: */
216: private boolean isValidDragAction(ReportTreeNode[] source,
217: ReportTreeNode dest) {
218: boolean isValid = true;
219: TreeNode[] path = dest.getPath();
220: for (int i = 0; i < path.length; i++) {
221: if (contains(source, path[i])) {
222: isValid = false;
223: }
224: }
225: return isValid;
226: }
227:
228: public void mouseEntered(MouseEvent e) {
229: }
230:
231: private void changeSelectionIfDragging(MouseEvent e) {
232: if (dragging) {
233: ReportGuiPackage.getInstance().getMainFrame()
234: .drawDraggedComponent(dragIcon, e.getX(), e.getY());
235: if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
236: currentPath = tree.getPathForLocation(e.getX(), e
237: .getY());
238: if (!contains(draggedNodes, getCurrentNode())) {
239: tree.setSelectionPath(currentPath);
240: }
241: }
242: }
243: }
244:
245: private boolean contains(Object[] container, Object item) {
246: for (int i = 0; i < container.length; i++) {
247: if (container[i] == item) {
248: return true;
249: }
250: }
251: return false;
252: }
253:
254: public void mousePressed(MouseEvent e) {
255: // Get the Main Frame.
256: ReportMainFrame mainFrame = ReportGuiPackage.getInstance()
257: .getMainFrame();
258: // Close any Main Menu that is open
259: mainFrame.closeMenu();
260: int selRow = tree.getRowForLocation(e.getX(), e.getY());
261: if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
262: log.debug("mouse pressed, updating currentPath");
263: currentPath = tree.getPathForLocation(e.getX(), e.getY());
264: }
265: if (selRow != -1) {
266: // updateMainMenu(((JMeterGUIComponent)
267: // getCurrentNode().getUserObject()).createPopupMenu());
268: if (isRightClick(e)) {
269: if (tree.getSelectionCount() < 2) {
270: tree.setSelectionPath(currentPath);
271: }
272: if (getCurrentNode() instanceof ReportTreeNode) {
273: log.debug("About to display pop-up");
274: displayPopUp(e);
275: }
276: }
277: }
278: }
279:
280: public void mouseDragged(MouseEvent e) {
281: if (!dragging) {
282: dragging = true;
283: draggedNodes = getSelectedNodes();
284: if (draggedNodes[0].getUserObject() instanceof ReportGui) {
285: dragging = false;
286: }
287:
288: }
289: changeSelectionIfDragging(e);
290: }
291:
292: public void mouseMoved(MouseEvent e) {
293: }
294:
295: public void mouseExited(MouseEvent ev) {
296: }
297:
298: public void keyPressed(KeyEvent e) {
299: }
300:
301: public void keyReleased(KeyEvent e) {
302: }
303:
304: public void keyTyped(KeyEvent e) {
305: }
306:
307: private boolean isRightClick(MouseEvent e) {
308: return (MouseEvent.BUTTON2_MASK & e.getModifiers()) > 0
309: || (MouseEvent.BUTTON3_MASK == e.getModifiers());
310: }
311:
312: /*
313: * NOTUSED private void updateMainMenu(JPopupMenu menu) { try { MainFrame
314: * mainFrame = GuiPackage.getInstance().getMainFrame();
315: * mainFrame.setEditMenu(menu); } catch (NullPointerException e) {
316: * log.error("Null pointer: JMeterTreeListener.updateMenuItem()", e);
317: * log.error("", e); } }
318: */
319:
320: private void displayPopUp(MouseEvent e) {
321: JPopupMenu pop = getCurrentNode().createPopupMenu();
322: ReportGuiPackage.getInstance().displayPopUp(e, pop);
323: }
324:
325: private void displayPopUp(MouseEvent e, JPopupMenu popup) {
326: log.warn("Shouldn't be here");
327: if (popup != null) {
328: popup.pack();
329: popup.show(tree, e.getX(), e.getY());
330: popup.setVisible(true);
331: popup.requestFocus();
332: }
333: }
334: }
|