View Javadoc

1   package de.fzi.wim.guibase.graphview.layout;
2   
3   import java.util.Collection;
4   
5   import de.fzi.wim.guibase.graphview.graph.*;
6   
7   /***
8    * The layouter applies the layout strategy to the graph in a separate thread,
9    */
10  public class Layouter {
11      /*** The graph that this layouter takes care of. */
12      protected Graph m_graph;
13      /*** The layout strategy for this layouter. */
14      protected LayoutStrategy m_layoutStrategy;
15      /*** The thread of the layouter. */
16      protected Thread m_layouterThread;
17  
18      /***
19       * Creates the layouter.
20       *
21       * @param layoutStrategy            the layout strategy
22       */
23      public Layouter(LayoutStrategy layoutStrategy) {
24          m_layoutStrategy=layoutStrategy;
25          m_graph=m_layoutStrategy.getGraph();
26          m_graph.addGraphListener(new GraphHandler());
27      }
28      /***
29       * Starts the layouter thread.
30       */
31      public synchronized void start() {
32          if (m_layouterThread==null) {
33              m_layouterThread=new LayouterThread();
34              m_layouterThread.start();
35          }
36      }
37      /***
38       * Stops the layouter thread.
39       */
40      public void stop() {
41          Thread layouterThread;
42          synchronized (this) {
43              layouterThread=m_layouterThread;
44              m_layouterThread=null;
45          }
46          if (layouterThread!=null) {
47              layouterThread.interrupt();
48              try {
49                  layouterThread.join();
50              }
51              catch (InterruptedException ignored) {
52              }
53          }
54      }
55  
56      /***
57       * The layouter thread.
58       */
59      protected class LayouterThread extends Thread {
60          public LayouterThread() {
61              super("GraphLayouter");
62              setDaemon(true);
63          }
64          public void run() {
65              synchronized (m_graph) {
66                  m_layoutStrategy.graphContentsChanged();
67                  m_layoutStrategy.notifyGraphLayoutUpdated();
68              }
69              while (true) {
70                  try {
71                      boolean hasMoreSteps=false;
72                      synchronized (m_graph) {
73                          hasMoreSteps=m_layoutStrategy.shouldExecuteStep();
74                          if (hasMoreSteps) {
75                              m_layoutStrategy.executeGraphLayoutStep();
76                              m_graph.notifyLayoutUpdated();
77                          }
78                      }
79                      if (hasMoreSteps)
80                          Thread.sleep(20);
81                      else
82                          synchronized (Layouter.this) {
83                              Layouter.this.wait();
84                          }
85                  }
86                  catch (InterruptedException e) {
87                      break;
88                  }
89                  catch (Throwable shouldntHappen) {
90                      shouldntHappen.printStackTrace();
91                  }
92              }
93          }
94      }
95  
96      /***
97       * The handler for graph events.
98       */
99      protected class GraphHandler implements GraphListener {
100         public void graphLayoutUpdated(Graph graph) {
101             synchronized (m_graph) {
102                 synchronized (Layouter.this) {
103                     if (m_layouterThread!=Thread.currentThread()) {
104                         m_layoutStrategy.notifyGraphLayoutUpdated();
105                         Layouter.this.notifyAll();
106                     }
107                 }
108             }
109         }
110         public void graphUpdated(Graph graph) {
111         }
112         public void graphContentsChanged(Graph graph) {
113             synchronized (m_graph) {
114                 m_layoutStrategy.graphContentsChanged();
115                 notifyGraphChanged();
116             }
117         }
118         public void elementsAdded(Graph graph,Collection nodes,Collection edges) {
119             synchronized (m_graph) {
120                 m_layoutStrategy.elementsAdded(nodes,edges);
121                 notifyGraphChanged();
122             }
123         }
124         public void elementsRemoved(Graph graph,Collection nodes,Collection edges) {
125             synchronized (m_graph) {
126                 m_layoutStrategy.elementsRemoved(nodes,edges);
127                 notifyGraphChanged();
128             }
129         }
130         protected void notifyGraphChanged() {
131             synchronized (Layouter.this) {
132                 m_layoutStrategy.notifyGraphLayoutUpdated();
133                 Layouter.this.notifyAll();
134             }
135         }
136     }
137 }