Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Java GUI应用程序启动windows批处理文件_Java_Multithreading_Swing_Batch File - Fatal编程技术网

从Java GUI应用程序启动windows批处理文件

从Java GUI应用程序启动windows批处理文件,java,multithreading,swing,batch-file,Java,Multithreading,Swing,Batch File,我已经使用JavaSwing创建了一个桌面应用程序。它接受用户的一些输入,创建一个配置文件和一个批处理文件来运行python脚本。许多问题是: -当批处理文件正在执行时,我希望GUI处于活动模式 -应用程序中有一个类似ShowLog的按钮,用于在执行期间检查控制台输出。单击此按钮应能正常工作 -我在GUI中有一条“任务进行中”消息,当批处理文件执行完成时,该消息应替换为“任务已完成” -还有一个“停止”按钮,用于强制停止批处理文件的执行。这也应该很好 (注意:批处理文件执行将需要数小时才能完成)

我已经使用JavaSwing创建了一个桌面应用程序。它接受用户的一些输入,创建一个配置文件和一个批处理文件来运行python脚本。许多问题是:
-当批处理文件正在执行时,我希望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
方法