1
14 package demo.view.hierarchy;
15
16 import y.view.ImageNodePainter;
17 import y.view.GenericNodeRealizer;
18 import y.view.HitInfo;
19 import y.view.Graph2DViewActions;
20 import y.view.ViewMode;
21 import y.view.Graph2D;
22 import y.view.NodeRealizer;
23 import y.view.NodeLabel;
24 import y.view.ShapeNodePainter;
25 import y.view.hierarchy.DefaultGenericAutoBoundsFeature;
26 import y.view.hierarchy.GenericGroupNodeRealizer;
27 import y.view.hierarchy.DefaultHierarchyGraphFactory;
28 import y.view.hierarchy.HierarchyManager;
29 import y.base.Node;
30 import y.geom.YInsets;
31
32 import java.awt.EventQueue;
33 import java.awt.Font;
34 import java.awt.Color;
35 import java.awt.Dimension;
36 import java.awt.geom.Dimension2D;
37 import java.awt.event.ActionEvent;
38 import java.net.URL;
39 import java.util.Locale;
40 import java.util.Map;
41 import javax.swing.ActionMap;
42 import javax.swing.Action;
43
44 import demo.view.DemoBase;
45
46
52 public class CustomGroupVisualizationDemo extends GroupingDemo {
53
56 private static final String CONFIGURATION_GROUP =
57 "CustomGroupVisualizationDemo_GROUP_NODE";
58
61 private static final String CONFIGURATION_FOLDER =
62 "CustomGroupVisualizationDemo_FOLDER_NODE";
63
64 protected void loadInitialGraph() {
65 loadGraph(getClass().getResource("resource/CustomGroupVisualizationDemo.graphml"));
66 }
67
68
72 protected void registerViewModes() {
73 super.registerViewModes();
74 view.addViewMode(new StateChangeViewMode());
75 }
76
77
81 protected void configureDefaultGroupNodeRealizers() {
82 final GenericNodeRealizer.Factory factory = GenericNodeRealizer.getFactory();
83
84 final String resource = "resource/yicon.png";
87 final URL folderUrl = DemoBase.class.getResource(resource);
88 if (folderUrl == null) {
89 throw new IllegalStateException("Could not find \"" + resource + "\".");
90 } else {
91 final ImageNodePainter folderPainter = new ImageNodePainter(folderUrl);
92 final Map map = factory.createDefaultConfigurationMap();
93 map.put(GenericNodeRealizer.Painter.class, folderPainter);
94 map.put(GenericNodeRealizer.ContainsTest.class, folderPainter);
95
96 configureBoundsAndSizeHandling(map);
97
98 factory.addConfiguration(CONFIGURATION_FOLDER, map);
99 }
100
101 final GenericGroupNodeRealizer fnr = new GenericGroupNodeRealizer();
102 fnr.setConfiguration(CONFIGURATION_FOLDER);
103 fnr.setGroupClosed(true);
104 configureDefaultFolderLabel(fnr.getLabel());
105
106
107 {
111 final ShapeNodePainter groupPainter =
112 new ShapeNodePainter(ShapeNodePainter.ROUND_RECT);
113 final Map map = factory.createDefaultConfigurationMap();
114 map.put(GenericNodeRealizer.Painter.class, groupPainter);
115 map.put(GenericNodeRealizer.ContainsTest.class, groupPainter);
116
117 configureBoundsAndSizeHandling(map);
118
119 factory.addConfiguration(CONFIGURATION_GROUP, map);
120 }
121
122 final GenericGroupNodeRealizer gnr = new GenericGroupNodeRealizer();
123 gnr.setFillColor(new Color(202, 227, 255));
124 gnr.setConfiguration(CONFIGURATION_GROUP);
125 gnr.setGroupClosed(false);
126 configureDefaultGroupLabel(gnr.getLabel());
127
128
129 final DefaultHierarchyGraphFactory hgf =
131 (DefaultHierarchyGraphFactory) getHierarchyManager().getGraphFactory();
132 hgf.setProxyNodeRealizerEnabled(true);
133 hgf.setDefaultGroupNodeRealizer(gnr);
134 hgf.setDefaultFolderNodeRealizer(fnr);
135 }
136
137
141 private void configureDefaultFolderLabel( final NodeLabel fnl ) {
142 fnl.setFontSize(14);
143 fnl.setFontStyle(Font.BOLD);
144 fnl.setTextColor(Color.WHITE);
145 fnl.setAutoSizePolicy(NodeLabel.AUTOSIZE_NODE_WIDTH);
146 fnl.setBackgroundColor(new Color(62, 66, 69));
147 fnl.setModel(NodeLabel.SANDWICH);
148 fnl.setPosition(NodeLabel.S);
149 }
150
151
155 private void configureDefaultGroupLabel( final NodeLabel gnl ) {
156 gnl.setFontSize(14);
157 gnl.setFontStyle(Font.BOLD);
158 gnl.setTextColor(Color.WHITE);
159 gnl.setAutoSizePolicy(NodeLabel.AUTOSIZE_CONTENT);
160 gnl.setBackgroundColor(null);
161 gnl.setRotationAngle(270);
162 gnl.setPosition(NodeLabel.BOTTOM_LEFT);
163 }
164
165
170 private void configureBoundsAndSizeHandling( final Map map ) {
171 final DefaultGenericAutoBoundsFeature abf = new DefaultGenericAutoBoundsFeature() {
172
180 public YInsets getAutoBoundsInsets( final NodeRealizer context ) {
181 if (accept(context)) {
182 final YInsets insets =
183 ((GenericGroupNodeRealizer) context).getMinimalInsets();
184 return new YInsets(
185 insets.top,
186 Math.max(insets.left, context.getLabel().getWidth() + 5),
187 insets.bottom,
188 insets.right
189 );
190 }
191
192 return super.getInsets(context);
193 }
194
195
203 protected Dimension2D calculateMinimalLabelSize( final NodeRealizer context ) {
204 if (accept(context)) {
205 final NodeLabel label = context.getLabel();
206 final double d = 2*label.getDistance();
207 return new Dimension(
210 (int) Math.ceil(label.getContentHeight() + d),
211 (int) Math.ceil(label.getContentWidth() + d));
212 }
213
214 return super.calculateMinimalLabelSize(context);
215 }
216
217
224 private boolean accept( final NodeRealizer context ) {
225 if (context instanceof GenericGroupNodeRealizer) {
226 GenericGroupNodeRealizer ggnr = ((GenericGroupNodeRealizer) context);
227 if (ggnr.labelCount() > 0) {
228 final NodeLabel nl = ggnr.getLabel();
229 if (nl.getModel() == NodeLabel.INTERNAL &&
230 nl.getPosition() == NodeLabel.BOTTOM_LEFT &&
231 nl.getRotationAngle() == 270) {
232 return true;
233 }
234 }
235 }
236
237 return false;
238 }
239 };
240 abf.setConsiderNodeLabelSize(true);
241 map.put(GenericGroupNodeRealizer.GenericAutoBoundsFeature.class, abf);
242 map.put(GenericNodeRealizer.GenericSizeConstraintProvider.class, abf);
243 map.put(GenericNodeRealizer.LabelBoundsChangedHandler.class, abf);
244 }
245
246
247
248 public static void main( String[] args ) {
249 EventQueue.invokeLater(new Runnable() {
250 public void run() {
251 Locale.setDefault(Locale.ENGLISH);
252 initLnF();
253 (new CustomGroupVisualizationDemo()).start();
254 }
255 });
256 }
257
258
259
263 private static final class StateChangeViewMode extends ViewMode {
264 public void mouseClicked( final double x, final double y ) {
265 if (lastClickEvent.getClickCount() == 2 &&
266 lastClickEvent.getButton() == 1) {
267 final HitInfo hitInfo = getHitInfo(x, y);
268 if (hitInfo.hasHitNodes()) {
269 final Node node = hitInfo.getHitNode();
270 final Graph2D graph = getGraph2D();
271 final HierarchyManager manager = graph.getHierarchyManager();
272 if (manager != null) {
273 if (manager.isGroupNode(node)) {
274 closeGroup(graph, node);
275 } else if (manager.isFolderNode(node)) {
276 openFolder(graph, node);
277 }
278 }
279 }
280 }
281 }
282
283
288 protected void closeGroup( final Graph2D graph, final Node node ) {
289 Action action = null;
290
291 final ActionMap amap = view.getCanvasComponent().getActionMap();
292 if (amap != null) {
293 action = amap.get(Graph2DViewActions.CLOSE_GROUPS);
294 }
295 if (action == null) {
296 action = new Graph2DViewActions.CloseGroupsAction();
297 }
298
299 view.getGraph2D().unselectAll();
300 view.getGraph2D().setSelected(node, true);
301 action.actionPerformed(new ActionEvent(view, ActionEvent.ACTION_PERFORMED, ""));
302 }
303
304
309 protected void openFolder( final Graph2D graph, final Node node ) {
310 Action action = null;
311
312 final ActionMap amap = view.getCanvasComponent().getActionMap();
313 if (amap != null) {
314 action = amap.get(Graph2DViewActions.OPEN_FOLDERS);
315 }
316 if (action == null) {
317 action = new Graph2DViewActions.OpenFoldersAction();
318 }
319
320 view.getGraph2D().unselectAll();
321 view.getGraph2D().setSelected(node, true);
322 action.actionPerformed(new ActionEvent(view, ActionEvent.ACTION_PERFORMED, ""));
323 }
324 }
325 }
326