我正在尝试确保JFrame在更新GUI时保持响应。我正在使用SwingWorker。该方案是在程序的顺序流程中执行以下代码。
public int[][] readInputFile(MatrixOperations matrixOperations,
String inputFile, Boolean isDirected) throws IOException {
List<String> fileLines = Files.readAllLines(Paths.get(inputFile),
StandardCharsets.UTF_8);
int[][] adjacencyMatrix = matrixOperations.createAdjacencyMatrixFromFile(
fileLines, isDirected);
//The following two lines perform the computationally expensive operation.
//So I'm asking SwingWorker to do this.
task = new Task(fileLines, isDirected, ROOT_GRAPH);
task.execute();
return adjacencyMatrix;
}
这是正在执行的SwingWorker类。我面临的问题是在doInBackground()中执行for循环期间。在执行doInBackground()期间,三个函数,即createNodeFromFile(source),createNodeFromFile(destination),createEdgeFromFile(source,destination,isDirected)按照自己的顺序被调用,但它们应该按顺序调用。结果我得到ConcurrentModification Exception或者有时Node不存在异常(这是Graphstream库特定的异常)。我该如何解决这个问题?
import java.util.List;
import javax.swing.SwingWorker;
import org.graphstream.graph.Graph;
public class Task extends SwingWorker<Void, Integer>{
List<String> list;
Boolean isDirected;
Graph graph;
public Task(List<String> list, Boolean isDirected, Graph graph){
this.list = list;
this.isDirected = isDirected;
this.graph = graph;
}
@Override
public Void doInBackground() throws Exception {
// TODO Auto-generated method stub
int count = 0;
for (int i = 0; i < list.size(); i++) {
// System.out.println(fileContent.get(i));
if ((!list.get(i).startsWith("#"))
&& (list.get(i).length() > 1)) {
count++;
String[] arrLine = list.get(i).trim().split("\\s+");
String source = arrLine[0].trim();
String destination = arrLine[1].trim();
createNodeFromFile(source);
createNodeFromFile(destination);
createEdgeFromFile(source, destination, isDirected);
}
if (count % 1000 == 0) {
System.out.println("Finished processing " + count + " lines");
}
}
return null;
}
public void createNodeFromFile(String nodeId) {
if (graph.getNode(nodeId) == null) {
graph.addNode(nodeId);
showLabelOnRootGraph(nodeId, nodeId);
}
}
public void showLabelOnRootGraph(String nodeId, String label) {
graph.getNode(nodeId).addAttribute("ui.label", label);
}
public void createEdgeFromFile(String source, String destination, Boolean isDirected) {
if (graph.getNode(source).hasEdgeBetween(destination) == false) {
graph.addEdge("S" + source + "D" + destination, source,
destination, isDirected);
}
}
}
答案 0 :(得分:0)
我找到了答案。基本上,我们必须从Swing Worker返回对象Graph。然后必须将此对象传递给process()。这是解决方案:
package main.graph.generate;
import java.util.Iterator;
import java.util.List;
import javax.swing.SwingWorker;
import org.graphstream.graph.Graph;
import org.graphstream.ui.view.Viewer;
import org.graphstream.ui.view.ViewerPipe;
public class Task extends SwingWorker<Graph, Graph>{
List<String> list;
Boolean isDirected;
Graph graph;
ViewerPipe viewerPipe;
public Task(List<String> list, Boolean isDirected, Graph graph, ViewerPipe viewerPipe){
this.list = list;
this.isDirected = isDirected;
this.graph = graph;
this.viewerPipe = viewerPipe;
}
@Override
public Graph doInBackground() throws Exception {
// TODO Auto-generated method stub
int count = 0;
//for (int i = 0; i < list.size(); i++) {
// System.out.println(fileContent.get(i));
for(Iterator it = list.iterator();it.hasNext();){
String line = (String) it.next();
if ((!line.startsWith("#"))
&& (line.length() > 1)) {
count++;
String[] arrLine = line.trim().split("\\s+");
String source = arrLine[0].trim();
String destination = arrLine[1].trim();
createNodeFromFile(source);
createNodeFromFile(destination);
createEdgeFromFile(source, destination, isDirected);
publish(graph);
}
if (count % 1000 == 0) {
System.out.println("Finished processing " + count + " lines");
}
}
return graph;
}
@Override
protected void process(List<Graph> graphs){
GraphGenerate.ROOT_GRAPH = graphs.get(graphs.size()-1);
viewerPipe.addAttributeSink(GraphGenerate.ROOT_GRAPH);
}
public void createNodeFromFile(String nodeId) {
if (graph.getNode(nodeId) == null) {
graph.addNode(nodeId);
showLabelOnRootGraph(nodeId, nodeId);
}
}
public void showLabelOnRootGraph(String nodeId, String label) {
graph.getNode(nodeId).addAttribute("ui.label", label);
}
public void createEdgeFromFile(String source, String destination, Boolean isDirected) {
if (graph.getNode(source).hasEdgeBetween(destination) == false) {
graph.addEdge("S" + source + "D" + destination, source,
destination, isDirected);
}
}
}
干杯!