我有一个奇怪的问题……我是一个相对较新的“狂热” Java程序员(在以前的职业中,我曾经以从事Perl工作为生),正在开发我的第一个半真实应用程序。 “Main-Class”是MyApp
类,它创建一个UserInputDialog
实例。UserInputDialog
是我写的一个类,extend
的JFrame
,实现ActionListener
和KeyListener
,使用FlowLayout
,并向用户提供JLabel
,JTextField
和Cancel / OK JButton
。当JTextField
生成其中KeyEvent
的keyReleased() == KeyEvent.VK_ENTER
时,或当“OK” JButton
生成ActionEvent
时,UserInputDialog
进行一些输入验证,调用setVisible(false)
,然后调用MyApp.doSomething( JTextFieldInstance.getText() )
。
一切都完美。但是,现在我正在尝试向MyApp
添加进度窗口,因为doSomething()
有时可能需要相当长的时间才能完成。
我创建了ProgressWindow
类,该类扩展了JFrame
,使用了BorderLayout
并在中扔了一个JProgressBar
。中的NORTH
和JScrollPane
(包装JTextArea
)。 CENTER
。从ProgressWindow
实例化并馈送测试数据后,ProgressWindowTester
可以完美地工作。如果我将测试从ProgressWindowTester
的循环复制并粘贴到MyApp
,并且没有MyApp
实例化UserInputDialog
,那么它也可以正常工作(即MyApp
内在没有引起这种行为的固有现象;这似乎是我的某种交互作用)我不了解UserInputDialog
和ProgressWindow
之间)。
但是,当我尝试按预期在ProgressWindow
中使用MyApp
时,即ProgressWindow
setVisible(true),我得到了一个空白的Swing窗口(大小适当,并且标题栏设置正确)。 JProgressBar
和JScrollPane / JTextArea
组件不出现。 ProgressWindow
正确地调用了MyApp
方法(System.err.println()
消息显示了正确的交互),一切似乎都工作正常,只是,在ProgressWindow
中应该可见的组件……不是。
我可以发布代码片段,但这有点令人费解,而且我可能只是缺少一些明显的东西...
我熟悉通常将UI和业务逻辑分开的概念(例如,在构建Perl应用程序时使用了HTML::Template
和Class::DBI
和CGI::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!