Могу ли я найти ширину консоли с помощью Java?

Есть ли способ найти ширину консоли, на которой запущена моя программа Java?

Я бы хотел, чтобы это было кросс-платформой, если это возможно …

У меня нет желания изменять ширину буфера или windows, я просто хочу узнать его ширину, чтобы я мог правильно форматировать текст, который печатается на экране.

Нет надежных кросс-платформенных решений этой проблемы. Действительно, бывают ситуации, когда невозможно узнать, какова реальная ширина консоли.

Например, в системе Linux вы обычно можете узнать условные размеры терминала из переменных среды LINES и COLUMNS. Хотя эти переменные автоматически обновляются при изменении размеров окон «эмулятора терминала», это не всегда так. В самом деле, в случае удаленной консоли, подключенной по протоколу telnet, нет способа получить фактические размеры терминала в оболочке пользователя.

EDIT : просто добавьте, что если пользователь изменит размеры своего xterm в Linux после запуска Java-приложения, приложение Java не будет уведомлено, и оно не увидит новые измерения, отраженные в его копии LINES и переменные окружения COLUMNS!

EDIT 2 : Моя ошибка, они являются переменными оболочки bash , но не экспортируются в среду по умолчанию. Вы можете «исправить» это, выполнив export COLUMNS LINES перед запуском приложения Java.

На самом деле, Java-библиотека уже существует для этого в Java: JLine 2 . (В SourceForce есть старая версия, но эта ссылка на GitHub кажется последней.)

Это работало для меня под Linux (Mint 14) и Windows (я не знаю, какую версию), используя JLine 2.11:

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

JLine обещает работать и на Mac.

Я обнаружил, что он возвращает плохую ширину (например, 1 !) Под консолью Eclipse (но даже родная консоль Java не работает под Eclipse!) И, к сожалению, под Cygwin. Но я работал над этим с кодом, который проверяет необоснованные значения ( < 10 ) и просто использует 80 в этих случаях.

Обновление для JLine 3 (за метку -thanks, mate!):

 terminalWidth = org.jline.terminal.TerminalBuilder.terminal().getWidth() 

Изменить: см. Комментарий @ dave_thompson_085 о ProcessBuilder , поскольку это почти наверняка лучший подход.

Еще один ответ упоминал о запуске tput cols в скрипте перед началом вашей команды. Но если вы хотите запустить это после того, как Java уже запущена, используя Runtime.getRuntime().exec() , вы обнаружите, что tput не может разговаривать с вашим терминалом, поскольку Java перенаправляет stdout и stderr. В качестве обходного решения, не используемого для всех, вы можете использовать устройство magical /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.

Java 6 имеет class java.io.Console, но, к сожалению, он не обладает требуемой функциональностью. Получение ширины windows консоли невозможно в стандартной библиотеке Java и чистой межплатформенной Java.

Вот альтернативная консольная библиотека Java, которая позволяет получить размер экрана, но включает в себя DLL, специфичную для Windows. Возможно, вы сможете взять исходный код и скомпилировать часть C в общую библиотеку Linux или Mac OS X, чтобы она также работала на этих платформах.

Раньше я работал над этой проблемой. Я использую несколько разных методов. Однако сложно иметь по-настоящему кросс-платформенное решение.

Я попытался сделать что-то вроде этого:

 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"); 

Вы можете читать / тестировать и добавлять «экспорт COLUMNS» в файл .bashrc в каждом домашнем каталоге пользователей Linux с помощью метода String.contains («export COLUMNS») и свойства user.dir.

Это позволит вам загружать столбцы каждый раз при запуске приложения 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); } } 

Другой вариант, который у вас есть, – выполнить yor Java.jar с помощью скрипта bash при запуске. Внутри скрипта вы можете использовать «tput cols» для получения ширины. Затем передайте это значение вашему Java-приложению как String [] arg.

Вот так:

 //#!/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, похоже, имеет хорошее решение: 11.9.3. Запрос размера выходного терминала . Я бы не задерживал дыхание, ожидая, что это будет доступно в основной Java, но вы можете использовать Jython для обеспечения доступности функций Python.

Для меня единственный способ получить представление о окне терминала (все еще неверно, когда изменяется размер windows) – использовать команду, например

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

При запуске без части cmd.exe это показывает, что команда не найдена. Также обратите внимание на часть redirectError . Если не используется, тогда будет использоваться размер вывода Java, а не фактический. Только с этой комбинацией можно было захватить фактический размер.

  • Перенаправить вывод консоли в текстовое поле в отдельной программе
  • Скрыть пользовательский ввод при запросе пароля
  • Какая хорошая Java, curses-like, библиотека для терминальных приложений?
  • Оранжевый цвет текста в приложении консоли C #?
  • Где читать консольные сообщения из background.js в расширении Chrome?
  • Захват вывода консоли из приложения .NET (C #)
  • Зачем использовать LDR поверх MOV (или наоборот) в сборке ARM?
  • Как я могу проверить ввод консоли как целые числа?
  • Как увеличить емкость консоли вывода Eclipse?
  • Почему регистратор ARM PC указывает на инструкцию после следующего запуска?
  • Перенаправить вывод консоли в строку в java
  • Давайте будем гением компьютера.