1/* 2 * Copyright (c) 2008, 2015, 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 */ 24package com.sun.hotspot.igv.view.widgets; 25 26import com.sun.hotspot.igv.graph.Figure; 27import com.sun.hotspot.igv.graph.OutputSlot; 28import com.sun.hotspot.igv.graph.Slot; 29import com.sun.hotspot.igv.util.DoubleClickHandler; 30import com.sun.hotspot.igv.view.DiagramScene; 31import java.awt.Color; 32import java.awt.Font; 33import java.awt.Graphics2D; 34import java.awt.Rectangle; 35import java.awt.geom.Rectangle2D; 36import java.util.HashSet; 37import java.util.Set; 38import org.netbeans.api.visual.action.WidgetAction; 39import org.netbeans.api.visual.model.ObjectState; 40import org.netbeans.api.visual.widget.Widget; 41 42/** 43 * 44 * @author Thomas Wuerthinger 45 */ 46public abstract class SlotWidget extends Widget implements DoubleClickHandler { 47 48 private Slot slot; 49 private FigureWidget figureWidget; 50 private static double TEXT_ZOOM_FACTOR = 0.9; 51 private static double ZOOM_FACTOR = 0.6; 52 private DiagramScene diagramScene; 53 54 public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) { 55 super(scene); 56 this.diagramScene = scene; 57 this.slot = slot; 58 figureWidget = fw; 59 this.setToolTipText("<HTML>" + slot.getToolTipText() + "</HTML>"); 60 this.setCheckClipping(true); 61 parent.addChild(this); 62 63 //this.setPreferredBounds(this.calculateClientArea()); 64 } 65 66 @Override 67 protected void notifyStateChanged(ObjectState previousState, ObjectState state) { 68 super.notifyStateChanged(previousState, state); 69 repaint(); 70 } 71 72 public Slot getSlot() { 73 return slot; 74 } 75 76 public FigureWidget getFigureWidget() { 77 return figureWidget; 78 } 79 80 @Override 81 protected void paintWidget() { 82 83 if (getScene().getZoomFactor() < ZOOM_FACTOR) { 84 return; 85 } 86 87 Graphics2D g = this.getGraphics(); 88 // g.setColor(Color.DARK_GRAY); 89 int w = this.getBounds().width; 90 int h = this.getBounds().height; 91 92 if (getSlot().getSource().getSourceNodes().size() > 0) { 93 final int SMALLER = 0; 94 g.setColor(getSlot().getColor()); 95 96 int FONT_OFFSET = 2; 97 98 int s = h - SMALLER; 99 int rectW = s; 100 101 Font font = this.getSlot().getFigure().getDiagram().getSlotFont(); 102 if (this.getState().isSelected()) { 103 font = font.deriveFont(Font.BOLD); 104 } 105 106 if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) { 107 g.setFont(font); 108 Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g); 109 rectW = (int) r1.getWidth() + FONT_OFFSET * 2; 110 } 111 g.fillRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1); 112 113 if (this.getState().isHighlighted()) { 114 g.setColor(Color.BLUE); 115 } else { 116 g.setColor(Color.BLACK); 117 } 118 g.drawRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1); 119 120 if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) { 121 Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g); 122 g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent() - 1);//(int) (r1.getHeight())); 123 } 124 125 } else { 126 127 if (this.getSlot().getConnections().isEmpty()) { 128 if (this.getState().isHighlighted()) { 129 g.setColor(Color.BLUE); 130 } else { 131 g.setColor(Color.BLACK); 132 } 133 int r = 2; 134 if (slot instanceof OutputSlot) { 135 g.fillOval(w / 2 - r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2 * r, 2 * r); 136 } else { 137 g.fillOval(w / 2 - r, Figure.SLOT_START - r, 2 * r, 2 * r); 138 } 139 } else { 140 // Do not paint a slot with connections. 141 } 142 } 143 } 144 145 @Override 146 protected Rectangle calculateClientArea() { 147 return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH); 148 } 149 150 protected abstract int calculateSlotWidth(); 151 152 protected int calculateWidth(int count) { 153 return getFigureWidget().getFigure().getWidth() / count; 154 } 155 156 @Override 157 public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) { 158 Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes()); 159 if (diagramScene.isAllVisible()) { 160 hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes()); 161 } 162 163 boolean progress = false; 164 for (Figure f : diagramScene.getModel().getDiagramToView().getFigures()) { 165 for (Slot s : f.getSlots()) { 166 if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) { 167 progress = true; 168 hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet()); 169 } 170 } 171 } 172 173 if (progress) { 174 this.diagramScene.getModel().showNot(hiddenNodes); 175 } 176 } 177} 178