如何通过swing GUI打开任何命令行程序并将命令传递给它?

时间:2013-06-12 07:32:57

标签: java swing command-line command processbuilder

我基本上想要使用Swing将命令行程序转换为gui程序。一旦用户按下适当的按钮,GUI就应该将相应的命令传递给命令行程序。如果我们可以在不显示命令行程序的情况下执行此操作,那么它将完全取代该程序。

我过去两天一直试图在互联网上搜索这个,我只发现Runtime.getRuntime()。exec(cmd)命令对打开命令提示符并打开命令行程序很有用,但是命令无法进一步传递给提示,不能对该程序执行进一步操作。 请帮助。

1 个答案:

答案 0 :(得分:3)

我实际上会避免通过命令提示符并直接调用命令行程序。您所要做的就是找到您的计划所在的位置。

需要考虑的一些事项:

  • 您应该在EDT(事件调度线程)之外执行命令,以避免GUI冻结(SwingWorker将做得很好)
  • 而是使用ProcessBuilder而不是RuntimeExec

以下是调用命令java -version的此类代码的示例(仅用于使用ProcessBuilder API的示例):

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;

public class TestRuntimeExec {

    private JButton executeButton;

    protected void initUI() {
        final JFrame frame = new JFrame();
        frame.setTitle(TestRuntimeExec.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        executeButton = new JButton("Clik me to execute command");
        executeButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                doWork();
            }
        });
        frame.add(executeButton, BorderLayout.SOUTH);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    protected void doWork() {
        SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
            @Override
            protected String doInBackground() throws Exception {
                ProcessBuilder builder = new ProcessBuilder(System.getProperty("java.home") + "/bin/java", "-version");
                builder.redirectErrorStream(true);
                Process process = builder.start();
                ConsoleReader consoleReader = new ConsoleReader(process.getInputStream());
                consoleReader.start();
                int waitFor = process.waitFor();
                consoleReader.join();
                switch (waitFor) {
                case 0:
                    return consoleReader.getResult();
                default:
                    throw new RuntimeException("Failed to execute " + builder.command() + " \nReturned message: "
                            + consoleReader.getResult());
                }
            }

            @Override
            protected void done() {
                try {
                    showCommandResult(get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                    showCommandError(e);
                }
            }
        };
        worker.execute();
    }

    protected void showCommandError(ExecutionException e) {
        JOptionPane.showMessageDialog(executeButton, e.getMessage(), "An error has occured", JOptionPane.ERROR_MESSAGE);
    }

    protected void showCommandResult(String commandResult) {
        JOptionPane.showMessageDialog(executeButton, commandResult);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestRuntimeExec().initUI();
            }
        });
    }

    public static class ConsoleReader extends Thread {
        private InputStream is;

        private StringWriter sw;

        ConsoleReader(InputStream is) {
            this.is = is;
            sw = new StringWriter();
        }

        @Override
        public void run() {
            try {
                int c;
                while ((c = is.read()) != -1) {
                    sw.write(c);
                }
            } catch (IOException e) {
                ;
            }
        }

        String getResult() {
            return sw.toString();
        }
    }
}