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.palette.ui;
042:
043: import java.awt.Component;
044: import java.awt.Graphics;
045: import java.awt.Rectangle;
046: import java.awt.geom.Line2D;
047:
048: import java.util.HashMap;
049:
050: import javax.swing.JComponent;
051: import javax.swing.JPanel;
052: import javax.swing.JTree;
053:
054: /**
055: * Glass pane which is used for paint of a drop line over <code>JComponent</code>.
056: *
057: * @author Jiri Rechtacek, S. Aubrecht
058: *
059: * @see java.awt.dnd.DropTarget
060: * @see org.openide.explorer.view.TreeViewDropSupport
061: */
062: final class DropGlassPane extends JPanel {
063: static private HashMap<Integer, DropGlassPane> map = new HashMap<Integer, DropGlassPane>();
064: final static private int MIN_X = 0;//5;
065: final static private int MIN_Y = 0;//3;
066: final static private int MIN_WIDTH = 0;//10;
067: final static private int MIN_HEIGTH = 0;//3;
068: static private Component oldPane;
069: static private JComponent originalSource;
070: static private boolean wasVisible;
071: Line2D line = null;
072: Rectangle prevLineRect = null;
073:
074: private DropGlassPane() {
075: }
076:
077: /** Check the bounds of given line with the bounds of this pane. Optionally
078: * calculate the new bounds in current pane's boundary.
079: * @param comp
080: * @return */
081: synchronized static public DropGlassPane getDefault(JComponent comp) {
082: Integer id = Integer.valueOf(System.identityHashCode(comp));
083:
084: if ((map.get(id)) == null) {
085: DropGlassPane dgp = new DropGlassPane();
086: dgp.setOpaque(false);
087: map.put(id, dgp);
088: }
089:
090: return map.get(id);
091: }
092:
093: /** Stores the original glass pane on given tree.
094: * @param source the active container
095: * @param pane the original glass
096: * @param visible was glass pane visible
097: */
098: static void setOriginalPane(JComponent source, Component pane,
099: boolean visible) {
100: // pending, should throw an exception that original is set already
101: oldPane = pane;
102: originalSource = source;
103: wasVisible = visible;
104: }
105:
106: /** Is any original glass pane stored?
107: * @return true if true; false otherwise
108: */
109: static boolean isOriginalPaneStored() {
110: return oldPane != null;
111: }
112:
113: /** Sets the original glass pane to the root pane of stored container.
114: */
115: static void putBackOriginal() {
116: if (oldPane == null) {
117: // pending, should throw an exception
118: return;
119: }
120:
121: originalSource.getRootPane().setGlassPane(oldPane);
122: oldPane.setVisible(wasVisible);
123: oldPane = null;
124: }
125:
126: /** Unset drop line if setVisible to false.
127: * @param boolean aFlag new state */
128: public void setVisible(boolean aFlag) {
129: super .setVisible(aFlag);
130:
131: if (!aFlag) {
132: setDropLine(null);
133: }
134: }
135:
136: /** Set drop line. Given line is used by paint method.
137: * @param line drop line */
138: public void setDropLine(Line2D line) {
139: if (!isValid())
140: return;
141:
142: if (null != prevLineRect
143: && ((null != line && (!prevLineRect.contains(line
144: .getP1()) || !prevLineRect.contains(line
145: .getP2()))) || null == line)) {
146:
147: repaint(prevLineRect);
148: }
149:
150: this .line = line;
151: Rectangle newLineRect = null;
152: if (null != this .line) {
153: checkLineBounds(this .line);
154: newLineRect = line.getBounds();
155: newLineRect.grow(5, 5);
156: }
157:
158: if (null != newLineRect && !newLineRect.equals(prevLineRect)) {
159: repaint(newLineRect);
160: }
161: prevLineRect = newLineRect;
162: }
163:
164: /** Check the bounds of given line with the bounds of this pane. Optionally
165: * calculate the new bounds in current pane's boundary.
166: * @param line a line for check
167: * @return a line with bounds inside the pane's boundary */
168: private Line2D checkLineBounds(Line2D line) {
169: Rectangle bounds = getBounds();
170: double startPointX;
171: double startPointY;
172: double endPointX;
173: double endPointY;
174:
175: // check start point
176: startPointX = Math.max(line.getX1(), bounds.x + MIN_X);
177: startPointY = Math.max(line.getY1(), bounds.y + MIN_Y);
178:
179: // check end point
180: endPointX = Math.min(line.getX2(), (bounds.x + bounds.width));// - MIN_WIDTH);
181: endPointY = Math.min(line.getY2(), (bounds.y + bounds.height)
182: - MIN_HEIGTH);
183:
184: // set new bounds
185: line.setLine(startPointX, startPointY, endPointX, endPointY);
186:
187: return line;
188: }
189:
190: /** Paint drop line on glass pane.
191: * @param Graphics g Obtained graphics */
192: public void paint(Graphics g) {
193: if (line != null) {
194:
195: int x1 = (int) line.getX1();
196: int x2 = (int) line.getX2();
197: int y1 = (int) line.getY1();
198: int y2 = (int) line.getY2();
199:
200: if (y1 == y2) {
201: // LINE
202: g.drawLine(x1 + 2, y1, x2 - 2, y1);
203: g.drawLine(x1 + 2, y1 + 1, x2 - 2, y1 + 1);
204:
205: // RIGHT
206: g.drawLine(x1, y1 - 2, x1, y1 + 3);
207: g.drawLine(x1 + 1, y2 - 1, x1 + 1, y1 + 2);
208:
209: // LEFT
210: g.drawLine(x2, y1 - 2, x2, y1 + 3);
211: g.drawLine(x2 - 1, y1 - 1, x2 - 1, y1 + 2);
212: } else {
213: // LINE
214: g.drawLine(x1, y1 + 2, x2, y2 - 2);
215: g.drawLine(x1 + 1, y1 + 2, x2 + 1, y2 - 2);
216:
217: // RIGHT
218: g.drawLine(x1 - 2, y1, x1 + 3, y1);
219: g.drawLine(x1 - 1, y1 + 1, x1 + 2, y1 + 1);
220:
221: // LEFT
222: g.drawLine(x2 - 2, y2, x2 + 3, y2);
223: g.drawLine(x2 - 1, y2 - 1, x2 + 2, y2 - 1);
224: }
225: }
226: }
227: }
|