2015-10-06 27 views
0

我試圖在一個小項目中使用Graphics2D和Swing(不知道這是個好主意,我只是爲了好玩而做的)排序算法,並且到了一個點每次數組中的一個元素改變其值時,我都會調用update方法,並調用paintCompenent方法。paintComponent不會每次我想要它調用

問題是paintComponent方法只是在算法完成後才被調用。這裏是算法的代碼:

private void sortBubble() { 
    int n = array.length; 
    do {    
     int newn = 1; 
     for (int i = 0; i < n - 1; i++) { 
      if (array[i] > array[i + 1]) {     
       int index = array[i];      
       array[i] = array[i + 1];          
       array[i + 1] = index; 
       System.out.println("SWITCHED"); 
       this.setChanged(); 
       this.notifyObservers(); 
       newn = i + 1;     
      } 
     } 
     n = newn; 
    } while (n > 1);  
} 

更新方法的代碼:

public void update(Observable o, Object arg) { 
    if(draw!=null) { 
     drawPanel.remove(draw);   
    }  
    draw = new Plotter(array.array,this.getWidth(),this.getHeight()); 
    drawPanel.add(draw); 
    drawPanel.validate();  
    System.out.println("UPDATED"); 
} 

而且JPanel類的代碼:

private void draw(Graphics g) {  
    g2d = (Graphics2D) g; 
    int i;     
    for(i=0;i<array.length;i++) { 
     g2d.draw(new Line2D.Double(i, height, i, height-array[i]));    
    }   
} 

@Override 
public void paintComponent(Graphics g) {    
    super.paintComponent(g); 
    draw(g); 
    System.out.println("PLOTTED"); 
} 

有沒有辦法讓JPanel實際上每次更新值都會更新?

回答

1

Swing是一個單線程框架,這意味着任何長時間的運行/阻塞代碼都會導致程序「失速」,從而無法更新UI或響應用戶輸入。

有關更多詳細信息,請參見Concurrency in Swing

有幾種方法可以解決這個問題,您可以使用SwingWorker或Swing Timer,這取決於您的需求/能力。

Worker Threads and SwingWorkerHow to use Swing Timers更多細節

也看看java multiple graphics了可視化排序實現的例子

+0

謝謝,我會看看它,但爲什麼長時間運行的代碼,可預防UI更新?它畢竟是一系列命令,在算法運行時UI不應該更新,而是在「休息」期間更新。 – shyvex

+0

負責處理來自事件隊列的所有事件的事件分派線程無法在您使用「do-while」循環進行阻塞時運行。整個框架被封裝在一個線程中。我不確定你的意思是什麼「休息」,因爲我沒有真正看到它,但之後,你只是拋棄了一堆沒有關聯的代碼,而不是一個[可運行的示例](https ://stackoverflow.com/help/mcve)它演示你的問題 – MadProgrammer

相關問題