代码之家  ›  专栏  ›  技术社区  ›  masher

我能用Java找到控制台宽度吗?

  •  31
  • masher  · 技术社区  · 17 年前

    有没有办法找到我的Java程序运行的控制台的宽度?

    如果可能的话,我希望这是跨平台的…

    我不想更改缓冲区或窗口的宽度,我只想知道它的宽度,这样我就可以正确地格式化正在打印到屏幕上的文本。

    8 回复  |  直到 7 年前
        1
  •  24
  •   Stephen C    12 年前

    没有 可靠的 这个问题的跨平台解决方案。实际上,在某些情况下,不可能知道真正的控制台宽度是多少。

    例如,在Linux系统上,通常可以从行和列环境变量中找到概念性的终端维度。当您调整某些“终端模拟器”窗口的大小时,这些变量会自动更新,但情况并非总是如此。事实上,对于通过telnet协议连接的远程控制台,没有办法获得用户外壳的实际终端尺寸。

    编辑 只需补充一点,如果用户在启动Java应用程序后在Linux上改变他/她的XTYNE的尺寸,Java应用程序就不会被通知,而且它不会看到新的维度反映在其行和列环境变量的副本中。

    编辑2 :是我的错 bash shell变量,但默认情况下不会导出到环境中。你可以通过运行来“修复”这个问题 export COLUMNS LINES 在运行Java应用程序之前。

        2
  •  17
  •   Michael Scheper    8 年前

    实际上,Java库已经存在于Java中: JLine 2 . (在sourceforce上有一个旧版本,但到github的链接似乎是最新的。)

    这在Linux(Mint14)和Windows(我不知道哪个版本)下对我很有效,使用jline 2.11:

    terminalWidth = jline.TerminalFactory.get().getWidth();
    

    jline也承诺在Mac上工作。

    我发现它会返回错误的宽度(比如 1 !)在Eclipse控制台下(但即使Java的本地控制台在伊柯丽斯下也不能工作)!不幸的是,在塞格温的统治下。但是我用代码来检查不合理的值( < 10 )在这些情况下只需要80个。

    更新jline 3 (每) Mark 谢谢,伙计!:

    terminalWidth = org.jline.terminal.TerminalBuilder.terminal().getWidth()
    
        3
  •  10
  •   Jack O'Connor    8 年前

    编辑:参见@dave_thompson_085的评论 ProcessBuilder 因为这几乎肯定是更好的方法。

    另一个答案提到了跑步 tput cols 在启动命令之前的脚本中。但是如果您想在Java已经启动之后运行它,请使用 Runtime.getRuntime().exec() 您会发现TPT无法与终端通信,因为Java已经重定向了STDUT和STDRR。作为一个完全不便携的解决方案,你可以使用魔法 /dev/tty 设备,指当前进程的终端。这样就可以运行类似的程序:

    Process p = Runtime.getRuntime().exec(new String[] {
        "bash", "-c", "tput cols 2> /dev/tty" });
    // Read the output of this process to get your terminal width
    

    这对我在Linux上很有用,但我不希望它在任何地方都能工作。希望它能在Mac上工作。它肯定不会在Windows上工作,尽管它可能与Cygwin一起工作。

        4
  •  4
  •   Jesper    17 年前

    Java 6有一个类java. Io.控制台,但不幸的是缺少您要的功能。使用标准的Java库和纯的跨平台Java,不可能获得控制台窗口宽度。

    这是另一种选择 Java console library 它允许您获取屏幕大小,但它包含一个特定于Windows的dll。您可能能够获取源代码并将C部分编译成Linux或MacOSX共享库,这样它也可以在这些平台上工作。

        5
  •  3
  •   marc_s MisterSmith    9 年前

    我以前一直在研究这个问题。我使用了两种不同的技巧。然而,很难找到真正的跨平台解决方案。

    我试过这样做:

    String os = System.getProperty("os.name").toLowerCase();
    
        //Windows
        if(os.contains("win")){
            System.out.append("Windows Detected");
            //set Windows Dos Terminal width 80, height 25
            Process p = Runtime.getRuntime().exec("mode 80, 25");
        }
        //Mac
        if(os.contains("mac")){
            System.out.println("Macintosh Detected");
            //... I dont know...try Google
        }
        //Linux
        if(os.contains("linux")){
            System.out.println("Linux Detected");
    

    您可以使用string.contains(“export columns”)方法和user.dir属性读取/测试并将“export columns”附加到每个Linux用户主目录中的.bashrc文件。

    这将允许您在每次Java应用程序启动时加载列。

    然后我把它传给临时文件。这样地:

    try {
        ProcessBuilder pb = new ProcessBuilder("bash","-c","echo $COLUMNS >/home/$USER/bin/temp.txt" );  
            pb.start();
    
        }catch (Exception e) {
            System.out.println("exception happened - here's what I know: ");
            e.printStackTrace();
            System.exit(-1);
        }
    }
    

    另一个选择是在启动时用bash脚本执行yor java.jar。在脚本中,可以使用“tput cols”获取宽度。然后将该值作为字符串[]ARG传递给Java应用程序。

    像这样:

    //#!/bin/bash
    
    //#clear the screen
    
    clear 
    
    //#get the console width and height
    
    c=$[$(tput cols)]
    
    l=$[$(tput lines)]
    
    //#pass the columns, lines and an optional third value as String[] args.
    
    java -jar ~/bin/Plus.jar $c $l $1
    

    为什么Java这么困难?显然是编写好API的好地方。我想我们也可以试试apache.commons.exec?

        6
  •  1
  •   Arne Brasseur    7 年前

    有一个技巧你可以根据 ANSI Escape Codes . 它们不提供直接查询控制台大小的方法,但是它们有一个命令来请求当前位置大小。通过将光标移动到一个非常高的行和列,然后请求控制台的大小,可以得到一个准确的测量值。

    将以下序列发送到终端(stdout)

    "\u001b[s"             // save cursor position
    "\u001b[5000;5000H"    // move to col 5000 row 5000
    "\u001b[6n"            // request cursor position
    "\u001b[u"             // restore cursor position
    

    现在看stdin,你应该收到一个看起来像 \u001b[25;80R" ,其中25是行计数,80是列。

    我第一次看到这个用在 Lanterna 图书馆。

        7
  •  0
  •   Michael Scheper    12 年前

    python似乎有一个很好的解决方案: 11.9.3. Querying the size of the output terminal . 我不会屏住呼吸等待这个在核心Java中可用,但是你也许可以使用。 Jython 使python功能可用。

        8
  •  0
  •   Panayotis    9 年前

    对于我来说,了解终端窗口的唯一方法(当窗口调整大小时仍然不正确)是使用如下命令

    ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "mode con");
    pb.redirectError(ProcessBuilder.Redirect.INHERIT);
    

    当跑步时没有 cmd.exe 部分,它显示找不到命令。还注意到 redirectError 部分。如果不使用,则将使用Java输出大小,而不是实际的输出大小。只有通过这种组合,才可能获得实际尺寸。

    推荐文章