如何让Java Frame不等待?
我正在编写一种遗传算法,用多边形来近似图像。在经历不同的世代时,我想将进度输出到 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
的,如果循环代码在 EDT 上执行,那么 GUI 无法重新绘制自身,直到循环完成。循环代码应该在它自己的线程中执行,这样它就不会阻塞 EDT。
有关详细信息,请阅读 Swing 教程中有关并发的部分。
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.
我认为你的问题是Java不允许你从GUI线程本身之外的另一个线程更新GUI。这在某些时候会给每个人带来悲伤,但幸运的是,提供了一个相当方便的解决方法。
其想法是将执行更新的代码作为
Runnable
传递给方法SwingUtilities.invokeAndWait
或SwingUtilities.invokeLater
。 这是一个示例。为了以最大速度运行 GA 并利用并行性,我认为
invokeLater
比较合适。编辑:哦等等,camickr 的解决方案暗示您正在做其他事情:您正在 GUI 的线程中运行 GA。嗯,那只能做其中之一,计算或显示。因此,真正的解决方案将结合这两个更改:
main()
使用的线程中运行它);并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 methodSwingUtilities.invokeAndWait
orSwingUtilities.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:
main()
after you've instantiated the GUI); andinvokeLater
to communicate updates to the GUI thread (which camickr calls the EDT, or Event Dispatch Thread).