实时输出到jTextArea
我有一些代码需要几分钟才能处理,它必须为长数组中的每个字符串连接到网络,每个字符串都是一个网址。我想让它每次连接时都应该刷新 jtextarea,这样用户就不会盯着看起来冻结了 20 分钟的空白页面。或者无论需要多长时间。这是我尝试过但不起作用的示例:
try {
ArrayList<String> myLinks = LinkParser.getmyLinksArray(jTextArea1.getText());
for (String s : myLinks) {
jTextArea2.append(LinkChecker.checkFileStatus(s) + "\n");
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(jTextArea1, "Parsing Error", "Parsing Error", JOptionPane.ERROR_MESSAGE);
Logger.getLogger(MYView.class.getName()).log(Level.SEVERE, null, ex);
}
I have some code which takes a few minutes to process, it has to connect to the web for each string in a long array, each string is a url. I want to make it so that everytime it connects, it should refresh the jtextarea so that the user is not staring into a blank page that looks frozen for 20 min. or however long it takes. here is an example of something i tried and didnt work:
try {
ArrayList<String> myLinks = LinkParser.getmyLinksArray(jTextArea1.getText());
for (String s : myLinks) {
jTextArea2.append(LinkChecker.checkFileStatus(s) + "\n");
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(jTextArea1, "Parsing Error", "Parsing Error", JOptionPane.ERROR_MESSAGE);
Logger.getLogger(MYView.class.getName()).log(Level.SEVERE, null, ex);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是您需要异步执行计算。您应该创建一个执行计算的后台线程,然后使用 SwingUtilities.invokeLater 更新 JTextArea。
编辑
有人指出,JTextArea 的追加函数实际上是线程安全的(与大多数 Swing 函数不同)。因此,对于这种特殊情况,没有必要通过 invokeLater 更新它。但是,您仍然应该在后台线程中进行处理,以便允许 GUI 更新,因此代码是:
但是,对于修改 Swing 对象的几乎所有其他操作,您将需要使用 invokeLater(以确保修改发生在 GUI 线程中),因为几乎所有 Swing 函数都不是线程安全的。
The problem is that you need to perform the computation asynchronously. You should create a background thread that performs the computation, and then use SwingUtilities.invokeLater to update the JTextArea.
Edit
It has been pointed out that JTextArea's append function actually is thread safe (unlike most Swing functions). Therefore, for this particular, case it is not necessary to update it via invokeLater. However, you should still do you processing in a background thread so as to allow the GUI to update, so the code is:
However, for pretty much any other operation that modifies a Swing object, you will need to use invokeLater (to ensure the modification occurs in the GUI thread), since almost all the Swing functions aren't thread safe.
您需要研究线程及其与 GUI 更新的关系 在摇摆中。任何影响或使用 Swing 中 GUI 组件的操作都必须在名为 事件调度线程 (EDT)。
如果你的代码片段冻结了 GUI,我想它正在 EDT 中运行。在 EDT 上执行长时间运行的操作将使 GUI 无响应,因为当长时间运行的进程正在使用该线程时,无法进行进一步的更新。
有一个名为
SwingWorker
的帮助程序类允许您将长时间运行的计算卸载到后台线程,然后在完成时更新 GUI 线程。SwingWorker
负责 GUI 线程和后台线程之间的上下文切换。您还可以显示进度条,让用户了解长时间运行的进程的状态,以便他们知道您的应用程序尚未挂起。You need to investigate threading and its relationship to GUI updates in Swing. Anything that affects or makes use of GUI components in Swing must done on a special thread called the Event Dispatch Thread (EDT).
If your code snippet, if it's freezing the GUI, I imagine that it is being run in the EDT. Performing a long-running action on the EDT will make the GUI unresponsive, because no further updates can be done while your long-running process is using the thread.
There is a helper class called
SwingWorker
that allows you to offload long-running computations to a background thread, and then make updates to the GUI thread when it is complete. TheSwingWorker
looks after the context switches between the GUI thread and the background thread. You can also display progress bars to let the user know the state of the long-running process, so they know your application hasn't hung.swing/awt 是一个单线程库,因此一旦显示组件,仅更改其外观将无法正常工作。您需要更改 GUI 线程上的组件,而不是从您的线程中更改组件。要做到这一点,请包装使用 SwingUtilities.invokeLater 更新组件的任何代码...因为
您还想限制在 gui 线程上执行的操作,以避免 gui 变得缓慢,因此,如果 checkFileStatus 很耗时,请在该线程之外执行它run 方法并将结果存储在最终的局部变量中,只需在 run() 代码中访问该变量即可。
swing/awt is a single threaded library, so once a component is shown, just changing it's appearance won't work correctly. You need to change the component on the GUI Thread, not from your thread. To do this wrap any code that updates a component with SwingUtilities.invokeLater... as in
also you want to limit what you do on the gui thread to avoid the gui from becoming sluggish, so if checkFileStatus is time consuming, execute it outside the run method and store the result in a final local variable, and just access the variable in the run() code.