2009-08-17 8 views
28

私のJavaプログラムが実行されているコンソールの幅を見つける方法はありますか?可能であればコンソールの幅をJavaで見つけることはできますか?

私は、これはクロスプラットフォームになりたい...

私は、バッファの幅またはウィンドウを変更する欲求を持っていない、私はちょうど私が正しくそのテキストの書式を設定することができますので、その幅を知りたいですがスクリーンに印刷されています。

答えて

23

この問題に対する信頼できるクロスプラットフォームソリューションはありません。実際、実際のコンソール幅が何であるかを知ることができない状況があります。

例えば、Linuxシステム上で、あなたは通常、LINESとCOLUMNS環境変数からの想定元本の端子寸法を見つけることができます。これらの変数は、「端末エミュレータ」ウィンドウのサイズを変更すると自動的に更新されますが、必ずしもそうであるとは限りません。実際に、Telnetプロトコルを介して接続されたリモートコンソールの場合、ユーザーのシェルに実際の端末の寸法を取得する方法はありません。

EDIT:ただ、ユーザーがJavaアプリを起動した後、Linux上で彼/彼女のxtermの寸法を変更した場合、Javaアプリケーションが通知されないことを追加し、それが反射し、新たな次元を見ることはありませんLINESとCOLUMNS環境変数のコピーに!

EDIT 2:私の誤りは、bashシェル変数ですが、デフォルトでは環境にエクスポートされません。 Javaアプリケーションを実行する前にexport COLUMNS LINESを実行することで、この問題を「修正」できます。

+0

幅や高さなどを返すものがあればいいと思っていました。ようこそハードコードされた定数! – masher

+0

@masher:問題は、Linuxでは、ほとんどの場合、「必ず確実に判断できない」ということです。 –

+0

私はSystemでこれをやろうとしました。getenv( "COLUMNS")がnullを返しました。 Ubuntu 10.04/GNOME 2.30.2 – jsj

4

のJava 6がjava.io.Consoleクラスを持っているが、それは残念ながらあなたが求めている機能を欠いています。コンソールウィンドウの幅を取得することは、標準のJavaライブラリと純粋なクロスプラットフォームのJavaでは不可能です。

は、ここでは、画面サイズを取得することができます代替Java console libraryですが、それはWindows固有のDLLが含まれています。ソースコードを入手してC言語の部分をLinuxまたはMac OS Xの共有ライブラリにコンパイルして、それらのプラットフォームでも動作するようにすることができます。

+0

私はコンソールAPIを見つけて興奮しました。そして、私はそうではありませんでした... 私がしたいことについては、Cとクロスコンパイルの方法を学ぶことは、壊れたボールで釘を打つようなものです。 – masher

+0

@Jesper - それは本当にJavaの欠陥ではありません。 Linux/Unixマシンでは、すべての場合に現在のコンソールサイズを取得することが不可能になることがたくさんあります。 –

1

私は以前この問題に取り組んできました。私はいくつかの異なる技術を使用しています。しかし、真にクロスプラットフォームのソリューションを持つことは困難です。

私はこのような試みの何かをやってみました:

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(「輸出COLUMNSを持つすべてのLinuxユーザのホームディレクトリの.bashrcファイルに「輸出COLUMNS」を追加することができます")メソッドとuser.dirプロパティです。

これは、javaアプリケーションが起動するたびにロードするようにすることができます。

次に、それを一時ファイルに渡します。このように:

起動時に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も試してみることができると思いますか?

+2

Javaプロセスが起動する前に 'export COLUMNS'が呼び出された場合は、単純に' System.getenv( "COLUMNS") '; 'ProcessBuilder'でサブプロセスを起動する必要はありません。 – dimo414

8

編集:@ dave_thompson_085のコメントProcessBuilderを参照してください。これはほぼ確実なアプローチです。

コマンドを開始する前に、スクリプトでtput colsを実行しているとの別の回答がありました。しかし、Javaがすでに起動した後にRuntime.getRuntime().exec()を使用して実行したい場合は、Javaがstdoutとstderrをリダイレクトしているため、tputは端末と通信できません。ポータブルではない回避策として、現在のプロセスの端末を指す魔法の/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でもうまくいきます。それはCygwinで可能かもしれませんが、間違いなくWindowsでは動作しません。

+2

Macでも動作します – pascal

+0

これは私にとっては唯一の解決策です。 – Panayotis

+1

'ProcessBuilder' Java7(2011)は、デフォルトのリダイレクトされたパイプの代わりにJavaのstdin/out/errを子プロセスに渡すことができます。 'inheritIO()'と 'redirect *(Redirect.INHERIT)'を参照してください。これは 'java'自体がユーザによってリダイレクトされている場合には役に立ちませんが、その場合はなぜI/Oデバイスを使用していますか? –

0

Pythonは良い解決策を持っているようです:11.9.3. Querying the size of the output terminal。私はコアJavaでこれが利用可能になるのを待っていませんが、Jythonを使用してPythonの機能を利用できるようにすることができます。

+0

'shutil'ドキュメントに言及すると、これは[os.get_terminal_size()'](https://docs.python.org/3.5/library/os.html#os.get_terminal_size)に落ちます。これはOS- (https://hg.python.org/cpython/file/3.5/Modules/posixmodule.c#l11128)をCで実装しています.Jythonを使用すると、いくつかのユースケースで動作する可能性がありますが、かなり重いハンマーです。 – dimo414

13

実際にJavaでこれを行うには、JavaライブラリJLine 2が存在します。

これはJLine 2.11を使って、Linux(Mint 14)とWindows(私はどのバージョンがわからないのですか)の下で私の仕事をしてくれました:(sourceforceの古いバージョンですが、

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

JLineもMacで動作することを約束します。

私はEclipseコンソールの下で(たとえJavaのネイティブコンソールでさえもEclipseではうまくいきません!)、残念ながらCygwinの下で、悪い幅を返します(1!)。しかし、私は不合理な値(< 10)をチェックし、そのような場合に80を使用するコードでこれを解決しました。私にとって

+3

Unixでは、JLineは[TerminalLineSetting']( 'https://github.com/jline/jline2/blob/master/src/main/java/jline/internal/TerminalLineSettings.java ')で単に' stty -a'を呼び出します。 Windowsでは 'org.fuseource.jansi.internal.WindowsSupport'を介してJAnsiライブラリのクローズドソース部分にフックします。 – dimo414

0

、(ウィンドウのサイズが変更するとき、まだ訂正していない)ターミナルウィンドウのアイデアを得るための唯一の方法は、それがあることを示し、cmd.exe部分なしで実行すると

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

のようなコマンドを使用することですコマンドが見つかりませんでした。また、redirectError部分にも注意してください。使用されていない場合、実際の出力サイズではなくJava出力サイズが使用されます。この組み合わせでのみ、実際のサイズを取得することができました。

関連する問題