2010-05-02 79 views
2

我在寫一個用多邊形逼近圖像的遺傳算法。在經歷不同世代的同時,我想將進度輸出到JFrame。但是,好像JFrame一直等到GA的while循環完成顯示內容。我不認爲這是重繪的問題,因爲一旦while循環退出,它最終會顯示所有內容。即使在while循環運行時,我也想動態更新GUI。如何防止Java Frame等待?

這裏是我的代碼:

while (some conditions) { 
    //do some other stuff 
    gui.displayPolygon(best); 
    gui.displayFitness(fitness); 
    gui.setVisible(true); 
} 

public void displayPolygon(Polygon poly) { 
    BufferedImage bpoly = ImageProcessor.createImageFromPoly(poly); 
    ImageProcessor.displayImage(bpoly, polyPanel); 
    this.setVisible(true); 
} 

public static void displayImage(BufferedImage bimg, JPanel panel) { 
    panel.removeAll(); 
    panel.setBounds(0, 0, bimg.getWidth(), bimg.getHeight()); 
    JImagePanel innerPanel = new JImagePanel(bimg, 25, 25); 
    panel.add(innerPanel); 
    innerPanel.setLocation(25, 25); 
    innerPanel.setVisible(true); 
    panel.setVisible(true); 
} 
+0

它可能是一個重新繪製preoblem(爲什麼你不這麼認爲?)。您應該重寫paintComponent方法。 – Giancarlo 2010-05-02 18:52:06

回答

1

我覺得你的問題是Java不會讓你從另一個線程不是GUI線程本身更新GUI。這在某些時候會導致所有人都感到悲傷,但幸運的是提供了一個相當方便的解決方法。

這個想法是將代碼更新爲Runnable傳遞給方法SwingUtilities.invokeAndWaitSwingUtilities.invokeLaterHere's an example

要以最快的速度運行你的GA並利用並行性,我猜invokeLater會是合適的。編輯:哦,等等,camickr的解決方案暗示你正在做其他事情:你在GUI的線程中運行GA。那麼,這隻能做一個或另一個,計算或顯示。所以,真正的解決方案將結合兩種變化:

  1. 在一個單獨的線程運行GA(你實例化的GUI後,你可以通過main()使用的線程中運行它);和
  2. 使用invokeLater來溝通GUI線程(camickr稱爲EDT或Event Dispatch Thread)的更新。
+1

就像你我仍然傾向於創建一個單獨的線程,然後使用invokeLater(),但本教程建議使用SwingWorker,它將1&2合併到同一個類中。我認爲大多數人現在都使用這種方法。 – camickr 2010-05-02 19:21:18

+0

這是我的新聞,謝謝!我以前見過SwingWorker,但從未給過多關注。 – 2010-05-02 19:43:31

+0

SwingWorker是正確的答案......謝謝! – pypmannetjies 2010-05-03 18:47:24

3

然而,這似乎是JFrame的 等待,直到GA的while循環 完成顯示的東西。我不相信 它就像重新粉刷

是的,如果循環代碼的執行EDT那麼GUI不能重繪自己,直到循環結束的問題。循環代碼應該在它自己的Thread中執行,因此它不會阻止EDT。

有關更多信息,請參閱Concurrency上的Swing教程部分。

+0

+1給你的幫助。謝謝! – 2010-05-03 19:06:50