2016-09-05 27 views
0

我试图确保JFrame在更新GUI时保持响应。我为此使用SwingWorker。该方案是在程序的顺序流程中执行以下代码。Swing Worker - 按自己的顺序调用函数

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-loop期间。在执行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

我发现这个问题的答案。基本上,我们必须返回来自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); 
    } 
} 

} 

干杯!