1 package org.glassbox.graphview;
2
3 import org.glassbox.gui.*;
4
5 import de.fzi.wim.guibase.graphview.layout.*;
6 import de.fzi.wim.guibase.graphview.graph.Graph;
7
8 import java.beans.PropertyChangeListener;
9 import java.beans.PropertyChangeEvent;
10
11 /***
12 Abstract implementation of a manager for the graph layout.
13 Must be member of a <code>GraphGroup</code>.
14 Subclasses must implement the method <code>createLayoutStrategy(Graph graph)</code>
15 to create the desired <code>LayoutStrategy</code> for a new graph.
16 */
17 public abstract class AbstractGraphLayoutManager extends AbstractMember implements PropertyChangeListener {
18 public static final String IDENTIFIER = "glassbox.GraphGroup";
19
20 private Layouter _layouter;
21
22 public AbstractGraphLayoutManager() {
23 _layouter = null;
24 }
25
26 /***
27 Get the layouter, maybe <code>null</code> if the graph of this member's <code>GraphGroup</code> is <code>null</code>.
28 */
29 protected Layouter getLayouter() {
30 return _layouter;
31 }
32
33 /***
34 Get the graph pane, maybe <code>null</code> if the instance is currently not member of a <code>GraphGroup</code>.
35 */
36 protected GGraphPane getGraphPane() {
37 if (getGroup()!=null) {
38 return ((GraphGroup)getGroup()).getGraphPane();
39 } else {
40 return null;
41 }
42 }
43
44 /***
45 Get the current layouted graph, maybe <code>null</code> if the instance is currently not member of a <code>GraphGroup</code> or
46 if the group's graph is <code>null</code>.
47 */
48 protected Graph getGraph() {
49 if (getGroup()!=null) {
50 return ((GraphGroup)getGroup()).getGraph();
51 } else {
52 return null;
53 }
54 }
55
56 /***
57 Notify the instance that a new graph should be layouted.
58 */
59 protected void notifyNewGraph(Graph graph) {
60 if (_layouter!=null) {
61 _layouter.stop();
62 _layouter = null;
63 }
64 if (graph!=null) {
65 _layouter = new Layouter(createLayoutStrategy(graph));
66 _layouter.start();
67 }
68 }
69
70 /***
71 Create the layout strategy for a new graph. Must be implemented by subclasses.
72 */
73 protected abstract LayoutStrategy createLayoutStrategy(Graph graph);
74
75 public void propertyChange(PropertyChangeEvent e) {
76 if ("graph".equals(e.getPropertyName())) {
77 notifyNewGraph((Graph)e.getNewValue());
78 }
79 }
80
81 /***
82 Get a unique identifier of the member.
83 */
84 public String getIdentifier() {
85 return IDENTIFIER;
86 }
87
88 /***
89 Sets the group of this member. This method will usually be called by the group itself when this member is added to or removed from it.
90 @exception IllegalArgumentException If <code>group</code> is not an instance of <code>GraphGroup</code>.
91 */
92 public void setGroup(Group group) throws IllegalArgumentException {
93 if (!(group instanceof GraphGroup || group == null))
94 throw new IllegalArgumentException("GraphLayoutManager must be member of a GraphGroup.");
95
96 if (getGraphPane()!=null) {
97 getGraphPane().removePropertyChangeListener(this);
98 }
99
100 super.setGroup(group);
101
102 notifyNewGraph(getGraph());
103 if (getGraphPane()!=null) {
104 getGraphPane().addPropertyChangeListener(this);
105 }
106 }
107
108 /***
109 Called by this member's group if a property of the group changed.
110 */
111 public void groupPropertyChanged(String name, Object oldvalue, Object newvalue) {
112 if (name.equals(Group.APPLICATION_STATUS_KEY)) {
113 if (Group.PAUSED.equals(newvalue)) {
114 if (_layouter!=null) _layouter.stop();
115 } else if (Group.RUNNING.equals(newvalue)) {
116 if (_layouter!=null) _layouter.start();
117 } else if (Group.EXITING.equals(newvalue)) {
118 if (_layouter!=null) _layouter.stop();
119 }
120 }
121 }
122 }