在Java中编写GUI的常规方法是什么?

时间:2013-10-03 18:03:47

标签: java swing user-interface actionlistener thread-sleep

我已经完成了一个GUI应用程序。我有四个班级:Main, UserWindow, Task1, Task2Main类包含布尔变量buttonStartPressedMain方法启动UserWindow类的实例,并等待用户按下“开始”按钮。当用户按下“开始”按钮(在UserWindow中)时,ActionListener会将true分配给static boolean buttonStartPressed,并且Main方法会继续。

Main.java

public static void ......
static boolean buttonStartPressed = false;

...........

while (!buttonStartPress) {
Thread.sleep(50);
}

Task1 t1 = new Task1();

.....
}
}

工作正常,但我不喜欢while循环。我觉得这不是编写应用程序的传统方式。还有另一种方法:我可以组合MainUserWindow类,ActionListener(buttonPressed)的结果将是Task1的开始。但是,另一方面,我认为Main类和UserWindow类应该彼此分开。

2 个答案:

答案 0 :(得分:3)

是的,那是错的。你不应该在任何地方都有繁忙的循环。

你甚至需要buttonStartPressed变量吗?为什么你有兴趣知道它是否被按下,按下按钮时执行某些动作的主要想法不是?

您应该在actionPerformed()方法中创建Task1,并根据您要执行的操作,启动一个执行任务的线程(或者如果它真的很快就在EDT中运行它做,所以它不会冻结GUI)。

答案 1 :(得分:2)

Swing(几乎每个GUI工具包)都有一个专用线程。这个线程,即事件调度线程,在您第一次需要它时启动。这通常是您setVisible JFrame时的情况。这个线程是一个巨大的循环,其作用是消耗输入事件并重新绘制事件并相应地运行一些逻辑。

在你的情况下,你实际上有两个线程。第一个是main线程,第二个是EDT。您的main主题正在执行busy wait。一旦用户按下按钮,actionListener的代码就会在EDT中执行。

您正在使用布尔变量作为使两个线程进行通信的方法。使用某些共享内存确实是inter-thread communication的一种可能方式。

现在,你怀疑你应该避免忙碌等待。它无用地消耗CPU时间,每次唤醒时都会扰乱其他线程,并且它有不可避免的反应延迟。

使用共享内存进行通信通常也很糟糕。这是一种过于低级的沟通方式,而且往往做错了。必须通过锁定机制保护对来自两个线程的数据的访问。即使像布尔一样简单的数据也可以咬你,因为无法保证如果一个线程写入它,另一个线程将看到修改。在您的示例中,布尔值应至少声明为volatile以获得此保证。

因此,添加volatile关键字后,您的解决方案就可以了:您有一个EDT正在忙着做这些事情,当用户点击按钮时,main线程会执行{ {1}}。问自己的第一个问题是:Task1是一项耗时的任务吗?实际上,最简单的解决方案是在Task1中通过从EDT调用Task1来运行Task1。请注意,在actionListener中执行某些代码会冻结GUI。如果EDT持续时间少于100毫秒,则用户甚至不会注意到冻结,并且在另一个线程中执行它没有意义。如果您担心将GUI类与“任务”类耦合,那么您应该使用观察者模式来防止直接依赖。

如果任务耗时并且您不希望GUI冻结,那么您应该使用多个线程。一个解决方案是您实施的解决方案。它有点受限,因为你只有一个Task1线程,但它有效。你现在的问题是让这些线程进行通信。线程间通信中一个非常常见的模式是使用blocking queue。这也是一个共享数据,但它被设计为由多个线程使用。一个线程(main)写入(EDT),另一个线程从中读取(add())并阻塞,直到写入内容为止。对于您的简单示例而言,这似乎有些过分,但它是在线程之间共享数据的一种非常方便的方法。写入阻塞队列的对象可以是任何东西;例如,它们可以表示要执行的命令。

从GUI执行耗时功能的更常规方法是在需要时创建或使用专用线程。这可以使用低级API(Thread)或使用更高级别的API(ExecutorService)来完成,两者都非常易于使用。同样,如果要将GUI操作与线程创建分离,请使用观察者模式。

我很抱歉,如果这个文本墙不能为您的问题提供简单的答案,但是当我们混合使用GUI和线程时,有很多事情需要考虑。我希望对你有用,了解你的其他选择。

相关问题