My JFrame
containing an embedded single graph (Graphstream) freezes when I try to update it in a loop that calls Thread,sleep(). I have tried using the same update on a standalone-graph (displayed on it's own) and it works as expected.
I have a single graph embedded in JFrame as follows (AppGraph.java):
public static ViewPanel init(){
graph.addAttribute("ui.stylesheet", styleSheet);
graph.setAutoCreate(true);
graph.setStrict(false);
graph.addAttribute("ui.quality");
graph.addAttribute("ui.antialias");
initGraph();
initNodes(graph);
return attachViewPanel();
}
private static ViewPanel attachViewPanel() {
Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
viewer.enableAutoLayout();
return viewer.addDefaultView(false);
}
private static void initGraph(){
FileSource fs = new FileSourceDOT();
String graph_filename = "graph.gv";
String absolute_path = System.getProperty("user.home") + File.separator + graph_filename;
fs.addSink(graph);
try {
fs.readAll(absolute_path);
} catch (IOException | NullPointerException e) {
e.printStackTrace();
} finally {
fs.removeSink(graph);
}
}
Then this is called in the JFrame class as below:
/*AppWindow.java
* Set up graph
*/
GridBagConstraints graphConstraints = new GridBagConstraints();
graphConstraints.fill = GridBagConstraints.BOTH;
graphConstraints.gridx = 0;
graphConstraints.gridy = 1;
graphConstraints.weightx = 0.5;
graphConstraints.weighty = 0.5;
graphConstraints.gridwidth = 4;
graphConstraints.gridheight = GridBagConstraints.RELATIVE;
add(AppGraph.init(), graphConstraints);`
On the JFrame
are buttons for different search algorithms like BFS. During the execution of these algorithms, edges traversed are colored at fixed time intervals to create a sort of animation effect as shown below:
//BFSAlgorithm.java
private void callBFS(Node startNode, Node goalNode) {
startNode.setAttribute("parent", "null");
startNode.setAttribute("level", 0);
startNode.setAttribute("visited?");
LinkedList<Node> queueFrontier = new LinkedList<>();
int level = 1;
queueFrontier.addLast(startNode);
while (!queueFrontier.isEmpty()) {
System.out.println("Level: " + (level - 1));
LinkedList<Node> next = new LinkedList<>();
for (Node node : queueFrontier) {
if (node == goalNode) {
System.out.println(node.getId() + ": Found Found Found!!!");
if (node != startNode) {
colorEdge(node);
}
return;
}
System.out.print(node.getId() + " visited \t");
if (node != startNode) {
colorEdge(node);
}
for (Edge edge : node.getEdgeSet()) {
Node opposite = edge.getOpposite(node);
if (!opposite.hasAttribute("visited?")) {
System.out.print(opposite.getId() + " enqueued \t");
opposite.setAttribute("level", level);
opposite.setAttribute("parent", node);
opposite.setAttribute("visited?");
next.addLast(opposite);
}
}
System.out.print("\n");
}
level++;
queueFrontier = next;
sleep();
}
}
private void colorEdge(Node node) {
Edge visitedEdge = node.getEdgeBetween(node.getAttribute("parent", Node.class));
visitedEdge.setAttribute("ui.color", 0.5);
sleep();
}
private void sleep() {
try {
Thread.sleep(AppWindow.speed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This BFSAlgorithm
implements DynamicAlgorithm
and extends SinkAdapter
. I have extended the SinkAdapter
to enable it to interact with the View as the algorithm runs. When I call the BFSAlgorithm
, while the algorithm runs and the various println
statements are delayed by sleep()
, the GUI freezes and is unresponsive until after execution before all the visited edges are then colored. I tried implementing ViewerListener
in my AppGraph.java
as is documented on the graphstream documentation but it only resulted in an infinite loop that crashed the application:
/*...init() method from AppGraph.java*/
ProxyPipe fromViewer = viewer.newThreadProxyOnGraphicGraph();
fromViewer.addSink(graph);
fromViewer.pump();
while(loop) {
fromViewer.pump(); //
}