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: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.ui.components;
042:
043: import org.netbeans.lib.profiler.ui.UIConstants;
044: import org.netbeans.lib.profiler.ui.UIUtils;
045: import org.netbeans.lib.profiler.ui.components.tree.TreeCellRendererPersistent;
046: import java.awt.BorderLayout;
047: import java.awt.Component;
048: import java.awt.Dimension;
049: import java.awt.Graphics;
050: import java.awt.Graphics2D;
051: import java.awt.Point;
052: import java.awt.Rectangle;
053: import java.awt.event.MouseEvent;
054: import java.awt.event.MouseListener;
055: import java.awt.event.MouseMotionListener;
056: import java.awt.image.BufferedImage;
057: import javax.swing.BorderFactory;
058: import javax.swing.JComponent;
059: import javax.swing.JToolTip;
060: import javax.swing.JTree;
061: import javax.swing.SwingUtilities;
062: import javax.swing.tree.TreeCellRenderer;
063: import javax.swing.tree.TreePath;
064:
065: /**
066: *
067: * @author Jiri Sedlacek
068: */
069: public class JExtendedTree extends JTree implements CellTipAware {
070: //~ Inner Classes ------------------------------------------------------------------------------------------------------------
071:
072: private class PrivateComponentListener implements MouseListener,
073: MouseMotionListener {
074: //~ Methods --------------------------------------------------------------------------------------------------------------
075:
076: public void mouseClicked(MouseEvent e) {
077: }
078:
079: public void mouseDragged(MouseEvent e) {
080: }
081:
082: public void mouseEntered(MouseEvent e) {
083: // --- CellTip support ------------------
084: CellTipManager.sharedInstance().setEnabled(false);
085: }
086:
087: public void mouseExited(MouseEvent e) {
088: // --- CellTip support ------------------
089: // Return if mouseExit occured because of showing heavyweight celltip
090: if (contains(e.getPoint()) && cellTip.isShowing()) {
091: return;
092: }
093:
094: CellTipManager.sharedInstance().setEnabled(false);
095: lastTreePath = null;
096: }
097:
098: public void mouseMoved(MouseEvent e) {
099: // --- CellTip support ------------------
100: processCellTipMouseMove(e);
101: }
102:
103: public void mousePressed(MouseEvent e) {
104: }
105:
106: public void mouseReleased(MouseEvent e) {
107: }
108: }
109:
110: //~ Instance fields ----------------------------------------------------------------------------------------------------------
111:
112: protected JToolTip cellTip;
113: protected Rectangle rendererRect;
114: protected TreePath lastTreePath = null;
115: private PrivateComponentListener componentListener = new PrivateComponentListener();
116:
117: //~ Constructors -------------------------------------------------------------------------------------------------------------
118:
119: /** Creates a new instance of JExtendedTree */
120: public JExtendedTree() {
121: addMouseListener(componentListener);
122: addMouseMotionListener(componentListener);
123:
124: setRowHeight(UIUtils.getDefaultRowHeight()); // celltips require to have row height initialized!
125:
126: // --- CellTip support ------------------
127: cellTip = createCellTip();
128: cellTip.setBackground(getBackground());
129: cellTip
130: .setBorder(BorderFactory
131: .createLineBorder(UIConstants.TABLE_VERTICAL_GRID_COLOR));
132: cellTip.setLayout(new BorderLayout());
133:
134: CellTipManager.sharedInstance().registerComponent(this );
135: }
136:
137: //~ Methods ------------------------------------------------------------------------------------------------------------------
138:
139: public JToolTip getCellTip() {
140: return cellTip;
141: }
142:
143: public Point getCellTipLocation() {
144: if (rendererRect == null) {
145: return null;
146: }
147:
148: return new Point(rendererRect.getLocation().x - 1, rendererRect
149: .getLocation().y - 1);
150: }
151:
152: public void processMouseEvent(MouseEvent e) {
153: super .processMouseEvent(e);
154: }
155:
156: protected JToolTip createCellTip() {
157: return new JToolTip();
158: }
159:
160: protected void processCellTipMouseMove(MouseEvent e) {
161: // Identify treetable row and column at cursor
162: TreePath currentTreePath = getPathForLocation(e.getX(), e
163: .getY());
164:
165: // Return if treetable cell is the same as in previous event
166: if (currentTreePath == lastTreePath) {
167: return;
168: }
169:
170: lastTreePath = currentTreePath;
171:
172: // Return if cursor isn't at any cell
173: if (lastTreePath == null) {
174: CellTipManager.sharedInstance().setEnabled(false);
175:
176: return;
177: }
178:
179: Component cellRenderer;
180: Component cellRendererPersistent;
181: int row = getRowForPath(lastTreePath);
182:
183: TreeCellRenderer treeCellRenderer = getCellRenderer();
184:
185: if (!(treeCellRenderer instanceof TreeCellRendererPersistent)) {
186: return;
187: }
188:
189: cellRenderer = treeCellRenderer.getTreeCellRendererComponent(
190: JExtendedTree.this ,
191: lastTreePath.getLastPathComponent(), false,
192: isExpanded(row), getModel().isLeaf(
193: lastTreePath.getLastPathComponent()), row,
194: false);
195: cellRendererPersistent = ((TreeCellRendererPersistent) treeCellRenderer)
196: .getTreeCellRendererComponentPersistent(
197: JExtendedTree.this , lastTreePath
198: .getLastPathComponent(), false,
199: isExpanded(row), getModel().isLeaf(
200: lastTreePath.getLastPathComponent()),
201: row, false);
202:
203: // Return if celltip is not supported for the cell
204: if (cellRenderer == null) {
205: CellTipManager.sharedInstance().setEnabled(false);
206:
207: return;
208: }
209:
210: Point cellStart = getPathBounds(lastTreePath).getLocation();
211: rendererRect = new Rectangle(cellStart.x, cellStart.y,
212: cellRenderer.getPreferredSize().width, cellRenderer
213: .getPreferredSize().height + 2);
214:
215: if (!rendererRect.contains(e.getPoint())) {
216: CellTipManager.sharedInstance().setEnabled(false);
217:
218: return;
219: }
220:
221: // Return if cell contents is fully visible
222: Rectangle visibleRect = getVisibleRect();
223:
224: if ((rendererRect.x >= visibleRect.x)
225: && ((rendererRect.x + rendererRect.width) <= (visibleRect.x + visibleRect.width))) {
226: CellTipManager.sharedInstance().setEnabled(false);
227:
228: return;
229: }
230:
231: while (cellTip.getComponentCount() > 0) {
232: cellTip.remove(0);
233: }
234:
235: cellTip.add(cellRendererPersistent, BorderLayout.CENTER);
236: cellTip.setPreferredSize(new Dimension(cellRendererPersistent
237: .getPreferredSize().width + 2, getRowHeight() + 2));
238:
239: CellTipManager.sharedInstance().setEnabled(true);
240: }
241: }
|