我可以用Javafind控制台宽度吗?
有没有办法find我的Java程序正在运行的控制台的宽度?
如果可能的话,我希望这是跨平台的…
我不想改变缓冲区或窗口的宽度,我只是想知道它的宽度,所以我可以正确地格式化正在打印到屏幕上的文本。
这个问题没有可靠的跨平台解决scheme。 事实上,在某些情况下,无法知道真正的控制台宽度是多less。
例如,在Linux系统上,您通常可以从LINES和COLUMNS环境variables中find概念terminal维度。 当您调整某些“terminal模拟器”窗口的大小时,这些variables会自动更新,但情况并非总是如此。 事实上,在通过telnet协议连接的远程控制台的情况下,无法将实际的terminal尺寸获得给用户的shell。
编辑 :只需要添加,如果用户在启动Java应用程序后在Linux上更改他/她的xterm的尺寸,则Java应用程序将不会被通知,并且不会看到在其LINES副本中反映的新尺寸和COLUMNS环境variables!
编辑2 :我的错误,他们是bash
shellvariables,但不会导出到默认情况下的环境。 在运行Java应用程序之前,可以通过运行export COLUMNS LINES
来“解决”这个问题。
实际上,在Java中已经存在一个Java库: JLine 2 。 (SourceForce上有一个旧版本,但与GitHub的链接似乎是最新版本。)
这对我在Linux(Mint 14)和Windows(我不知道什么版本)下使用JLine 2.11:
terminalWidth = jline.TerminalFactory.get().getWidth();
JLine也承诺在Mac上工作。
我发现它在Eclipse控制台下返回了不好的宽度(比如1
!)(但是即使Java的本地控制台也不能在Eclipse下工作!),不幸的是在Cygwin下。 但是我已经用这个代码检查了不合理的值( < 10
),并在这种情况下使用了80。
编辑:请参阅@ dave_thompson_085关于ProcessBuilder
的评论,因为这几乎肯定是一个更好的方法。
在开始命令之前提到的另一个回答是在脚本中inputtput cols
。 但是如果你想在Java启动之后运行它,使用Runtime.getRuntime().exec()
,你会发现tput不能和你的terminal通信,因为Java已经redirect了stdout和stderr。 作为一个不可移植的解决方法,您可以使用神奇的/dev/tty
设备,它指向当前进程的terminal。 这可以让你运行这样的东西:
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上工作,尽pipe它可能与Cygwin。
Java 6有一个类java.io.Console,但不幸的是缺less你所要求的function。 使用标准的Java库和纯粹的跨平台Java来获得控制台窗口宽度是不可能的。
下面是一个替代的Java控制台库 ,它允许您获得屏幕大小,但是它包含一个Windows特定的DLL。 你也许可以把源代码编译成一个Linux或Mac OS X共享库,这样它也可以在这些平台上工作。
我之前一直在处理这个问题。 我使用了几种不同的技术。 但是真正有跨平台的解决scheme是很困难的。
我试着做这样的事情:
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属性读取/testing并将“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脚本执行Java.jar。 在脚本里面你可以使用“tput cols”来获得宽度。 然后将该值作为String [] 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?
Python似乎有一个很好的解决scheme: 11.9.3。 查询输出terminal的大小 。 我不会屏住呼吸等待核心Java中可用,但您可能能够使用Jython使Pythonfunction可用。
对于我来说,获得terminal窗口的概念(当窗口resize时仍然不正确)的唯一方法是使用像
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "mode con"); pb.redirectError(ProcessBuilder.Redirect.INHERIT);
当没有cmd.exe
部分运行时,它显示找不到该命令。 另请注意redirectError
部分。 如果不使用,则将使用Java输出大小,而不是实际的大小。 只有使用这种组合,才有可能获得实际的尺寸。