2013-04-09 107 views
2

我試圖用drawlines做一個排序算法,所以它看起來像一個圖。這裏的問題是,當數組正在排序時,我看不到進度是一個移動的圖。當我輸入睡眠時間時,外印只顯示我很長的一行,並且在睡眠線之後顯示完整的排序圖。所以我只需要在圖表排序時看到進度。在這種情況下,我使用了bublesort。我非常感謝每一個幫助!Stuck with Thread and updateGraphics

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

public class newClass extends JFrame { 

public newClass() { 
    final Thread hei = new Thread(new Runnable() { 

     public void run() { 
      bublesort(); 
     } 
    }); 
    hei.start(); 
} 
int[] array = { 400, 420, 380, 120, 340, 179, 454, 400, 420, 380, 120, 340, 179, 454, 400, 420, 380, 120, 340, 179 }; 

public void updateGraphic() { 
    paint(this.getGraphics()); 
} 

public void paint(Graphics g) { 

    for (int i = 0; i < array.length; i++) { 
     int tjue = 20; 
     g.drawLine(i * tjue, 500, i * tjue, array[i]); 
    } 

    for (int j = 0; j < array.length - 1; j++) { 
     for (int x = 0; x < array.length - 1; x++) { 
      if (array[x] > array[x + 1]) { 
       int temp = array[x]; 
       array[x] = array[x + 1]; 
       array[x + 1] = temp; 
       updateGraphic(); 
       this.validate(); 
       try { 
        Thread.sleep(50); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(newClass.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    } 
} 

}

+0

哪裏是漂亮的方法? – emecas 2013-04-09 22:19:28

+0

1)爲了更快地獲得更好的幫助,請發佈[SSCCE](http://sscce.org/)。 2)不要阻塞EDT(Event Dispatch Thread) - 當發生這種情況時,GUI將「凍結」。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複執行任務,或者一個'SwingWorker'執行長時間運行的任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 – 2013-04-10 00:00:46

回答

0

在一般情況下,這是一個好主意,不使用的Thread.sleep或做性能密集型的東西在paint方法。這是因爲paint方法在事件派發線程上執行,Swing依賴該線程執行GUI更新。相反,在一個單獨的線程中運行排序,並在該線程中調用repaint()而不是updateGraphic()。看起來你已經有一個bubbleSort()方法,所以只是適應它像這樣:

for (int j = 0; j < array.length - 1; j++) { 
    for (int x = 0; x < array.length - 1; x++) { 
     if (array[x] > array[x + 1]) { 
      int temp = array[x]; 
      array[x] = array[x + 1]; 
      array[x + 1] = temp; 
      repaint(); 
      try { 
       Thread.sleep(50); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(newClass.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 
} 

當然,你想從你的paint方法刪除此代碼。

+0

而不是捕獲和幾乎忽略中斷,你應該退出循環。這樣在將來你可以停止這個過程。 – user949300 2013-04-09 22:23:06

1

自定義繪畫是通過覆蓋JPanel(或JComponent)的paintComponent()方法完成的,然後將面板添加到框架。請參閱Custom Painting的Swing教程中的部分,以獲得一個工作示例。

如果要爲動畫繪製動畫,則應使用擺動計時器來安排動畫。從教程中搜索目錄以查找關於How to Use Swing Timers的部分以獲取更多信息。