从Java GUI应用程序启动windows批处理文件
我已经使用JavaSwing创建了一个桌面应用程序。它接受用户的一些输入,创建一个配置文件和一个批处理文件来运行python脚本。许多问题是:从Java GUI应用程序启动windows批处理文件,java,multithreading,swing,batch-file,Java,Multithreading,Swing,Batch File,我已经使用JavaSwing创建了一个桌面应用程序。它接受用户的一些输入,创建一个配置文件和一个批处理文件来运行python脚本。许多问题是: -当批处理文件正在执行时,我希望GUI处于活动模式 -应用程序中有一个类似ShowLog的按钮,用于在执行期间检查控制台输出。单击此按钮应能正常工作 -我在GUI中有一条“任务进行中”消息,当批处理文件执行完成时,该消息应替换为“任务已完成” -还有一个“停止”按钮,用于强制停止批处理文件的执行。这也应该很好 (注意:批处理文件执行将需要数小时才能完成)
-当批处理文件正在执行时,我希望GUI处于活动模式
-应用程序中有一个类似ShowLog的按钮,用于在执行期间检查控制台输出。单击此按钮应能正常工作
-我在GUI中有一条“任务进行中”消息,当批处理文件执行完成时,该消息应替换为“任务已完成”
-还有一个“停止”按钮,用于强制停止批处理文件的执行。这也应该很好
(注意:批处理文件执行将需要数小时才能完成)
有谁能想出一些办法来实现这些目标吗?
您可以在java中运行bat文件,并使用Runtime
Runtime.getRuntime().exec("cmd /c start your_batch_file.bat");
如您所知,Swing是一个单线程框架,这意味着在事件调度线程上下文中运行的任何内容都将阻止它更新屏幕或响应用户输入 基本解决方案是使用
线程
在中运行批处理过程,但这会导致UI更新的同步问题,因为您不应在EDT上下文之外修改UI或与UI交互
更好的解决方案是使用SwingWorker
,它使您能够在后台运行长时间运行的任务,但使您能够在EDT上下文中发布更新和处理更新,它还为您提供了一个done
方法,该方法在doInBackground
方法退出后调用,并在EDT上下文中调用
最后,它为您提供了一个cancel
选项,但这就是问题所在。假设您将在次线程中读取来自该进程的输入,并将等待该进程在启动它的同一线程(SwingWorker
)中退出SwingWorker
依赖于Thread
的interrupt
功能,该功能可能不会触发waitFor
方法返回
现在已经阅读了过程
文档,waitFor
确实抛出了一个中断异常
如果当前线程在运行时被另一个线程中断
等待,然后等待结束并抛出InterruptedException
这表明当调用done
时,您需要调用isCancelled
来检查工作人员是否被取消。如果是,您需要调用进程上的destroy
,并关闭可能正在运行的任何辅助线程
您可以使用一个额外的SwingWorker
从流程中读取输入,并使用其发布
/流程
功能来更新日志
这意味着,您将启动一个SwingWorker
来执行外部流程。这可能是对某些事件的响应,比如按下按钮
当调用此工作者的doInBackground
方法时,它将执行外部进程并调用process\waitFor
。这将停止doInBackground
方法返回,直到进程退出
在调用进程#waitFor
之前,您可以创建另一个SwingWorker
,并将进程的输出流传递给它。这将允许该工作者独立处理来自该进程的输出。然后,您可以使用此功能通过SwingWorker
的publish
/流程
功能将流程输出发送回EDT,该功能可以添加到JTextArea
之类的功能中
这将为您节省大量处理SwingUtilities.invokeLater
的麻烦
你需要第二份工作吗?这取决于你想让工人做什么。我倾向于在单独的线程中处理外部进程的所有输出,并允许曾经创建过该进程的人使用waitFor
,这会进一步隔离责任,并防止IO被锁定在一个永远无法到达的waitFor
,但这就是我
查看更多详细信息谢谢@Dark。但是,您知道,我关心的不是如何从Java应用程序启动bat文件。@Val:您可能需要使用[描述性文本](http://stackoverflow/link/here)
更人性化链接的语法。我认为这是愚蠢的。新流程将有自己的“SwingWrokers”。执行并行进程不需要线程。@Val这是什么意思?我通常使用一个单独的线程来读取进程OutputStream
,同时允许开始waitFor
@Val的线程
。您能更详细地解释一下您的观点吗?@MadProgrammer谢谢您的新想法。但在我看来,我已经在NetBeans中设计了一个现有的GUI。我可以将SwingWorkers集成到现有设置中吗?或者需要从头开始吗?不,您应该能够非常简单地集成它。基本上,您只需要获取执行和监视外部进程的代码部分,并将其包装在SwingWorker
中。只要确保维护对它的引用,就可以调用它的cancel
方法