如何让Java Frame不等待?

发布于 2024-08-30 22:04:24 字数 885 浏览 2 评论 0原文

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

这是我的代码:

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

I am writing a genetic algorithm that approximates an image with a polygon. While going through the different generations, I'd like to output the progress to a JFrame. However, it seems like the JFrame waits until the GA's while loop finishes to display something. I don't believe it's a problem like repainting, since it eventually does display everything once the while loop exits. I want to GUI to update dynamically even when the while loop is running.

Here is my code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

折戟 2024-09-06 22:04:24

但是,看起来像 JFrame
等待 GA 的 while 循环
完成显示一些东西。我不
相信这是一个类似重画的问题

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

有关详细信息,请阅读 Swing 教程中有关并发的部分。

However, it seems like the JFrame
waits until the GA's while loop
finishes to display something. I don't
believe it's a problem like repainting

Yes, if the looping code execute on the EDT then the GUI can't repaint itself until the loop finishes. The looping code should execute in its own Thread so it doesn't block the EDT.

Read the section from the Swing tutorial on Concurrency for more information.

时光与爱终年不遇 2024-09-06 22:04:24

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

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

为了以最大速度运行 GA 并利用并行性,我认为 invokeLater 比较合适。


编辑:哦等等,camickr 的解决方案暗示您正在做其他事情:您正在 GUI 的线程中运行 GA。嗯,那只能做其中之一,计算或显示。因此,真正的解决方案将结合这两个更改:

  1. 在单独的线程中运行 GA(在实例化 GUI 后,您可以在 main() 使用的线程中运行它);并
  2. 使用 invokeLater 将更新传达给 GUI 线程(camickr 称为 EDT,或事件调度线程)。

I think your problem is that Java won't let you update the GUI from another thread than the GUI thread itself. This causes grief to everybody at some point, but fortunately a reasonably convenient workaround is provided.

The idea is to pass the code that does the updating as a Runnable to the method SwingUtilities.invokeAndWait or SwingUtilities.invokeLater. Here's an example.

To run your GA at maximum speed and exploit parallelism, I guess invokeLater would be appropriate.


EDIT: Oh wait, camickr's solution hints that you're doing something else: You're running the GA in the GUI's thread. Well, that can only do one or the other, calculate or display. So the true solution would combine both changes:

  1. Run the GA in a separate thread (you could run it in the thread used by main() after you've instantiated the GUI); and
  2. Use invokeLater to communicate updates to the GUI thread (which camickr calls the EDT, or Event Dispatch Thread).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文