【问题标题】:How do you call a text UI (whiptail or dialog) within a Java application?如何在 Java 应用程序中调用文本 UI(鞭尾或对话框)?
【发布时间】:2017-12-06 21:18:23
【问题描述】:

有两个 Linux 命令行程序(whiptaildialog)可以向用户显示文本 UI。我想从我的 Java 应用程序中调用其中一个(最好是whiptail),以便用户可以从预定义的列表中选择一个选项。以下 SO 问题有助于我弄清楚如何从我的代码中调用 Linux 命令:

How to run linux commands in java code?

Want to invoke a linux shell command from Java

这些提供了有关如何运行典型 Linux 命令(例如“ls”)的有用提示,但由于我希望向用户显示文本 UI,我的情况稍微复杂一些(我认为)。

要了解whiptail 的作用和外观,请参阅this

【问题讨论】:

  • 我知道这是您的第一篇文章;欢迎来到!对于这个论坛,“我该怎么做”问题往往过于模糊。通常,你会尝试一些东西,展示一些代码,然后询问它为什么会或没有按照你的期望做。本着这种精神,试着简单地调用whiptail,看看你能不能让它显示出来。然后,您可能会弄乱返回结果。顺便说一句,JOptionPane 在您的代码中执行类似的功能。你必须做一些 Swing 编程才能做你想做的事,但这最终可能会更容易。

标签: java linux dialog whiptail


【解决方案1】:

ProcessBuilder 开头。您要发送命令的每个参数都是命令列表中的一个单独元素,例如...

import java.io.IOException;
import java.io.InputStream;

public class Test {

    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder(
                "whiptail", "--title", "Check list example", " --checklist",
                "Choose user's permissions", "20", "78", "4",
                "NET_OUTBOUND", "Allow connections to other hosts", "ON",
                "NET_INBOUND", "Allow connections from other hosts", "OFF",
                "LOCAL_MOUNT", "Allow mounting of local devices", "OFF",
                "REMOTE_MOUNT", "Allow mounting of remote devices", "OFF");
        pb.redirectInput(Redirect.INHERIT);
        // I tend to use pb.redirectErrorStream(true);
        // which sends the error stream to the input stream, but
        // then you'd need to still consume it to get the result
        Process p = pb.start();
        InputStreamConsumer errorConsumer = new InputStreamConsumer(p.getErrorStream());

        Scanner input = new Scanner(System.in);
        String option = input.nextLine();

        p.getOutputStream().write(option.getBytes());
        p.getOutputStream().flush();

        int exitCode = p.waitFor();
        System.out.println(exitCode);

        errorConsumer.join();

        System.out.println(errorConsumer.getContent());
    }

    public static class InputStreamConsumer extends Thread {

        private InputStream is;
        private StringBuilder content;

        public InputStreamConsumer(InputStream is) {
            this.is = is;
            content = new StringBuilder(128);
        }

        public String getContent() {
            return content.toString();
        }

        @Override
        public void run() {

            try {
                int value = -1;
                while ((value = is.read()) != -1) {
                    content.append((char)value);
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }

        }

    }
}

这是非常基本的,它只是执行命令,将其输出消耗到StringBuilder(稍后检索),等待命令存在并显示基本结果。

由于我无权访问whiptail,我无法测试代码,但如果该命令在操作系统的默认搜索路径中可用,它应该可以工作,否则您需要提供命令的路径作为命令列表中第一个元素的一部分

【讨论】:

  • 这可以通过删除 InputStreamConsumer 并改用 pb.inheritIO(); 来简化。
  • @VGR 是的,我是老派......和控制狂:P
  • 另一方面,它不会执行 OP 的要求,因为它不会在 终端 中运行。
  • @ThomasDickey 这将取决于 OP 是否从控制台运行代码 - 由于未提供该信息,我只专注于尝试提供特定问题的答案
  • 我很好奇为什么这会引起反对 - 它不提供执行请求命令的解决方案吗?可以用不同的方式或更好的方式来完成吗?为什么可以改进?
猜你喜欢
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多