comparison visualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java @ 4512:015fb895586b

Moved visualizer to new directory.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 07 Feb 2012 22:41:09 +0100
parents
children
comparison
equal deleted inserted replaced
4511:6cb549627941 4512:015fb895586b
1 /*
2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24 package com.sun.hotspot.igv.view.widgets;
25
26 import com.sun.hotspot.igv.data.Properties;
27 import com.sun.hotspot.igv.graph.Figure;
28 import com.sun.hotspot.igv.util.DoubleClickAction;
29 import com.sun.hotspot.igv.util.DoubleClickHandler;
30 import com.sun.hotspot.igv.util.PropertiesSheet;
31 import com.sun.hotspot.igv.view.scene.DiagramScene;
32 import java.awt.*;
33 import java.util.ArrayList;
34 import java.util.HashSet;
35 import java.util.Set;
36 import javax.swing.Action;
37 import javax.swing.BorderFactory;
38 import javax.swing.JMenu;
39 import javax.swing.JPopupMenu;
40 import javax.swing.event.MenuEvent;
41 import javax.swing.event.MenuListener;
42 import org.netbeans.api.visual.action.PopupMenuProvider;
43 import org.netbeans.api.visual.action.WidgetAction;
44 import org.netbeans.api.visual.layout.LayoutFactory;
45 import org.netbeans.api.visual.model.ObjectState;
46 import org.netbeans.api.visual.widget.LabelWidget;
47 import org.netbeans.api.visual.widget.Widget;
48 import org.openide.nodes.AbstractNode;
49 import org.openide.nodes.Children;
50 import org.openide.nodes.Node;
51 import org.openide.nodes.Sheet;
52
53 /**
54 *
55 * @author Thomas Wuerthinger
56 */
57 public class FigureWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler {
58
59 public static final boolean VERTICAL_LAYOUT = true;
60 //public static final int MAX_STRING_LENGTH = 20;
61 private static final double LABEL_ZOOM_FACTOR = 0.3;
62 private static final double ZOOM_FACTOR = 0.1;
63 private Font font;
64 private Font boldFont;
65 private Figure figure;
66 private Widget leftWidget;
67 private Widget rightWidget;
68 private Widget middleWidget;
69 private ArrayList<LabelWidget> labelWidgets;
70 private DiagramScene diagramScene;
71 private boolean boundary;
72 private Node node;
73 private Widget dummyTop;
74
75 public void setBoundary(boolean b) {
76 boundary = b;
77 }
78
79 public boolean isBoundary() {
80 return boundary;
81 }
82
83 public Node getNode() {
84 return node;
85 }
86
87 @Override
88 public boolean isHitAt(Point localLocation) {
89 return middleWidget.isHitAt(localLocation);
90 }
91
92
93 public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) {
94
95 super(scene);
96
97 assert this.getScene() != null;
98 assert this.getScene().getView() != null;
99
100 this.figure = f;
101 font = f.getDiagram().getFont();
102 boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD);
103 this.setCheckClipping(true);
104 this.diagramScene = scene;
105 parent.addChild(this);
106
107 Widget outer = new Widget(scene);
108 outer.setBackground(f.getColor());
109 outer.setLayout(LayoutFactory.createOverlayLayout());
110
111 middleWidget = new Widget(scene);
112 middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0));
113 middleWidget.setBackground(f.getColor());
114 middleWidget.setOpaque(true);
115 //middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
116 middleWidget.getActions().addAction(new DoubleClickAction(this));
117 middleWidget.setCheckClipping(true);
118
119 labelWidgets = new ArrayList<>();
120
121 String[] strings = figure.getLines();
122
123 dummyTop = new Widget(scene);
124 dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
125 middleWidget.addChild(dummyTop);
126
127
128 for (String cur : strings) {
129
130 String displayString = cur;
131
132 LabelWidget lw = new LabelWidget(scene);
133 labelWidgets.add(lw);
134 middleWidget.addChild(lw);
135 lw.setLabel(displayString);
136 lw.setFont(font);
137 lw.setForeground(Color.BLACK);
138 lw.setAlignment(LabelWidget.Alignment.CENTER);
139 lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
140 lw.setBorder(BorderFactory.createEmptyBorder());
141 }
142
143 Widget dummyBottom = new Widget(scene);
144 dummyBottom.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
145 middleWidget.addChild(dummyBottom);
146
147 middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight()));
148 //outer.addChild(middleWidget);
149 this.addChild(middleWidget);
150
151 // Initialize node for property sheet
152 node = new AbstractNode(Children.LEAF) {
153
154 @Override
155 protected Sheet createSheet() {
156 Sheet s = super.createSheet();
157 PropertiesSheet.initializeSheet(f.getProperties(), s);
158 return s;
159 }
160 };
161 node.setDisplayName(getName());
162 }
163
164 public Widget getLeftWidget() {
165 return leftWidget;
166 }
167
168 public Widget getRightWidget() {
169 return rightWidget;
170 }
171
172 @Override
173 protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
174 super.notifyStateChanged(previousState, state);
175
176 Color borderColor = Color.BLACK;
177 Color innerBorderColor = getFigure().getColor();
178 int thickness = 1;
179 boolean repaint = false;
180 Font f = font;
181 if (state.isSelected() || state.isHighlighted()) {
182 thickness = 2;
183 }
184 if(state.isSelected()) {
185 f = boldFont;
186 innerBorderColor = borderColor;
187 } else {
188 }
189
190 if (state.isHighlighted()) {
191 innerBorderColor = borderColor = Color.BLUE;
192 repaint = true;
193 } else {
194 repaint = true;
195 }
196
197 if (state.isHovered() != previousState.isHovered()) {
198
199 /*
200 if (state.isHovered()) {
201 diagramScene.addAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
202 } else {
203 diagramScene.removeAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
204 }*/
205 repaint = true;
206 }
207
208 if (state.isSelected() != previousState.isSelected()) {
209 repaint = true;
210 }
211
212 if (repaint) {
213 middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1)));
214 for (LabelWidget labelWidget : labelWidgets) {
215 labelWidget.setFont(f);
216 }
217 repaint();
218 }
219 }
220
221 public String getName() {
222 return getProperties().get("name");
223 }
224
225 @Override
226 public Properties getProperties() {
227 return figure.getProperties();
228 }
229
230 public Figure getFigure() {
231 return figure;
232 }
233
234 @Override
235 protected void paintChildren() {
236 Composite oldComposite = null;
237 if (boundary) {
238 oldComposite = getScene().getGraphics().getComposite();
239 float alpha = DiagramScene.ALPHA;
240 this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
241 }
242
243 if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) {
244
245 for (LabelWidget labelWidget : labelWidgets) {
246 labelWidget.setVisible(false);
247 }
248 super.paintChildren();
249 for (LabelWidget labelWidget : labelWidgets) {
250 labelWidget.setVisible(true);
251 }
252
253 } else {
254 super.paintChildren();
255 }
256
257 if (boundary) {
258 getScene().getGraphics().setComposite(oldComposite);
259 }
260 }
261
262 @Override
263 public JPopupMenu getPopupMenu(Widget widget, Point point) {
264 JPopupMenu menu = diagramScene.createPopupMenu();
265 menu.addSeparator();
266
267 JMenu predecessors = new JMenu("Nodes Above");
268 predecessors.addMenuListener(new NeighborMenuListener(predecessors, getFigure(), false));
269 menu.add(predecessors);
270
271 JMenu successors = new JMenu("Nodes Below");
272 successors.addMenuListener(new NeighborMenuListener(successors, getFigure(), true));
273 menu.add(successors);
274
275 return menu;
276 }
277
278 /**
279 * Builds the submenu for a figure's neighbors on demand.
280 */
281 private class NeighborMenuListener implements MenuListener {
282
283 private final JMenu menu;
284 private final Figure figure;
285 private final boolean successors;
286
287 public NeighborMenuListener(JMenu menu, Figure figure, boolean successors) {
288 this.menu = menu;
289 this.figure = figure;
290 this.successors = successors;
291 }
292
293 @Override
294 public void menuSelected(MenuEvent e) {
295 if (menu.getItemCount() > 0) {
296 // already built before
297 return;
298 }
299
300 Set<Figure> set = figure.getPredecessorSet();
301 if (successors) {
302 set = figure.getSuccessorSet();
303 }
304
305 boolean first = true;
306 for (Figure f : set) {
307 if (f == figure) {
308 continue;
309 }
310
311 if (first) {
312 first = false;
313 } else {
314 menu.addSeparator();
315 }
316
317 Action go = diagramScene.createGotoAction(f);
318 menu.add(go);
319
320 JMenu preds = new JMenu("Nodes Above");
321 preds.addMenuListener(new NeighborMenuListener(preds, f, false));
322 menu.add(preds);
323
324 JMenu succs = new JMenu("Nodes Below");
325 succs.addMenuListener(new NeighborMenuListener(succs, f, true));
326 menu.add(succs);
327 }
328
329 if (menu.getItemCount() == 0) {
330 menu.add("(none)");
331 }
332 }
333
334 @Override
335 public void menuDeselected(MenuEvent e) {
336 // ignore
337 }
338
339 @Override
340 public void menuCanceled(MenuEvent e) {
341 // ignore
342 }
343 }
344
345 @Override
346 public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
347
348 if (diagramScene.isAllVisible()) {
349 final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
350 hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
351 this.diagramScene.getModel().showNot(hiddenNodes);
352 } else if (isBoundary()) {
353
354 final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
355 hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
356 this.diagramScene.getModel().showNot(hiddenNodes);
357 } else {
358 final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
359 hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
360 this.diagramScene.getModel().showNot(hiddenNodes);
361 }
362 }
363 }