2

我正在编写一个用多边形近似图像的遗传算法。在经历不同的世代时,我想将进度输出到 JFrame。但是,似乎 JFrame 一直等到 GA 的 while 循环完成才能显示某些内容。我不相信这是像重绘这样的问题,因为一旦 while 循环退出,它最终会显示所有内容。即使 while 循环正在运行,我也希望 GUI 能够动态更新。

这是我的代码:

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);
}
4

2 回答 2

3

但是,似乎 JFrame 一直等到 GA 的 while 循环完成才能显示某些内容。我不相信这是像重新粉刷那样的问题

是的,如果循环代码在 EDT 上执行,那么 GUI 在循环完成之前无法重新绘制自身。循环代码应该在自己的线程中执行,这样它就不会阻塞 EDT。

阅读 Swing 教程中关于并发的部分以获取更多信息。

于 2010-05-02T18:55:28.450 回答
1

我认为你的问题是 Java 不允许你从另一个线程而不是 GUI 线程本身更新 GUI。这在某些时候会给每个人带来悲伤,但幸运的是,提供了一个相当方便的解决方法。

这个想法是将执行更新的代码作为 aRunnable传递给方法SwingUtilities.invokeAndWaitSwingUtilities.invokeLater. 这是一个例子

为了以最大速度运行您的 GA 并利用并行性,我想invokeLater这将是合适的。


编辑:哦,等等,camickr 的解决方案暗示您正在做其他事情:您正在 GUI 的线程中运行 GA。好吧,那只能做一个或另一个,计算或显示。所以真正的解决方案将结合这两种变化:

  1. 在单独的线程中运行 GA(您可以在main()实例化 GUI 后使用的线程中运行它);和
  2. 用于invokeLater向 GUI 线程(camickr 称为 EDT 或事件调度线程)传达更新。
于 2010-05-02T18:55:11.627 回答