Swing Worker - 按自己的顺序调用函数

时间:2016-09-05 18:39:04

标签: java multithreading swingworker

我正在尝试确保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);
    }
}

}

1 个答案:

答案 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);
    }
}

}

干杯!