我编写了一个程序,该程序执行cmd命令并将输出打印到程序的“控制台”。我已经使用Thread打印输出而不冻结程序。我希望能够看到实时输出。
问题出在哪里,我找不到解决方案,因为在执行initialize
方法之后,executeCommand
中的一部分在executeCommand之后立即执行。我想要做的是一旦线程停止运行就执行其余的初始化。如果不冻结整个程序,我就做不到。
我使用了Thread join方法和类似方法,但是我的应用程序完全死机了。
这是我的主班
private String genCmd2;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ConvertGUI window = new ConvertGUI();
window.frmConvert.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ConvertGUI() {
initialize();
}
private void initialize() {
// Execute a generated command concurrently
genCmd2 = "ping google.com -n 5";
executeCommand(genCmd2, genCmdTextArea);
//CODE TO RUN AFTER EXECUTE COMMAND IS FULLY FINISHED
//NOT RIGHT AFTER executeCommand method is called
}
public static void printToTheConsole(JTextArea console, String message) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
console.append(message);
console.validate();
}
});
}
private static void executeCommand(String command, JTextArea console) {
Runnable r = new CommandLineRunnable(command, console);
t = new Thread(r);
t.start();
}
我的Runnable类,它执行命令并将内容打印到控制台
public class CommandLineRunnable extends ConvertGUI implements Runnable {
private String generatedCommand;
private JTextArea console;
public CommandLineRunnable(String command, JTextArea console) {
this.generatedCommand = command;
this.console = console;
printToTheConsole(console, command);
}
@Override
public void run() {
StringBuilder output = new StringBuilder();
BufferedReader reader;
Process process;
try {
process = Runtime.getRuntime().exec(generatedCommand);
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
printToTheConsole(console, line + "\n");
}
printToTheConsole(console, "\n--------------------------Success!--------------------------\n");
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
如果要打印到控制台,请在成功执行(未执行)一个Runnable#任务期间和之后更新JTextArea,您可以实现一个接口并将其提供给Runnables构造函数
请考虑以下示例,该示例以参数String'aCommand'作为命令,fa JTextArea对象'console'和新的ResponseEvent匿名类作为其参数来实例化CommandLineRunnable类。
请注意,由于匿名类中的重复项,如果您要执行多个命令,则可能不想多次实例化匿名类,而只需在函数接口的方法内部插入printToTheConsole代码
public static void main(String[] args) {
JTextArea console = new JTextArea();
/**
* JTextArea init code here
*/
executeCommand("aCommand", console, new ResponseEvent() {
@Override
public void onSuccess(JTextArea console, String response) {
printToTheConsole(console, response);
}
@Override
public void onUpdate(JTextArea console, String response) {
printToTheConsole(console, response);
}
@Override
public void onFailure(JTextArea console, String response) {
printToTheConsole(console, response);
}
});
}
private static void printToTheConsole(JTextArea console, String message) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
console.append(message);
console.validate();
}
});
}
private static void executeCommand(String command, JTextArea console, ResponseEvent event) {
Runnable r = new CommandLineRunnable(command, console, event);
Thread thread = new Thread(r);
thread.start();
}
@FunctionalInterface
private interface ResponseEvent {
default void onSuccess(JTextArea console, String response) {
}
default void onUpdate(JTextArea console, String response) {
}
default void onFailure(JTextArea console, String response) {
}
}
public static class CommandLineRunnable implements Runnable {
private final String command;
private final ResponseEvent event;
private final JTextArea console;
public CommandLineRunnable(String command, JTextArea console, ResponseEvent event) {
this.command = command;
this.console = console;
this.event = event;
}
public ResponseEvent getEvent() {
return event;
}
@Override
public void run() {
Process process;
BufferedReader reader = null;
try {
process = Runtime.getRuntime().exec(getCommand());
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
getEvent().onUpdate(getConsole(), line + "\n");
}
getEvent().onSuccess(getConsole(), "\n--------------------------Success!--------------------------\n");
} catch (IOException e) {
getEvent().onFailure(getConsole(), "\n--------------------------Failure!--------------------------\n");
}
}
private JTextArea getConsole() {
return console;
}
private String getCommand() {
return command;
}
}
一旦执行,可能在任何时间执行Runnable#run()函数。
代码将运行,并且ResponseEvent#onSuccess方法或ResponseEvent#onFailure方法将运行被称为
,然后可以根据需要处理响应,也许可以通过更新您的JTextAreas之一来实现