1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.layout.multipage;
15  
16  import y.base.Edge;
17  import y.base.Node;
18  import y.base.NodeCursor;
19  import y.layout.tree.BalloonLayouter;
20  import y.view.Arrow;
21  import y.view.Graph2D;
22  import y.view.Graph2DView;
23  import y.view.LocalViewCreator;
24  import y.view.NodeRealizer;
25  import y.view.ShapeNodeRealizer;
26  
27  import java.awt.Color;
28  import java.awt.Dimension;
29  import java.awt.EventQueue;
30  import java.beans.PropertyChangeEvent;
31  import java.beans.PropertyChangeListener;
32  import java.util.Comparator;
33  import java.util.Iterator;
34  import java.util.TreeSet;
35  import javax.swing.BorderFactory;
36  
37  
38  /**
39   * Overview component that displays all referenced pages for a given page graph.
40   *
41   */
42  class MultiPageOverview extends Graph2DView {
43    MultiPageOverview(
44            final Graph2DView pageView,
45            final MultiPageGraph2DBuilder pageBuilder
46    ) {
47      setPreferredSize(new Dimension(200, 200));
48      setBorder(BorderFactory.createLineBorder(Color.GRAY));
49  
50      // disable sloppy painting to ensure that labels are always painted
51      // regardless of current zoom level
52      setPaintDetailThreshold(0);
53  
54      getGraph2D().getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
55  
56      // the MultiPageOverviewCreator rebuilds this component's graph each
57      // time the graph of the specified page view is replaced with a new one
58      final MultiPageOverviewCreator creator =
59              new MultiPageOverviewCreator(pageView, this, pageBuilder);
60      pageView.addPropertyChangeListener("Graph2D", new PropertyChangeListener() {
61        public void propertyChange( final PropertyChangeEvent e ) {
62          EventQueue.invokeLater(new Runnable() {
63            public void run() {
64              creator.updateViewGraph();
65            }
66          });
67        }
68      });
69    }
70  
71    /**
72     * Creates a graph that displays all referenced pages for a given page graph. 
73     */
74    private static final class MultiPageOverviewCreator extends LocalViewCreator {
75      private static final Color PAGE_BACKGROUND = new Color(230, 230, 230);
76      private final Graph2DView source;
77      private final Graph2DView target;
78      private final MultiPageGraph2DBuilder pageBuilder;
79  
80      MultiPageOverviewCreator(
81              final Graph2DView source,
82              final Graph2DView target,
83              final MultiPageGraph2DBuilder pageBuilder
84      ) {
85        this.source = source;
86        this.target = target;
87        this.pageBuilder = pageBuilder;
88  
89        // layout algorithm to lay out the multi-page overview graph in a
90        // star-shaped fashion
91        final BalloonLayouter layouter = new BalloonLayouter();
92        layouter.setComparator(new Comparator() {
93          public int compare( final Object o1, final Object o2 ) {
94            final int i1 = ((Edge) o1).index();
95            final int i2 = ((Edge) o2).index();
96            if (i1 < i2) {
97              return 1;
98            } else if (i1 > i2) {
99              return -1;
100           } else {
101             return 0;
102           }
103         }
104       });
105       setLayouter(layouter);
106     }
107 
108     protected void buildViewGraph() {
109       final Graph2D model = getModel();
110       if (model.isEmpty()) {
111         return;
112       }
113 
114       // determine the page represented by the given page graph
115       // as well as all referenced pages
116       final TreeSet pageNos = new TreeSet();
117       int currentPageNo = -1;
118       for (NodeCursor nc = model.nodes(); nc.ok(); nc.next()) {
119         final Node node = nc.node();
120         final int refPageNo = pageBuilder.getReferencedPageNo(node);
121         if (refPageNo > -1) {
122           pageNos.add(new Integer(refPageNo));
123         }
124         if (currentPageNo < 0) {
125           currentPageNo = pageBuilder.getPageNo(node);
126         }
127       }
128 
129       // create nodes for all referenced pages
130       final Graph2D view = getViewGraph();
131       final ShapeNodeRealizer snr = new ShapeNodeRealizer();
132       snr.getLabel().setFontSize(18);
133       snr.setFillColor(PAGE_BACKGROUND);
134       snr.setSize(42, 60);
135       for (Iterator it = pageNos.iterator(); it.hasNext();) {
136         final NodeRealizer page = snr.createCopy();
137         final Integer next = (Integer) it.next();
138         page.setLabelText(Integer.toString(next.intValue() + 1));
139         view.createNode(page);
140       }
141 
142       // create a node for the current page
143       snr.setSize(56, 80);
144       final NodeRealizer currentPage = snr.createCopy();
145       if (currentPageNo > -1) {
146         currentPage.setLabelText(Integer.toString(currentPageNo + 1));
147       }
148 
149       // connect the current page to all referenced pages
150       final Node current = view.createNode(currentPage);
151       for (NodeCursor nc = view.nodes(); nc.ok(); nc.next()) {
152         final Node node = nc.node();
153         if (node != current) {
154           view.createEdge(current, node);
155         }
156       }
157     }
158 
159     public Graph2D getModel() {
160       return source.getGraph2D();
161     }
162 
163     public Graph2D getViewGraph() {
164       return target.getGraph2D();
165     }
166 
167     public Node getModelNode( final Node view ) {
168       return null;
169     }
170 
171     public Node getViewNode( final Node model ) {
172       return null;
173     }
174 
175     public Edge getModelEdge( final Edge view ) {
176       return null;
177     }
178 
179     public Edge getViewEdge( final Edge model ) {
180       return null;
181     }
182   }
183 }
184