linux上でGraphicsを使用した部分で,InternalErrorが発生する問題
Graphicsを使用して,グラフを描く処理が入っているソースをlinux上で動かそうとしたところ,以下のようなエラーが発生.
java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:134)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:141)
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62)
java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1041)
(以下略)
回避方法としては,実行時のオプションとして,「-Djava.awt.headless=true」を追加する.
例:
# javac SampleIMGCreate.java
# java -Djava.awt.headless=true SampleIMGCreate
などと書いたものの,単体駆動なんてまずしないだろうから,Tomcatサーバ上で動かしている場合は,Tomcat実行ユーザの環境変数にこのオプションを追加し,Tomcatを再起動すれば良い.
# export CATALINA_OPTS="-Djava.awt.headless=true"
参考URL:http://java.sun.com/j2se/1.4.2/docs/guide/awt/AWTChanges.html#headless
linux上でjava.awt.Graphicsを使って表示した日本語が文字化け
先の対処で実行時エラーは解消して,絵が表示されるようになったものの,今度は日本語部分が文字化け.(Windows環境下では問題なかったのに…)
g.drawString()とかで表示する日本語部分が→「□□□」みたいな感じに化けてしまう.
原因は,linuxデフォルトのフォントが日本語に対応していないからというもの.
よーするに,Graphicsオブジェクトに対して,どのFontを使うかを明示的に指定しないとダメなのでした.(WindowsではたまたまデフォルトのFontが日本語に対応していただけのハナシ)
指定しない場合はその実行環境デフォルトのFontが採用されてしまう.
というわけで,
- その実行環境で対応しているFont一覧を取得
- それらのうち日本語表示に対応しているものを見つける
- 日本語に対応したFontをGraphicsオブジェクトに指定する
という手順を踏まねばならない.
サンプルは以下のとおり,
(前略)
//インストールされている全てのFontを取得
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();//その中から日本語に対応したものを抽出
ArrayList fontList = new ArrayList();
for(int i = 0; i < fonts.length; i++){
if(fonts[i].canDisplay('日')){
fontList.add(fonts[i]);
}
}//抽出したFontの中に、MS Gothic(Windowsならたいていあるはず)が入っていればそれを採用,
//なければ「Kochi Gothic」(linuxに入っている)を採用
//それもなければ,何でもいいから日本語に対応しているFontを採用
Iterator itr = fontList.iterator();
while(itr.hasNext()){
Font f = (Font)itr.next();
if(f.getName().equals("MS Gothic")){
g.setFont(new Font(f.getName(), Font.PLAIN, 12));
break;
} else if (f.getName().equals("Kochi Gothic")){
g.setFont(new Font(f.getName(), Font.PLAIN, 12));
break;
} else {
g.setFont(new Font(f.getName(), Font.PLAIN, 12));
}
}
(後略)
これはあくまでもサンプルで,これやるとちょっと処理時間がかかる….
続きを読む