4

我有一个奇怪的问题......我是一个相对较新的“狂热”Java 程序员(我以前的职业生涯中曾经以黑客 Perl 为生),正在开发我的第一个半真实应用程序。“Main-Class”是MyApp创建UserInputDialog实例的类。

UserInputDialogextend是我编写的一个类JFrame,它实现了ActionListenerand KeyListener,使用FlowLayout了 ,并向用户展示了JLabel,JTextField和 Cancel/OK JButtons。当JTextField生成KeyEventwherekeyReleased() == KeyEvent.VK_ENTER或“OK”JButton生成时ActionEvent,进行UserInputDialog一些输入验证,调用setVisible(false),然后调用MyApp.doSomething( JTextFieldInstance.getText() )

这一切都完美无缺。但现在我正在尝试向 中添加进度窗口MyApp,因为doSomething()有时可能需要相当长的时间才能完成。

我创建了一个ProgressWindow类,它扩展JFrame、使用BorderLayout和抛出一个JProgressBarin 。NORTH和 a JScrollPane(包装 a JTextArea)在 . CENTER. ProgressWindow当从测试数据实例化ProgressWindowTester并提供测试数据时,它可以完美地工作。如果我将循环的测试复制并粘贴ProgressWindowTesterMyApp其中并且没有MyApp实例化,它也可以正常工作UserInputDialog(即,没有任何内在因素导致MyApp这种行为;这似乎是某种我不理解的交互,在UserInputDialogProgressWindow)。

但是当我尝试按预期使用ProgressWindowMyApp,即ProgressWindowsetVisible(true),我得到一个空白的 Swing 窗口(大小合适,并且标题栏设置正确)。和组件JProgressBarJScrollPane / JTextArea出现。这些ProgressWindow方法被MyApp正确调用(System.err.println()消息显示正确的交互),一切似乎都工作正常,只是,应该在ProgressWindow......中可见的组件不是。

我可以发布代码片段,但这有点令人费解,我可能只是遗漏了一些明显的东西......

我通常熟悉分离 UI 和业务逻辑的概念(例如,我在构建 Perl 应用程序时使用HTML::TemplateandClass::DBICGI::Application),但我不确定我在 Java 中“做对了”......

提前致谢!

哦,在我尝试过代码的两个环境中,我得到了完全相同的行为:Mac OS X 10.6.8 上的 javac 1.6.0_29 ("Snow Leopard");以及 Fedora 15 Linux 发行版、内核 2.6.31.10-3、LXDE 桌面环境上的 javac 1.7.0_02[1]。

[1] 直接从oracle.com下载;我没有使用 OpenJDK(我知道 JDK 7 基于 OpenJDK)或 gcj 或类似的东西

4

1 回答 1

5

您在 Swing 问题中遇到了并发问题,您尝试在 Swing 事件线程或 EDT 上执行长时间运行的进程。由于该线程负责绘制所有组件并处理用户输入,如果它被您的长时间运行的进程所束缚,那么您的 GUI 将被有效地冻结,直到该进程完成。关键是使用后台线程,例如 SwingWorker 为长时间运行的进程提供的线程,这样事件线程就不会被锁定。查看Swing 中的并发以获取更多信息。另请查看JProgressBar 教程,了解有关如何将进度条与后台线程一起使用的其他见解。

此外,您不会希望在对话框(例如 JDialog)更合适的地方使用 JFrame。此外,您需要避免在 Swing 中使用 KeyListener。更好的是简单地将 ActionListener 添加到您的 JTextField 中,因为它的默认行为是响应按键的按下。

哦,欢迎来到 StackOverflow.com!

于 2012-02-03T22:29:29.877 回答