2017-06-05 120 views
1

目前,我正在製作Java程序的圖形可視化Prim的算法尋找最小生成樹。使用定時器在固定的時間重繪,然後繼續計算

Here is the image of my program's output

while(condition){ 
    //Find the min vertex and min edges 
    Vertex vertex = findMinVertex(); 
    Edge[] edges = findMinEdges(); 

    //Then, for each vertex and edges I found, I will change the color of 
    //them and pause the program for 3 seconds, so user can see how 
    //algorithm works. 

    repaintAndPause(3000); 
} 
. 
. 
private void repaintAndPause(int time){ 
    long start = System.currentTimeMillis(); 
    long end = start + speed; 

    //Here is the timer for repainting. 
    Timer timer = new Timer(speed, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e){ 
      GraphPanel.this.repaint(); 
     } 
    }); 
    timer.setRepeats(false); 
    timer.setDelay(0); 
    timer.start(); 

    //And here is for pausing the program, a while loop without any commands. 
    while(System.currentTimeMillis() < end){} 
} 

不過,我不知道爲什麼,但該程序無法正常工作。是的,程序有暫停,但所有的邊和頂點只是在程序結束時改變顏色。他們不會每3秒更換一次。

有人能告訴我我做錯了嗎?

謝謝你,祝你有美好的一天!

回答

1

有人能告訴我我做錯了什麼嗎?

是的。您正在事件調度線程中設置一個忙碌循環。

while(System.currentTimeMillis() < end){} 

您的代碼讀取:

  1. 做一些計算(
  2. 完成後,發佈了 「重繪」 消息,重繪面板不忙的時候
  3. 繼續爲非常繁忙無所事事3秒
  4. 繼續通過4.

事件指派線程通過重複步驟1爲從未完成處理的第一個「事件」,直到該算法結束時,while (condition)環終於完成後。

你想:

Timer timer = new Timer(speed, new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     /* Code to perform one step of Prim's algorithm here */ 
     /* Change edge/vertex colour for step */ 
     /* Call timer.stop(), once done */ 

     GraphPanel.this.repaint(); 
    } 
}); 
timer.setRepeats(true); 
timer.setDelay(3000); 
timer.start(); 

計時器(每3秒一次)的每一個節拍,執行的算法的一個步驟。

注意這意味着算法的每個步驟必須運行任何部分結果存儲到類成員,所以下一步將能夠檢索到所有需要繼續的信息。堆棧變量只能在一個步驟內使用;它們不能用於保存跨步值。

您可以修改算法以使用SwingWorker在其自己的後臺線程中運行計算,並在計算時使用publish中間結果。隨着中間結果的產生,EDT可以重新繪製。在調用Thread#sleep()時,此後臺線程可能會將生成的中間結果延遲至每3秒一次。或者,您可以運行該算法,並存儲多個輸出副本,每個'步驟'一次。然後你的面板計時器可以簡單地顯示下一步的輸出。

+0

謝謝AJNeufeld, 你救了我的一天!它像一個魅力! – Lup