我可以用 Java 找到控制台宽度吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1286461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I find the console width with Java?
提问by masher
Is there a way to find the width of the console in which my Java program is running?
有没有办法找到运行我的 Java 程序的控制台的宽度?
I would like this to be cross platform if possible...
如果可能的话,我希望这是跨平台的......
I have no desire to change the width of the buffer or the window, I just want to know its width so I can properly format text that is being printed to screen.
我不想改变缓冲区或窗口的宽度,我只想知道它的宽度,这样我就可以正确格式化正在打印到屏幕的文本。
采纳答案by Stephen C
There are no reliablecross-platform solutions to this problem. Indeed, there are situations where it is not possible to know what the real console width is.
这个问题没有可靠的跨平台解决方案。事实上,在某些情况下无法知道真正的控制台宽度是多少。
For example, on a Linux system you can typically find out the notional terminal dimensions from the LINES and COLUMNS environment variables. While these variables are automatically updated when you resize some "terminal emulator" windows, this is not always the case. Indeed, in the case of a remote console connected via telnet protocol, there is no way to get the actual terminal dimensions to the user's shell.
例如,在 Linux 系统上,您通常可以从 LINES 和 COLUMNS 环境变量中找出名义上的终端维度。虽然这些变量会在您调整某些“终端模拟器”窗口的大小时自动更新,但情况并非总是如此。实际上,在通过 telnet 协议连接的远程控制台的情况下,无法获得用户 shell 的实际终端尺寸。
EDIT: Just to add that if the user changes the dimensions of his/her xterm on Linux after launching a Java app, the Java app won't be notified, and it won't see the new dimensions reflected in its copy of the LINES and COLUMNS environment variables!
编辑:只是补充一点,如果用户在启动 Java 应用程序后在 Linux 上更改了他/她的 xterm 的维度,则不会通知 Java 应用程序,并且不会看到反映在其 LINES 副本中的新维度和 COLUMNS 环境变量!
EDIT 2: My mistake, they are bash
shell variables, but are not exported to the environment by default. You can "fix" this by running export COLUMNS LINES
before you run your Java application.
编辑 2:我的错误,它们是bash
shell 变量,但默认情况下不会导出到环境中。您可以通过export COLUMNS LINES
在运行 Java 应用程序之前运行来“修复”这个问题。
回答by Jesper
Java 6 has a class java.io.Console, but it unfortunately lacks the functionality you're asking for. Getting the console window width is not possible with the standard Java library and pure, cross-platform Java.
Java 6 有一个类 java.io.Console,但不幸的是它缺少您所要求的功能。使用标准 Java 库和纯跨平台 Java 无法获得控制台窗口宽度。
Here is an alternative Java console librarywhich allows you to get the screen size, but it includes a Windows-specific DLL. You might be able to take the source code and compile the C part into a Linux or Mac OS X shared library, so that it will work on those platforms as well.
这是一个替代的Java 控制台库,它允许您获取屏幕大小,但它包含一个特定于 Windows 的 DLL。您可以获取源代码并将 C 部分编译到 Linux 或 Mac OS X 共享库中,以便它也能在这些平台上运行。
回答by aubreybourke
I have been working on this problem before. I use a couple of different techniques. However it is difficult to have a truly cross platform solution.
我以前一直在研究这个问题。我使用了几种不同的技术。然而,很难有一个真正的跨平台解决方案。
I tried doing try something like this:
我试着做这样的尝试:
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");
You can read/test and append "export COLUMNS" to the .bashrc file in every Linux users home directory with the String.contains("export COLUMNS") method and the user.dir property.
您可以使用 String.contains("export COLUMNS") 方法和 user.dir 属性读取/测试并将“export COLUMNS”附加到每个 Linux 用户主目录中的 .bashrc 文件。
That would allow you to get the columns to load up every time the java app starts up.
这将允许您在每次 Java 应用程序启动时加载列。
Then I would pass it to a temp file. Like this:
然后我会将它传递给一个临时文件。像这样:
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);
}
}
Another option you have is to execute yor Java.jar with a bash script at startup. Inside the script you can use "tput cols" to get the width. Then pass that value to your Java app as a String[] arg.
您的另一个选择是在启动时使用 bash 脚本执行您的 Java.jar。在脚本中,您可以使用“tput cols”来获取宽度。然后将该值作为 String[] arg 传递给您的 Java 应用程序。
Like so:
像这样:
//#!/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
why is this such a difficult task with Java? Obviously a good place to write a good API. I guess we could try Apache.commons.exec as well?
为什么这对 Java 来说是一项如此艰巨的任务?显然是编写好的 API 的好地方。我想我们也可以试试 Apache.commons.exec 吗?
回答by Hyman O'Connor
Edit: See @dave_thompson_085's comment about ProcessBuilder
, as that's almost certainly a better approach.
编辑:请参阅@dave_thompson_085 关于 的评论ProcessBuilder
,因为这几乎肯定是更好的方法。
Another answer mentioned running tput cols
in a script before you start your command. But if you want to run that after Java has already started, using Runtime.getRuntime().exec()
, you'll find that tput can't talk to your terminal, because Java has redirected stdout and stderr. As a not-at-all-portable workaround, you can use the magical /dev/tty
device, which refers to the terminal of the current process. That lets you run something like this:
另一个答案提到tput cols
在启动命令之前在脚本中运行。但是,如果您想在 Java 已经启动后运行它,使用Runtime.getRuntime().exec()
,您会发现 tput 无法与您的终端通信,因为 Java 已重定向 stdout 和 stderr。作为一个完全不可移植的解决方法,您可以使用魔法/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
This works for me on Linux, but I wouldn't expect it to work everywhere. It will hopefully work on Mac. It definitely won't work on Windows, though it might with Cygwin.
这在 Linux 上对我有用,但我不希望它在任何地方都有效。它有望在 Mac 上运行。它绝对不能在 Windows 上工作,尽管它可能与 Cygwin 一起使用。
回答by Michael Scheper
Python seems to have a good solution: 11.9.3. Querying the size of the output terminal. I wouldn't hold my breath waiting for this to be available in core Java, but you might be able to use Jythonto make the Python functionality available.
Python 似乎有一个很好的解决方案:11.9.3。查询输出终端的大小。我不会屏住呼吸等待它在核心 Java 中可用,但您也许可以使用Jython使 Python 功能可用。
回答by Michael Scheper
Actually, a Java library already exists to do this in Java: JLine 2. (There's an old version on SourceForce, but that link to GitHub seems to be the latest.)
实际上,在 Java 中已经存在一个 Java 库来执行此操作:JLine 2。(SourceForce 上有一个旧版本,但指向 GitHub 的链接似乎是最新的。)
This worked for me under Linux (Mint 14) and Windows (I don't know what version), using JLine 2.11:
这在 Linux(Mint 14)和 Windows(我不知道什么版本)下对我有用,使用 JLine 2.11:
terminalWidth = jline.TerminalFactory.get().getWidth();
JLine promises to work on Mac, too.
JLine 也承诺在 Mac 上工作。
I've found that it returns bad widths (like 1
!) under the Eclipse console (but even Java's native Console doesn't work under Eclipse!), and, unfortunately, under Cygwin. But I've worked around this with code that checks for unreasonable values (< 10
) and just uses 80 in those cases.
我发现它1
在 Eclipse 控制台下返回错误的宽度(例如!)(但即使是 Java 的本机控制台在 Eclipse 下也不工作!),不幸的是,在 Cygwin 下。但是我已经使用检查不合理值 ( < 10
) 的代码解决了这个问题,并且在这些情况下只使用了 80。
Update for JLine 3(per Mark—thanks, mate!):
JLine 3 的更新(根据Mark—谢谢,伙计!):
terminalWidth = org.jline.terminal.TerminalBuilder.terminal().getWidth()
回答by Panayotis
For me, the only way to get an idea of the terminal window (still not correct when the window resizes) is to use a command like
对我来说,了解终端窗口的唯一方法(调整窗口大小时仍然不正确)是使用类似的命令
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "mode con");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
When run without the cmd.exe
part, it shows that the command could not be found. Also note the redirectError
part. If not used then the Java output size will be used, not the actual one. Only with this combination it was possible to grab the actual size.
在没有cmd.exe
零件的情况下运行时,它显示找不到该命令。还要注意redirectError
部分。如果未使用,则将使用 Java 输出大小,而不是实际大小。只有通过这种组合,才有可能获得实际尺寸。
回答by Arne Brasseur
There's a trick that you can use based on ANSI Escape Codes. They don't provide a direct way to query the console size, but they do have a command for requesting the current cursor position. By moving the cursor to a really high row and column and then requesting the cursor position you can get an accurate measurement.
您可以根据ANSI Escape Codes使用一个技巧。它们不提供查询控制台大小的直接方法,但它们确实提供了用于请求当前光标位置的命令。通过将光标移动到非常高的行和列,然后请求光标位置,您可以获得准确的测量结果。
Combine this with commands to store/restore the cursor position, as in the following example:
将此与命令结合以存储/恢复光标位置,如下例所示:
Send the following sequences to the terminal (stdout)
将以下序列发送到终端 (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
Now watch stdin, you should receive a sequece that looks like \u001b[25;80R"
, where 25 is the row count, and 80 the columns.
现在观察标准输入,您应该会收到一个类似于 的序列\u001b[25;80R"
,其中 25 是行数,80 是列数。
I first saw this used in the Lanternalibrary.
我第一次看到这个是在Lanterna库中使用的。