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-2007 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.visual.widget;
042:
043: import org.netbeans.api.visual.action.WidgetAction;
044: import org.netbeans.api.visual.widget.Scene;
045: import org.netbeans.api.visual.widget.Widget;
046:
047: import javax.swing.*;
048: import javax.swing.border.CompoundBorder;
049: import javax.swing.border.EmptyBorder;
050: import javax.swing.border.LineBorder;
051: import javax.swing.event.AncestorEvent;
052: import javax.swing.event.AncestorListener;
053: import java.awt.*;
054: import java.awt.event.MouseEvent;
055: import java.awt.event.MouseMotionListener;
056: import java.awt.geom.AffineTransform;
057:
058: /**
059: * @author David Kaspar
060: */
061: public class BirdViewWindow extends JWindow implements
062: MouseMotionListener {
063:
064: private Scene scene;
065: private BirdViewComponent birdView;
066:
067: private boolean shown = false;
068: private double zoomFactor = 3.0;
069: private Point scenePoint;
070:
071: private WidgetAction action = new SceneTrackAction();
072: private ViewAncestorListener ancestorListener = new ViewAncestorListener();
073:
074: public BirdViewWindow(final Scene scene) {
075: this .scene = scene;
076: setSize(new Dimension(256, 256));
077: setLayout(new BorderLayout());
078: setAlwaysOnTop(true);
079:
080: JPanel pane = new JPanel();
081: pane.setBorder(new CompoundBorder(
082: new LineBorder(Color.BLACK, 1), new EmptyBorder(1, 1,
083: 1, 1)));
084: pane.setLayout(new BorderLayout());
085: add(pane, BorderLayout.CENTER);
086:
087: birdView = new BirdViewComponent();
088: birdView.setDoubleBuffered(true);
089: pane.add(birdView, BorderLayout.CENTER);
090: }
091:
092: public void invokeShow() {
093: if (scene.getView() == null)
094: return;
095: if (shown)
096: return;
097: shown = true;
098: birdView.addMouseMotionListener(this );
099: scene.getPriorActions().addAction(action);
100: scene.getView().addAncestorListener(ancestorListener);
101: updateForViewPoint(null);
102: }
103:
104: public void invokeHide() {
105: if (!shown)
106: return;
107: shown = false;
108: birdView.removeMouseMotionListener(this );
109: scene.getPriorActions().removeAction(action);
110: scene.getView().removeAncestorListener(ancestorListener);
111: updateForViewPoint(null);
112: }
113:
114: public void invokeRepaint() {
115: birdView.repaint();
116: }
117:
118: public void setZoomFactor(double zoomFactor) {
119: this .zoomFactor = zoomFactor;
120: invokeRepaint();
121: }
122:
123: public void setWindowSize(Dimension size) {
124: Dimension previousSize = getSize();
125: setSize(size);
126: if (isShowing()) {
127: Point location = getLocation();
128: setLocation(location.x + (previousSize.width - size.width)
129: / 2, location.y
130: + (previousSize.height - size.height) / 2);
131: validate();
132: }
133: }
134:
135: private void updateForViewPoint(Point viewPoint) {
136: JComponent view = scene.getView();
137: if (!shown || viewPoint == null
138: || !view.getVisibleRect().contains(viewPoint)) {
139: scenePoint = null;
140: setVisible(false);
141: dispose();
142: return;
143: }
144: scenePoint = scene.convertViewToScene(viewPoint);
145: Point viewOrigin = view.getLocationOnScreen();
146: Dimension size = getSize();
147: setBounds(viewOrigin.x + viewPoint.x - size.width / 2,
148: viewOrigin.y + viewPoint.y - size.height / 2,
149: size.width, size.height);
150: setVisible(true);
151: birdView.repaint();
152: }
153:
154: private void updateForBirdViewPoint(Point birdViewPoint) {
155: JComponent view = scene.getView();
156: if (view.isShowing() && isShowing()) {
157: Point viewOrigin = view.getLocationOnScreen();
158: Point birdViewOrigin = getLocationOnScreen();
159: Dimension size = getSize();
160: updateForViewPoint(new Point(birdViewPoint.x
161: + birdViewOrigin.x - viewOrigin.x, birdViewPoint.y
162: + birdViewOrigin.y - viewOrigin.y));
163: } else
164: updateForViewPoint(null);
165: }
166:
167: public void mouseDragged(MouseEvent e) {
168: updateForBirdViewPoint(e.getPoint());
169: }
170:
171: public void mouseMoved(MouseEvent e) {
172: updateForBirdViewPoint(e.getPoint());
173: }
174:
175: private class SceneTrackAction implements WidgetAction {
176:
177: public State mouseClicked(Widget widget, WidgetMouseEvent event) {
178: return State.CONSUMED;
179: }
180:
181: public State mousePressed(Widget widget, WidgetMouseEvent event) {
182: return State.CONSUMED;
183: }
184:
185: public State mouseReleased(Widget widget, WidgetMouseEvent event) {
186: return State.CONSUMED;
187: }
188:
189: public State mouseEntered(Widget widget, WidgetMouseEvent event) {
190: return State.CONSUMED;
191: }
192:
193: public State mouseExited(Widget widget, WidgetMouseEvent event) {
194: return State.CONSUMED;
195: }
196:
197: public State mouseDragged(Widget widget, WidgetMouseEvent event) {
198: updateForViewPoint(widget.getScene().convertSceneToView(
199: widget.convertLocalToScene(event.getPoint())));
200: return State.CONSUMED;
201: }
202:
203: public State mouseMoved(Widget widget, WidgetMouseEvent event) {
204: updateForViewPoint(widget.getScene().convertSceneToView(
205: widget.convertLocalToScene(event.getPoint())));
206: return State.CONSUMED;
207: }
208:
209: public State mouseWheelMoved(Widget widget,
210: WidgetMouseWheelEvent event) {
211: return State.CONSUMED;
212: }
213:
214: public State keyTyped(Widget widget, WidgetKeyEvent event) {
215: return State.CONSUMED;
216: }
217:
218: public State keyPressed(Widget widget, WidgetKeyEvent event) {
219: return State.CONSUMED;
220: }
221:
222: public State keyReleased(Widget widget, WidgetKeyEvent event) {
223: return State.CONSUMED;
224: }
225:
226: public State focusGained(Widget widget, WidgetFocusEvent event) {
227: return State.CONSUMED;
228: }
229:
230: public State focusLost(Widget widget, WidgetFocusEvent event) {
231: return State.CONSUMED;
232: }
233:
234: public State dragEnter(Widget widget,
235: WidgetDropTargetDragEvent event) {
236: return State.CONSUMED;
237: }
238:
239: public State dragOver(Widget widget,
240: WidgetDropTargetDragEvent event) {
241: return State.CONSUMED;
242: }
243:
244: public State dropActionChanged(Widget widget,
245: WidgetDropTargetDragEvent event) {
246: return State.CONSUMED;
247: }
248:
249: public State dragExit(Widget widget, WidgetDropTargetEvent event) {
250: return State.CONSUMED;
251: }
252:
253: public State drop(Widget widget, WidgetDropTargetDropEvent event) {
254: return State.CONSUMED;
255: }
256:
257: }
258:
259: private class BirdViewComponent extends JComponent {
260:
261: public void paint(Graphics g) {
262: Graphics2D gr = (Graphics2D) g;
263: super .paint(g);
264: if (scenePoint == null) {
265: gr.setColor(Color.BLACK);
266: gr.fill(getBounds());
267: return;
268: }
269: Dimension size = getSize();
270: AffineTransform previousTransform = gr.getTransform();
271: gr.translate(size.width / 2, size.height / 2);
272: gr.scale(zoomFactor, zoomFactor);
273: gr.translate(-scenePoint.x, -scenePoint.y);
274: scene.paint(gr);
275: gr.setTransform(previousTransform);
276: }
277:
278: }
279:
280: private class ViewAncestorListener implements AncestorListener {
281:
282: public void ancestorAdded(AncestorEvent event) {
283: }
284:
285: public void ancestorRemoved(AncestorEvent event) {
286: invokeHide();
287: }
288:
289: public void ancestorMoved(AncestorEvent event) {
290: }
291:
292: }
293:
294: }
|