gpt4 book ai didi

java - 从 Java GUI 应用程序启动 Windows 批处理文件

转载 作者:行者123 更新时间:2023-12-01 13:24:08 28 4
gpt4 key购买 nike

我已经使用 Java Swing 创建了一个桌面应用程序。它需要用户的一些输入,创建一个配置文件和一个批处理文件来运行 python 脚本。许多担忧是:
- 当批处理文件执行正在进行时,我希望 GUI 处于 Activity 模式
- 应用程序中有一个类似 ShowLog 的按钮,用于在执行过程中检查控制台输出。这应该可以在点击时起作用
- 我在 GUI 中有一条“任务进行中”消息,当批处理文件执行完成时,该消息应替换为“任务已完成”
- 还有一个“停止”按钮可以强制停止批处理文件的执行。这应该也能正常工作
(注意:批处理文件执行将需要数小时才能完成)

任何人都可以提出一些想法,让我实现所有这些目标吗?

最佳答案

正如您所知,Swing 是一个单线程框架,这意味着在事件调度线程上下文中运行的任何内容都将阻止它更新屏幕或响应用户输入。

基本的解决方案是使用 Thread 来运行批处理,但这会引发 UI 更新同步问题,因为您永远不应该从外部修改 UI 或与 UI 交互EDT 的背景。

更好的解决方案是使用 SwingWorker,它使您能够在后台运行长时间运行的任务,同时还使您能够发布在 EDT 上下文中更新并处理更新,它还为您提供了 done 方法,该方法在 doInBackground 方法退出后调用,并且在 EDT 上下文中调用。

最后,它为您提供了一个取消选项 - 但这就是问题发生的地方。据推测,您将在辅助线程中读取进程的输入,并等待进程在您启动它的同一线程 (SwingWorker) 中退出。 SwingWorker 依赖于 Thread中断功能,它可能不会触发 waitFor 方法返回。

现在阅读了 Process 文档,waitFor 确实抛出了 InterruptedException

if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

这表明当调用 done 时,您需要调用 isCancelled 来检查工作线程是否被取消。如果是这样,您需要在Process上调用destroy并关闭您可能正在运行的任何辅助Thread

您可以使用额外的 SwingWorker 来读取流程中的输入,并利用其publish/process 功能来更新日志。

这意味着,您将启动一个 SwingWorker 来执行您的外部进程。这可能是为了响应某些事件(例如按下按钮)而完成的。

当调用此工作线程的 doInBackground 方法时,它将执行外部进程并调用 Process#waitFor。这将阻止 doInBackground 方法返回,直到进程退出。

在调用 Process#waitFor 之前,您可以创建另一个 SwingWorker 并传递 ProcessOutputStream到它。这将允许该工作人员独立处理流程的输出。然后,您可以使用它通过 SwingWorkerpublish/process 功能将流程的输出发送回 EDT,这可以添加到诸如 JTextArea 之类的内容中。

这将为您在处理 SwingUtilities.invokeLater 时省去很多麻烦。

需要第二部作品吗?这取决于您希望 worker 做什么。我倾向于在单独的线程中处理外部进程的所有输出,并允许创建该进程的人使用 waitFor,它进一步隔离了责任,并防止 IO 被锁定而永远无法到达 waitFor,但这只是我。

看看Concurrency in Swing了解更多详情

关于java - 从 Java GUI 应用程序启动 Windows 批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21872242/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com