我有一个奇怪的问题……我是一个相对较新的“狂热” Java程序员(在以前的职业中,我曾经以从事Perl工作为生),正在开发我的第一个半真实应用程序。 “Main-Class”是MyApp类,它创建一个UserInputDialog实例。
UserInputDialog是我写的一个类,extendJFrame,实现ActionListenerKeyListener,使用FlowLayout,并向用户提供JLabelJTextField和Cancel / OK JButton。当JTextField生成其中KeyEventkeyReleased() == KeyEvent.VK_ENTER时,或当“OK” JButton生成ActionEvent时,UserInputDialog进行一些输入验证,调用setVisible(false),然后调用MyApp.doSomething( JTextFieldInstance.getText() )

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

我创建了ProgressWindow类,该类扩展了JFrame,使用了BorderLayout并在中扔了一个JProgressBar。中的NORTHJScrollPane(包装JTextArea)。 CENTER。从ProgressWindow实例化并馈送测试数据后,ProgressWindowTester可以完美地工作。如果我将测试从ProgressWindowTester的循环复制并粘贴到MyApp,并且没有MyApp实例化UserInputDialog,那么它也可以正常工作(即MyApp内在没有引起这种行为的固有现象;这似乎是我的某种交互作用)我不了解UserInputDialogProgressWindow之间)。

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

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

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

提前致谢!

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

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

最佳答案

您正在尝试在Swing事件线程或EDT上执行长时间运行的过程时,在Swing问题中存在并发问题。由于此线程负责绘制所有组件并处理用户输入,因此如果长时间运行的进程将其绑定在一起,则GUI将被有效冻结,直到该进程完成。关键是将诸如SwingWorker提供的后台线程用于长时间运行的进程,这样事件线程就不会被锁定。查看Concurrency in Swing以获得更多信息。另请查看JProgressBar Tutorial,以获取有关如何在后台线程中使用进度条的其他见解。

另外,在诸如JDialog之类的对话框更合适的情况下,您也不想使用JFrame。另外,您将希望避免将KeyListeners与Swing一起使用。更好的方法是将ActionListener简单地添加到JTextField中,因为它的默认行为是响应按键的按下。

哦,欢迎来到StackOverflow.com!

10-07 23:03