AWTとSwingのペイント(paint)の仕組み Java API javadoc改善運動! Javaの手帖 Javaの手帖--GUI分冊 /ひとつ上をゆくJavaの教科書 「JavaServer Faces完全ガイド」補遺
javacのエラーメッセージ解説 「Javaの哲学」の恥かき 「Javaによるテキスト処理」の恥かき 「モア・サーブレット」の恥かき 恥かきのホームページ フォーラム「JavaBeginner」
UIDefaultsのkeyとデフォルト値「コア・サーブレット」の恥かき comp.lang.java.guiのFAQ日本語訳 「入門 正規表現」 「Javaネットワークプログラミングの真髄」 「Java並行処理プログラミング」

last update: 080609

Java GUIプログラミングの、とてもBasicなFAQ

--Java情報リンク集としても貴重--

原著者の快諾を得て、comp.lang.java.guiのFAQの日本語訳をここに掲出します。
From:Thomas Weidenfeller (nobody@ericsson.invalid)
Subject:comp.lang.java.gui FAQ
View: Complete Thread (** 件)
Original Format
Newsgroups:comp.lang.java.gui
Date:Wed, Jun 14 2006 1:22 pm
Version: $Revision: 1.20 $
Posting-Frequency: monthly
Copyright: Copyright (c) 2003 - 2006 Thomas Weidenfeller
---Copyrightについては本ページ最後の14章を見てください---
Maintainer: Thomas Weidenfeller. See below for mailing instructions.
Last-modified: $Date: 2006/06/09 15:03:56 $


                      comp.lang.java.gui FAQ

目次

1 はじめに
Q1.1 このページの目的と内容
Q1.2  ここにないものは何ですか?。
Q1.3 このFAQをどこでゲットできますか?
Q1.4 JavaのFAQはいろいろありますが, どれが正しくて公式のものですか?
Q1.5 SunはこのFAQをサポートまたは公認していますか?
Q1.6 このFAQに紹介されているリンクの一部は壊れています。紹介する前に確認しないん
ですか?
Q1.7 このFAQのWordバージョンなどはありますか?
Q1.8 AWTって何ですか?
Q1.9 Swingって何ですか?
Q1.10 SWTって何ですか?


2 ニューズグループについて
Q2.1  このニューズグループの規約を教えてください。どんな質問ならOKですか?
Q2.2  歓迎されない話題や質問や投稿はありますか?
Q2.3  このグループのアーカイブはどこにありますか?
Q2.4  SSCCEとは何ですか?
Q2.5  なぜ、トップポスティングは嫌われるのですか? トップポスティングって何ですか?
Q2.6  このほか、質問の態度などに関する参考情報はありますか?
Q2.7  Sunはこのニューズグループを公認していますか?


3 最も多い5つの質問
Q3.1 GUIがフリーズしてしまい, 画面が変わりません。どうしたらいいですか?
Q3.2 GUIを別のスレッドから更新したいのですが, どうしたらいいですか?
Q3.3 ひとつのウィンドウの上にすべてのウィジェットを美しく並べました。しかしOSを
(Javaのバージョンを, フォントを, ルック&フィールを, etc.)変えたら, すべてだめに
なりました。どうしてでしょう?
Q3.4 Canvas/JPanel/JComponentなどの上でグラフィクスがうまく描けません。あるいは,
	  描画をしようとするとNullPointerExceptionになります。どうしたらいいですか?
Q3.5 透明なウィンドウや矩形以外の形をしたウィンドウを作りたいのですが?


4 アーキテクチャ
Q4.1  モデル- ビュー- コントローラ(Model-View-Controller, MVC)って何ですか?
Q4.2 Swingのシングルスレッド問題って、何ですか?
Q4.3 SwingのGUIを起動する正しいやり方は?
Q4.4 排他的全画面モード(full-screen exclusive mode)って何ですか?
Q4.5 アクティブレンダリングって何ですか?


5 Window/[J]Frame/[J]Dialog(トップレベルのコンテナ)
Q5.1 AWTやSwingのウィンドウが, 必ずほかのすべてのウィンドウの上にあるようにした
いのですが?
Q5.2 ウィンドウをアイコン化/アイコン化解除するには, どうしたらいいですか?
Q5.3 [J]Frameのタイトルバーの中のアイコン(ウィンドウのデコレーション)を変えたり
	削除するには。どうしたらいいですか?
Q5.4 [J]Dialogのタイトルバーの中のアイコンを変えたり削除するには。どうしたらいい
	ですか?
Q5.5 モーダルダイアログがメインウィンドウに隠されます。必ず前面にあるようにするた
	めには, どうしたらいいですか?
Q5.6 [Esc]キーでJDialogのキャンセル操作をしたいのですが?
Q5.7 JFrameやJDialogのクロージング処理を自分で実装するには?
Q5.8  ウィンドウを画面の中心に置きたいのですが, 画面のサイズはどうしたら分かりま
	すか?
Q5.9  ウィンドウの最大サイズや最小サイズを、どうやって指定しますか?
Q5.10 ウィンドウのアスペクト比は、どうやって指定しますか?
Q5.11 ウィンドウの配置をシステムのウィンドウマネージャに任せるには、どうしますか?
Q5.12 ウィンドウの位置やサイズを計算するときに、ツールバーなどのサイズを考慮した
いのですが?
Q5.13  ウィンドウのレイアウト表示がおかしいです。ウィンドウを動かさないと、
	レイアウトが正しくなりません。何が、いけないのですか?。
Q5.14  プログラムの起動時にスプラッシュスクリーンを表示したいのですが、どうやったらいいですか?


6 [J]Component(基本ウィジェット)
  6.1 一般的な質問
  Q6.1.1  ウィンドウ内のコンポーネント(ウィジェット)の位置を自由に決められますか?
  Q6.1.2  透明なウィジェットをどうやって作りますか?
  Q6.1.3  矩形でないウィジェットをどうやって作りますか?
  Q6.1.4  インセット(insets)って何ですか?
  Q6.1.5  コンポーネントのトップレベルのコンテナ(ウィンドウ)を、どうやって見つ
  けますか?

  6.2 JTree
  Q6.2.1 JTreeのデータや構造を変えても、表示が変わりません。どうして?
  Q6.2.2 ノードのアイコンをカスタマイズしたいのですが?
  Q6.2.3 JTreeのすべてのノードを一挙に削除したいのですが?

  6.3 スタイルドテキスト, JEditorPane, JTextPane
  Q6.3.1 Wordで作ったRTF文書をRTFEditorKitを使って読めますか?
  Q6.3.2 SwingのHTMLパーサを使ってパースできないHTMLがあります。それは正常なこと
  ですか?
  Q6.3.3 CSSのスタイルが無視される場合があります。それは正常なことですか?
  Q6.3.4 SwingのHTMLサポートを使ってWebブラウザを書けますか?
  Q6.3.5 SwingのHTMLサポートを使ってオンラインヘルプやeブックを作れますか?
  Q6.3.6 JavaのHTMLサポートがそんなにだめなら、それは何のためにあるのですか?

  6.4 [J]TextArea
  Q6.4.1 JTextAreaにテキストをアペンドしたとき, 必ずテキストの末尾までスクロール
	  させたいのですが?
  Q6.4.2  ひとつの[J]TextAreaの中でいろんな(スタイルやサイズの)フォントを使えますか?

  6.5 [J]Label, [J]Button
  Q6.5.1 [J]Labelのテキストを複数行にしたいのですが?
  Q6.5.2 [J]Labelの中にHTMLのリンクを入れられますか?
  Q6.5.3 自分が作ったJButtonをJDialogのボタンにしたい?


7. JScrollPane
Q7.1 コンポーネント(たとえば画像を載せたJPanel)をスクロールペインに入れ
ました。でも、スクロールペインが正しいサイズになりません、スクロールバーが出
ません。


8 グラフィクスと描画
Q8.1 AWTのCanvasのようなものは, Swingでは何ですか?
Q8.2 JPanelの上で描画をすると、背景がごみになります。
Q8.3 Javaで図表や図面を描くには, どうしたらいいですか?
Q8.4 Javaでグラフを描きたいのですが?
Q8.5 回路図などのエディタ〔グラフィカルエディタ)を作りたいのですが, 最初に何をや
るべきですか?
Q8.6 JPanelの上で。複数のJLabelを線で結びたいのですが?
Q8.7 グラフの描画をデバッグするには?
Q8.8 ツリーを描きたいのですが?
Q8.9 描画のアルゴリズムを知りたい。
Q8.10 JPanelやJComponentのサブクラスを作るときは、paint()をオーバライドするんです
よね?
Q8.11 ロードしたイメージをdrawImage()で表示できません。ロードしたイメージの幅と高
	さがどちらもゼロなのはなぜですか?
Q8.12 グラフィックをリサイズ(ズームイン/ ズームアウト)するには、どうしますか?
Q8.13 Swingが使っているアイコンは、どこにあるのですか?。
Q8.14 アプリケーションのための一般的なアイコンをどこで見つけられますか?。


9 フォント
Q9.1 どのフォントを使えますか?。<xyz>フォントは使えますか?。
Q9.2 Swingでテキストのアンチエイリアシングをonにするには?。
Q9.3 一部の文字が白い(黒い)四角になります。なぜですか?


10 そのほかのよくある質問
Q10.1 トップのPanelの上でJMenuをオープンすると, GUIの描画がおかしくなります...
Q10.2  アプレットでSwingを使えますか?。
Q10.3 アプリケーション全体のフォントや色を変えるには、どうしますか?。
Q10.4 UIDefaultsをすべて取得するにはどうしますか?。それらの意味は何ですか?。
Q10.5 なぜSwingは遅いのですか?


11. GUI以外の質問
Q11.1 Javaでコンソール上のテキストUIを実装したいのですが…?
Q11.2 JavaScriptで, こんなことをしたいのですが?
Q11.3 〜〜を作りたいのですが?


12 参考情報
12.1 SunのJava関連サイト
12.2 Sunのその他のサイト
12.3 アイコン
12.4 サンプルコード、チップス、トリック
12.5 スタイルガイド
12.5.1  レイアウトマネージャ(layout managers)

12.6 SDKのドキュメンテーション
12.7 そのほかのSwing情報
12.8 オンライン雑誌
12.9 Java 2D API
12.10 Java 3D API
12.11 Java一般
12.12 もっと?

Q12.12  もっとほかにないの?


13 提案・意見

14 謝辞



1 はじめに
~~~~~~~~~~
Q1.1 このページの目的と内容

このページはcomp.lang.java.guiニューズグループのFAQです. 主な内容は
JavaのSwingとAWTのプログラミングに関する情報とリンク集です.

また、これらの情報は多くの場合、多くの読者たちが近日中にまたまた議論
・説明されてほしくないと思っているものです〔訳注:FAQの中に塩漬けにし
ておきたい、あまりに一般的な情報〕。

Q1.2  ここにないものは何ですか?。

  これはプログラミング入門のためのページではありません。読者がJavaやGUIの
用語を知っている、と想定しています。

  また、以下の話題はまったく扱っていないか、または簡単に触れているだけです。
これらの話題はcomp.lang.java.guiにあまり登場しない、あるいは専門のグループ
がある、あるいはこのFAQの筆者があまり詳しくない分野だからです:

  * J2MEのGUIプログラミング

  * 3Dプログラミング(news:comp.lang.java.3dを見てください) 

  * ゲームプログラミング

  * コンピュータグラフィクスのアルゴリズム
    (news:comp.graphics.algorithmsを見てください)


Q1.3 このFAQをどこでゲットできますか?

1)このFAQは、news:comp.lang.java.guiに定期的にポストされます。

2)次のようなUsenetアーカイブ

http://gd.tuwien.ac.at/faqs/faqs-hierarchy/comp/comp.lang.java.gui/
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

3)閲覧や検索は、ここからできます:

http://groups.google.com/groups?group=comp.lang.java.gui

4)以下のURLにも、あります:

http://mindprod.com/jgloss/guifaq.html
http://www.physci.org/guifaq.jsp

5)日本語訳もあります:

http://homepage1.nifty.com/algafield/JavaGUIFaq19j.html


 Q1.4 JavaのFAQはいろいろありますが, どれが正しくて公式のものですか?

正しくて公式のFAQというものは, たぶんありません. FAQは誰でも作れますし, 実際
にいろんな人が作っています(更新努力が、数週間しか続かないのが多いですが).


Q1.5 SunはこのFAQ をサポートまたは公認していますか? 

いいえ。これはニューズグループのFAQ です。Sun はたぶん、このFAQ の存在を知らな
いでしょう。

[注記]このFAQ の筆者は、Sun のJavaやGUI 開発について内部情報や内部との接触
を持っていません。したがって、このFAQ の筆者がみなさんの質問を提案をSun に提
出して答えをもらってくることは、ありえません。そのようなリクエストは、やめて
ください。


Q1.6 このFAQに紹介されているリンクの一部は壊れています。紹介する前に確認し
	ないんですか?

確認はしません. 読者からの情報が, 頼りです. リンクが無効になることは
よくあります. 確認した数秒後にだめになっていることも, ありえますね.


Q1.7  このFAQ のWordバージョン、HTMLバージョンなどはありますか?

公式のバージョンとしては、ありません。FAQ のテキストをHTMLに変えるためには、
次のソフトが役立つでしょう:

    http://txt2html.sourceforge.net/

Q1.3“このFAQ をどうやってゲットするか? ”も、読んでください。


Q1.8 AWTって何ですか?

AWT(Abstract Window Toolkit)Sunが作った, Javaの最初のGUIツールキットです. 機
能がかなり限られていて, しかも各オペレーティングシステムのGUIコンポーネントを
そのまま使っています. あなたのサポート対象が古いVMでなければ, JavaのGUIツー
ルキットとしてはSwingを使ったほうがよいでしょう.


Q1.9 Swingって何ですか?

Swingは, JavaのGUIツールキットの, Sunによる第二弾です. 機能が高く, ウィジェ
ットの種類も豊富なSwingは, JavaのGUIツールキットのスタンダードと見なされてい
ます. 今では, Java 2 Standard Edition(J2SE)に最初から含まれています.

Swingは, GUIのコンポーネントのほとんどをはじめとして, 多くの部分がJavaで書
かれています. ただしイベント処理やトップレベルのコンテナに関しては, AWTを利
用します.Swing はAWT の“軽量コンポーネントフレームワーク”という仕組みの上
に構築されています。


Q1.10 SWTって何ですか?

SWTはIBMが作ったGUIツールキットです. AWTやSwingとちがって, SWTはJava 2
Standard Edition(J2SE) に含まれていません. SWTはネイティブのライブラリ(オ
ペレーティングシステムのライブラリ)を使っていますから, 目的とするプラットホ
ームごとに, 実装を入手しなければなりません.


2 ニューズグループについて
~~~~~~~~~~~~~~~~~~~~~~~~~~
Q2.1  このニューズグループの規約を教えてください。どんな質問ならOKですか?

ニューズグループに関する規約は1997年4月10日に票決により次のように決まりました:

     http://groups.google.com/groups?selm=860665862.3170%40isc.org

comp.lang.java.*の変遷に関する記録が、ここにあります:

     ftp://ftp.isc.org/usenet/news.announce.newgroups/comp/comp.lang.ja

以下は、97年の決定からの引用です(“全グループ”とは、comp.lang.java.gui
を含むすべてのJava関連グループを指します):

  規約:全グループ

  質問等の投稿は、もっともふさわしいグループ一つだけに対して行う。重
複投稿は、明確な分類が難しい話題や、明らかに複数の分野にまたがってい
る話題にかぎり、認められる。問題の性質が明確であれば、答えは一つのグ
ループに対してのみ行うこと。分類が難しい話題は、comp.lang.java.help
(だけ)に行くべきものが多いだろう。

  バイナリファイル(クラスファイルなど)や、表示スペースが2画面を越
えるような長いソースリストを、投稿してはならない。それらに関しては、
WWWやFTPのリンクを記述せよ(問題の焦点を示す短いコード片を伴うのは
良い)。

  規約:comp.lang.java.gui

  この、モデレータのいないグループは、JavaのGUIツールキットやウィン
ドウフレームワークに関連した議論のために存在する。話題には、AWT,
Netscape IFC,  MicrosoftのAFC, VisixのVibeツールキットなどが含まれて
もよい。このニューズグループはまた、JDKのイベントモデル、マウスやキ
ーボードの問題、ウィンドウ関連のバグ、Javaによるグラフィクスプログラ
ミングなどを議論する場としても適切である。コンピュータの画面の上に現
れるものはすべて、このグループの話題である。

  上の文は1997年の文なので、古い技術への言及があり、Swingの名が見当たりません。
しかし今日では、話題の中心はあくまでもSwingであり、ときどき、AWTや印刷の話題が
登場するぐらいです。


Q2.2  歓迎されない話題や質問や投稿はありますか?


この質問を投稿した人は過去に一人もいませんが、しかし実際には、Javaに関連した話
題であっても歓迎されないものが、いくつかあります。それらは:

*このFAQに答えのある問題(多くの人が見飽きている問題)。

*学校の宿題

*意見(comp.lang.java.advocacyへどうぞ)

*読者に助けを強要する投稿。そして、泣き言(「今日中に書かないと会社をクビになる
んです!」)

*広告や、広告のような文。広告を投稿するとあなたの評価を落とすだけですから、逆
効果です。

*主題に問題が明記されていない質問。たとえば「教えてください」、「助けてくださ
い」、「わかりません」、等々。関連するエラーメッセージやソースコードや、プログ
ラムの動作の詳細などが書かれていない質問。

* APIのドキュメンテーションを読めば誰にでも分かるような質問。そのほか、本気で勉
強する気のない質問。

* “エリートハッカー”ふうの投稿や、インスタントメッセージングふう、あるいは
チャットふうの文章。

* テストメッセージは、alt.test.*へ。そして、ニューズグループの運営等について
よく勉強してください。


Q2.3  このグループのアーカイブはどこにありますか?

ここです:

         http://groups.google.com/groups?group=comp.lang.java.gui

 Q2.4  SSCCEとは何ですか?

  短くて小さくて完結していてコンパイル可能なプログラム例
(Short/small Self Contained Compilable Example)のことです。

  あなたの問題の本質を簡潔に示す、小さなプログラムのソースリストを、質問に付随
させるのが、ベストの質問態度です。プログラムが長すぎるのでソースを投稿できない
とか、複雑すぎて説明が難しい、とか、会社の秘密なのでソースは見せられないとか、
などなどの言い訳はやめましょう。どんなに大きなプログラムでも、問題を簡潔に示す
例題プログラムは書けるはずです。質問への的確な答えがほしくないのならば、ソース
を見せない主義でもいいでしょう。

  プログラム事例の書き方等に関しては、このガイドを読んでください:

     http://www.physci.org/codes/sscce.jsp


Q2.5  なぜ、トップポスティングは嫌われるのですか?。
トップポスティングって何ですか?

以下のやりとりを見てください(これが、トップポスティングの典型です):

  A:質問と答えの流れの、正しい順序が狂うからですよ。
  Q:トップポスティングはなぜ忌み嫌われるのですか?。
  A:トップポスティングですよ。
  Q:フォーラム(掲示板)やメーリングリストで、いちばん嫌がられることは何ですか?。


Q2.6  このほか、質問の態度などに関する参考情報はありますか?

次のリンクを見てください:

     http://www.catb.org/~esr/faqs/smart-questions.html
     http://www.yoda.arachsys.com/java/newsgroups.html

  掲示板を上手に利用するコツは、他人を企業の“苦情受け付け係”扱いしないことです。

  以下のニューズグループも、参考になります:

     news:news.newusers.questions
     news:news.answers

RFC1855も、読みましょう:

     ftp://ftp.rfc-editor.org/in-notes/rfc1855.txt
     http://www.faqs.org/rfcs/rfc1855.html

Q2.7  Sunはこのニューズグループを公認していますか?

投稿者や回答者の中には、ときどき、SunのSwing開発チームのメンバらしき人がいま
したが、最近はあまり見かけませんね。ただしニューズグループを書き込み専用のメデ
ィアとして利用して(※)、なにかを発表する人はいます。Sunの人びとを見かける機
会は、それぐらいですね。

〔※:訳注:2006年冒頭には、Shannon Hickey's Blogの案内などがあった。〕

Sunにとってこのニューズグループは、関心の対象ではないと思います。ですから、こ
この投稿された意見などが、Sun を動かすことはありえないでしょう。そんな提案や意
見は、次のURLに投稿してみましょう:

    http://developer.java.sun.com/developer/bugParade/
    http://jcp.org/ 

〔訳者注記:Sun公認のフォーラムは、http://forum.java.sun.com/の下のフォーラム群など。〕

Q1.4“Sun はこのFAQ をサポートまたは公認しているか? ”も見てください。


3 最も多い5つの質問
~~~~~~~~~~~~~~~~~~~~
Q3.1 GUIがフリーズしてしまい, 画面が変わりません。どうしたらいいですか?

たぶんあなたは, イベントディスパッチングスレッド(EDT)をブロックしているので
しょう. 時間のかかる処理をイベントリスナの中でやるのをやめて, 別のスレッドに
してください。

あなたが手書きでそういうコードを書いてもいいですが, Sunが提供している
SwingWorkerのようなクラスを使うと便利です. これらの記事を読んでください:

     http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

SwingWorkerはJava Standard Edition 1.6に含まれる予定です。

特殊なケースでは, paintImmediately()を使えるでしょう. この記事を読みましょう:

     http://java.sun.com/products/jfc/tsc/articles/painting/index.html

Q3.2“GUIを別のスレッドから更新したいのですが, どうしたらいいですか? ”も見て
ください。

(訳者追記:コンテナのvalidate()を呼ぶのを忘れていたために, 更新結果が画面に反
映しない, というエラーも, 初心者にはよくあります。…AWTではinvalidate()を呼ん
でからvalidate()を呼ぶ、Swing/JComponentでは、revalidate()を呼ぶ==invalidate()
/validate()呼び出しをシステムにリクエストする。ただし、Swing上でコンポーネン
トをremove()したときは、(多くの場合)、コンテナのrepaint()を呼ばないとだめですよー。)


Q3.2 GUIを別のスレッドから更新したいのですが, どうしたらいい
ですか?

別スレッド(たとえば時間のかかる処理をEDT から移した先のスレッド)からGUIを更
新するためには、javax.swing.SwingUtilities.invokeLater()メソッドや
javax.swing.SwingUtilities.invokeAndWait()メソッドを使います。実際には、
invokeLater()メソッドのほうを使うことが多いです。〔GUIの処理が完了するまで、
別スレッドの処理を待たせたいときは、....AndWait()を使う。〕

そのコードは、かなり単純です。たとえば、無名クラスを使うなら:

        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                        // EDTの上で実行されるコード
                }
            }
        );
        // このスレッドはここから直ちに続行する

And

        SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                        // EDTの上で実行されるコード
                }
            }
        );
        // このスレッドはEDTの上のコードが実行されるのをここで待つ

参考情報は, やはりここ:

     http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

Q3.1“GUI がフリーズしてしまい, 画面が変わりません。どうしたらいいですか? ”も
見てください。


Q3.3 ひとつのウィンドウの上にすべてのウィジェットを美しく並べました。しかしOS
を(Javaのバージョンを, フォントを, ルック&フィールを, etc.)変えたら, すべて
だめになりました。どうしてでしょう?

おそらくあなたは, レイアウトマネージャを使わずに, コンポーネントのサイズや位置
を具体的・物理的に指定していますね. この問題を解決したければ, レイアウトマネー
ジャを避けて通れません. もちろん, レイアウトマネージャを一から自作してもかまい
ません.


Q3.4 Canvas/JPanel/JComponentなどの上でグラフィクスがうまく描けません。あるい
	は, 描画をしようとするとNullPointerExceptionになります。どうしたらいいですか?

Component.getGraphics()を使ってはいけません. あなたのサブクラスの中で, AWTな
らpaint(), SwingのコンポーネントならpaintComponent()をオーバライドしてくださ
い.

Component.getGraphics()は全然役に立ちません。Javaの通常の描画モードは“パッシ
ブレンダリング(passive rendering,受動的な描画)”と呼ばれます。この描画方式は、
コールバックと呼ばれる仕組みによって動きます。つまり、描画を行なうコードは、
Javaがpaint()やpaintComponent()メソッドを呼んで描画を開始するまで、じっと受け
身に待っているだけです。

そしてあなた(プログラマ)は、Javaがpaint()やpaintComponent()を呼んだときに備
えて、GraphicsやGraphics2Dの描画機能を使った描画コードを書いておくのです。
getGraphics()などの方法を使って…getGraphics()などから得られるGraphicsを使って…
グラフィクス情報や描画命令をコンポーネントに“押しつける”ことは、まったくプロ
グラマのやるべき仕事ではありません。

この仕組み(paint()/paintComponent()メソッドの呼び出し)があると, ウィンドウ
がほかのものの下に隠れたときなどに, Javaはいちいちウィンドウの内容を記憶せず
にすみます。ウィンドウが再び見えるようになったら, ウィンドウの内容の再描画を
アプリケーションに求めるだけです。ですから, paint()やpaintComponent()はコンポ
ーネントの記憶のようなものです。しかしgetGraphics()には, 前の描画操作を思い出
すことができません。getGraphis()を使って描画を行うと, ウィンドウが隠れたあと
にその描画を再現することができません。前の描画のデータはどこにも残っていませ
んし, AWTもSwingもgetGraphics()に再描画のための情報を与えることはできません。

しかも, Component.getGraphics()がnullを返す場合があります。それはこのメソッド
の正常な動作の一部です。そしてまた, getGraphics()を使ったとき, そのあとで
Graphicsオブジェクトをdispose()しない人が多いですね。

このページに, Javaのコンポーネントの描画に関する詳しい情報があります:

     http://java.sun.com/products/jfc/tsc/articles/painting/index.html

なお、非常に特殊なケース(ゲーム、アニメーション、スライドなど)では、“アク
ティブレンダリング(active rendering,能動的描画)”モードに切り換えることができ
ます。アクティブレンダリングは、排他的全画面モード(full-screen exclusive mode)
を使って、あなたが画面全体を完全に所有しているときに、いちばん有効に使えます。

“Q4.4  排他的全画面モードとは何ですか?”も見てください。

(訳者追記:getGraphics()によって得られるGraphicsオブジェクトは, Imageなどの
バッファリングやそのほかの描画以外の目的で使う, と考えたほうがよい。

例:Stringの幅(ピクセル数)をゲットする:

int pixels = myComponent.getGraphics().getFontMetrics().stringWidth(myString);

[080207追記: [getGraphics()に関する興味深い議論]Q3.5 透明なウィンドウや矩形以外の形をしたウィンドウを作りたいのですが?

プラットホームに依存しない良質な方法は, ありません.

Swingの中には、透明にできるコンポーネントもありますが、問題はトップレベルの
ウィンドウです。ウィンドウはつねに矩形ですし、ウィンドウを透明にできるJavaの
実装系はほとんどありません。

状況やプラットホームによっては、以下の方法が使えることもあります:

1)醜い裏技…Java 1.3以上、全プラットホーム

java.awt.Robot.createScreenCapture(rectangle) を使って背景画面のスナップ写
真を撮り, それをウィンドウのバックグラウンドイメージに使うと, 透明の錯覚を
作り出せます. しかし画面が変われば, その錯覚もばればれです.

  http://www-128.ibm.com/developerworks/java/library/j-iframe/
 
はJFrameのサブクラスで、Robotを利用して透明性を加えています。

2)Windows

このサイトにあるSkinルック&フィールの:

    https://skinlf.dev.java.net/

のnativeskin.jarは、Windowsの上で矩形でないウィンドウを作る機能を提供していま
す。それには、ネイティブのWin32のライブラリも同梱されています。もちろん、使え
るのはWindowsの上だけです。

Windows 以外のGUIシステム向けに、こんなライブラリを書くことは可能でしょう(た
とえばX11のshape拡張が使えるでしょう)。

3) Apple OS X

AppleのJava for OS Xは、ウィンドウの背景色にアルファ成分を使えます。それは本当
は、Javaのすべての実装に期待したい機能です。ウィンドウの背景色にアルファ成分を
指定できると、たとえば次のようにすれば背景を完全に透明にできます:

   window.setBackground(new Color(0, 0, 0, 0)); 

矩形以外のウィンドウは、次のようにして作れます:

  --ウィンドウの通常の装飾枠をoffにする、そして、
  --画像(PNGのようにアルファ成分のある画像)をウィンドウの背景に使う。

4)アプレット

アプレットの場合は, こんなやり方があります:

   http://java.sun.com/docs/books/faq/src/app/MatchBackgroundExample.html

    Q6.1.2“透明なウィジェットをどうやって作りますか? ”と、Q6.1.3“矩形でない
ウィジェットをどうやって作りますか? ”も見てください。


4 アーキテクチャ
~~~~~~~~~~~~~~~
Q4.1  モデル-ビュー-コントローラ(Model-View-Controller, MVC)って何ですか? 

MVCはアプリケーションを構造化する方法のひとつです。それは、データのプレゼンテ
ーションをデータそのものから分離する、という考え方に基づいています。MVCは
Smalltalkの世界で誕生し、今では一般的なデザインパターンになっています。

SwingはMVCの変形を使っています(Smalltalkのユーザが指摘するように、それは元
々のMVCではありません)。

以下の記事に、SwingのアーキテクチャとMVCの変形バージョンについて、良質な説明
があります:

    http://java.sun.com/products/jfc/tsc/articles/architecture/index.html


Q4.2 Swingのシングルスレッド問題って、何ですか?

問題というほどのものでは、ありません。Swingはほとんどの場合、スレッドセーフで
ありません。しかし、正しく注意すれば、マルチスレッドの環境でも安全に使えます。

注意すべき点は、以下の三点のみです。ほかには、ありません:

1) SwingのAPIのメソッドは、イベントディスパッチスレッド(EDT)から呼び出しま
す。APIのドキュメンテーションに、別のスレッドから呼び出せると書いてあるもの
(スレッドセーフなメソッド)以外は、必ずそうします。

[注記]APIのドキュメンテーションに間違いがあることもあります。不審に思ったら
        SunのbugParadeで調べてみましょう。

2) EDT以外のスレッドからSwing APIのメソッドを呼び出す必要があったら、
invokeAndWaitやinvokeLater()を使って、そのメソッド呼び出しをEDTに登録し、
EDTにスケジューリングさせます。

3) EDTをブロックしてはいけません。つまり、EDTの上で時間のかかるタスクを動かし
てはいけません。そういうタスクは別のスレッドで動かし、そのスレッドからGUIを更
新する必要があるときには、上のinvokeXxxx()メソッドを使います。

以上のほかには、なにも注意点はありません。

Q3.1“GUIがフリーズしてしまい、画面が変わりません”、Q3.2“GUIを別のスレッド
から更新したいのですが”、Q4.3“SwingのGUIを起動する正しいやり方”も見てくだ
さい。


Q4.3 SwingのGUIを起動する正しいやり方は?

Sunは、ほとんど誰も知らない間に、GUIを始動するときの推奨手続きを変えました。
SunのGUIのチュートリアルのプログラム例は、2004年の初めに書き換えられ、短い説
明が付きました。その説明を要約すると“Swingのどこかにスレッド関連のバグがある
ので、GUIの構築と始動はつねにEDTから行う必要がある”。Sunはそのバグの根本原
因を知っているのか、それを直す気があるのか、などの情報は、まだ(2004/10月上旬
現在)どこにもありません。

そこで、これからは、GUIを構築して始動する(setVisible(true)を呼ぶ)正式の方法は、
invokeLater()を使うことです。GUIアプリケーションのmain()メソッドの、基本的な形は、
こうなります:

    public static void main(String[] args) {
        invokeLater(new Runnable() {
            public void run() {
                //
                // GUIを構築して始動する.
                //
            }
        });
    }

Q4.2“Swingのシングルスレッド問題”も見てください。


Q4.4  排他的全画面モード(full-screen exclusive mode)って
何ですか?

それは文字通り、全画面をあなたのアプリケーションが独占的に使う方法です。それは
たとえば、ゲームや工程管理、スライドショウなどのアプリケーションで必要です。
このモードは、Java 1.4で導入されました。

このモードでは、通常のモードよりもハードウェアにより直接的にアクセスします。
そこでプログラミングのテクニックも、ふつうのSwing/AWTプログラミングとは違うも
のが必要です。排他的全画面モードは多くの場合、アクティブレンダリング(Q4.5)
と共に使います。参考情報は:

  http://java.sun.com/docs/books/tutorial/extra/fullscreen/index.html


Q4.5  アクティブレンダリングって何ですか?

アクティブレンダリングは、通常のコールバック方式(“パッシブレンダリング”
(Q3.4)…プログラマは描画をJavaに依頼するだけ)と違って、グラフィクス情報や
描画命令をプログラマが画面に対して“プッシュ”します。

アクティブレンダリングを使ったアプリケーションのアーキテクチャは、ふつうの
Javaアプリケーションのアーキテクチャとはまったく違ったものになります。使用
が推奨される分野は、ゲームやアニメーションなど、ごく限られています。

アクティブレンダリングをいちばん有効に使えるのは、排他的全画面モードです。
そして、ページフリップ(VRAM間のコピーを行なわずバッファポインタの切り替え
によるページの瞬時切り替え)を行なうBufferStrategyを併用することが多いです。

“Q4.4  排他的全画面モードって何ですか?”と“Q3.4 Canvas/JPanel/Jcomponentな
どの上でグラフィクスがうまく描けません。あるいは、描画をしようとすると
NullPointerException uなります。どうしたらいいですか?”も見てください。


5 Window/[J]Frame/[J]Dialog (トップレベルのコンテナ)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Q5.1 AWTやSwingのウィンドウが,必ずほかのすべてのウィンドウの上にあるようにしたいの
	ですが?

1)Javaの1.5以前はできませんでした

AWTにもSwingにもこの機能はありませんでした。[J]Dialogをモーダルダイアログと
して作り、そのときコンストラクタに、正しい親ウィンドウを与えるのが、せいぜいで
した。

2)1.5では、

Window#setAlwaysOnTop()を呼び出します。このメソッドは、JFrameのようなトップレ
ベルのコンテナからも使えます。しかし実装が不完全なので、とくにUNIX系オペレーテ
ィングシステム+ウィンドウマネージャという組み合わせの多くで問題が起きます。


Q5.2ウィンドウをアイコン化/アイコン化解除するには,どうしたらいいですか?

Java 1.2以前では、ネイティブメソッドを使う方法しかありませんでした。

1.2からは、[J]Frame#setState()を使えます。

1.4からは、[J]Frame#setExtendedState()も使えます。setExtendedState()は、
setState()よりも機能が豊富です。


Q5.3 [J]Frameのタイトルバーの中のアイコン(ウィンドウのデコレーション)を変え
	たり削除するには。どうしたらいいですか?

setIconImage()を使います。

プラットホームのデフォルトのアイコンに戻すには:

frame.setIconImage(null);


Q5.4 [J]Dialogのタイトルバーの中のアイコンを変えたり削除するには。どうしたらいいですか?

この問題には、不完全な解しかありません。またそれは、お勧めできません。

ダイアログは親のフレームからアイコンをもらいます。そこで、ダミーのフレームを作
って、そのフレームのアイコンをセットします。そしてそのフレームを、ダイアログの
コンストラクタで親フレームとして指定します:

         JFrame dummy = new JFrame();
         Image icon   = ...
         dummyFrame.setIconImage(icon);
         JDialog dialog = new JDialog(dummy);

しかし、この方法は危険です。GUIの動作の一部は、ダイアログと親フレームが正しい
関係であることに依存しています。そこにダミーの親を持ち込むと、正しい関係が壊れ
ます。アプリケーションのすべてのウィンドウのアイコン化/アイコン化解除の振る舞
いが狂ったり、モーダルダイアログがメインウィンドウの上に来なくなったりするでし
ょう。


Q5.5モーダルダイアログがメインウィンドウに隠されます。必ず前面にあるようにす
	るためには,どうしたらいいですか?

ダイアログのコンストラクタで、“親”を正しく指定してください。nullや、ダミー
のフレームを(ダイアログのアイコンを設定するために)使ってはいけません。


Q5.6 [Esc]キーでJDialogのキャンセル操作をしたいのですが?

最初に悪いニュース。JComboBoxやJTableなど一部のJComponentは、[Esc]キーを自分
の目的に使っています。そのため、それらのコンポーネントからエスケープキーの処理
を削除しないかぎり、以下のやり方は使えません。

[Esc]キーを、何かの操作に結び付けるためには、次のようなコードを使います:

    final String ESC_ACTION_KEY = "ESC_ACTION_KEY";
    theDialog.getRootPane().getActionMap().put(
        ESC_ACTION_KEY,
        new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                //
                // エスケープキーに結びつけた何かの処理
                //
                // すべてのウィンドウリスナに報告したり
                // 単純にdispose()を呼んだり…
                //
            }
    });

    theDialog.getRootPane().getInputMap(
        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
    ).put(
        KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
        ESC_ACTION_KEY
    );

※ActionMapにActionをputして、その名前(上ではESC_ACTION_KEY)をInputMapにput
  するのが、ワンパターン的な書き方です。


Q5.7 JFrameやJDialogのクロージング処理を自分で実装するには? 

まず、JDialog, JFrame, JInternalFrameなどのデフォルトのクローズ操作を“自分で
は何もしない”に設定します:

    theJDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

次に、自作のウィンドウリスナをaddします:

    theJDialog.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent we) {
            //
            // クローズの確認を求める,
            // そのほかの後始末をする.
            // 必要ならウィンドウをクローズする.
            //
            // we.getWindow().dispose();  // ウィンドウをクローズする
        }
    });


Q5.8  ウィンドウを画面の中心に置きたいのですが,画面のサイズはどうしたら分かり
	ますか? 

1.4以前には、java.awt.Toolkit.getDefaultToolkit().getScreenSize()を使って画面
サイズを入手し、こんな計算をしました:

         import java.awt.*;
         Dimension winSize = win.getSize();
         Dimension screenSize =
                         Toolkit.getDefaultToolkit().getScreenSize();
         win.setLocation(
                 (screenSize.width - winSize.width) / 2,
                 (screenSize.height - winSize.height) / 2
         );

1.4以降は:
         Window.setLocationRelativeTo(null);


Q5.9  ウィンドウの最大サイズや最小サイズを、どうやって指定しますか?

ほとんどの場合、良い方法はありません。できる場合でも、ごく限られたことしかでき
ません。

SwingとAWTはほとんどの場合、minimumSizeとmaximumSize属性を無視します。たとえば、
ネイティブのGUIシステムがウィンドウサイズをユーザーのマウス操作により1×1ピ
クセルにすることを可能にしているなら、Swing/AWTはよろこんでそれに従います。

1) Java 1.4より前の一般的な裏技

望ましくないリサイズが行われた後でサイズを修正する、醜い裏技はあります。リサイ
ズに対してまたリサイズをやるので、ウィンドウが醜くちらつく(ビクッ、という動き
をする)のです。

この醜い修正は、ウィンドウのコンポーネントリサイズイベントを捕捉するイベントリ
スナを使って行います(ComponentListener)。doLayout()メソッドをオーバライドする
やり方もあります。どちらの場合も、現サイズをgetWidth()/getHeight()で得ます。そ
のサイズがお望みのサイズでなかったら、setSize()で修正します(これによって二度
目のリサイズが起こり、ウィンドウがビクッと跳躍します)。

2) Java 1.4以降

Java 1.4には、JFrame.setDefaultLookAndFeelDecorated()が加わりました。このメ
ソッドはサイズ変更に対して反応しますが、それはドキュメントされていません。
このメソッドにtrueを渡して呼び出すと、プラットホームがルック&フィールによ
るウィンドウデコレーションを許していて、そのルック&フィールのウィンドウデ
コレーションをJavaが描画するなら(たとえばMetalのウィンドウデコレーション)、
サイズ変更の動作はレイアウトが指定しているサイズ範囲を通常は尊重します。

Java 1.4ではときどき、不思議なバグが観察できます。Metalでなくプラットホーム
のデフォルトのルック&フィールを使っていると、
JFrame.setDefaultLookAndFeelDecorated(true)はデコレーションだけをMetal
ルック&フィールにだけ変えますが、ウィンドウのコンテンツはデフォルトの
ルック&フィールで描画されます。その結果、ルック&フィールの奇妙なミック
ス(混血)を見ることになりますが、この奇妙なウィンドウはサイズ変更の範囲
制限は尊重します。

3) Java 1.5

JFrame.setDefaultLookAndFeelDecorated()はやはりサイズ変更に反応します。また、
ルック&フィールの混血現象は一応解消しました。一応というのは、
JFrame.setDefaultLookAndFeelDecorated(true)なら、ウィンドウデコレーションが
Metalに変わるだけでなく、ウィンドウのコンテンツもMetalになります。ただし、
デフォルトのルック&フィールを指定しているときでも、そうなります。

結論として、、Java 1.5とMetalルック&フィールと
JFrame.setDefaultLookAndFeelDecorated(true)という三者の組み合わせが、
サイズ変更に対するリーズナブルな振る舞いを提供します。

Q5.10“ウィンドウのアスペクト比は、どうやって指定しますか?”も見てください。


Q5.10ウィンドウのアスペクト比は、どうやって指定しますか?

良い方法はありません。上のような“醜い裏技”を使って、サイズを強制できます。

Q5.9“ウィンドウの最大サイズや最小サイズを、どうやって指定しますか?”も見てく
ださい。


Q5.11ウィンドウの配置をシステムの(ネイティブの)ウィンドウマネージャに任せる
	には、どうしますか?

1) Java 1.5以前

システムの(ネイティブの)ウィンドウマネージャの振る舞いをJavaから制御できませ
ん。ウィンドウの位置を指定しなければ、(0, 0)と解釈され、ウィンドウはそこに置か
れます。あるいは、ウィンドウはマネージャから見てベストフィットの場所に置かれま
す。

(0, 0)を指定しても、結果は同じです。一部のウィンドウマネージャはベストフィット
の位置にウィンドウを置き、そのほかのマネージャは(0, 0)の位置に置きます。

2) Java 1.5以降

ウィンドウマネージャの振る舞いを指定するための裏技が導入されました。
java.awt.Window.locationByPlatformプロパティがtrueにセットされると、ウィンド
ウマネージャはウィンドウを(0, 0)の原点に置くか、または自分が決めた場所に置き
ます。このプロパティがfalseなら、(0, 0)を指定したウィンドウはまさしく(0, 0)
に置かれます。

指定は、個々のウィンドウごとや、個々のsetVisible(true)ごとにもできます。それ
は、setVisible(true)の直後にWindow.locationByPlatform(true)を使うことによっ
て行います。


Q5.12ウィンドウの位置やサイズを計算するときに、ツールバーなどのサイズを考慮し
	たいのですが? 

その情報が得られないプラットホームもあります。運が良ければ、
Toolkit.getScreenInsets()によって、ツールバーやドック、パネルなどに占められ
ている外枠のスペースに関する情報が得られます。この情報を使って、必要な計算を
します。

        Insets i = theWindow.getToolkit().getScreenInsets(
                         theWindow.getGraphicsConfiguration()
                 );


必要なサイズが、たとえばつねにinsets.bottomだと想定してはいけません。また、
ツールバーを画面の上や横などに動かせるグラフィクスシステムも、多いです。複数
のツールバーも置けます。だからつねに、四辺の値を考慮に入れるべきです。

しかしプラットホームを特定しないJavaアプリケーションを作りたければ、これらの
情報に依存すべきではありません。どうしても必要なら、外枠のスペースをプログラ
ムまたはコンフィギュレーションで明白に指定する方式にすべきです。そうすると、
情報が得られないプラットホームの上でも、プログラム(やコンフィギュレーション)
で指定した値なら、当然、得られます。

Q6.1.4“インセット(insets)って何ですか?”も見てください。


Q5.13  ウィンドウのレイアウト表示がおかしいです。ウィンドウを動かさないと、
	レイアウトが正しくなりません。何が、いけないのですか?。

  ウィンドウが表示されたあとで、内容やレイアウトを変えたのでしょう。レイ
アウトの変更は、自動的には行われません。いちばん良いのは、表示する前にウ
ィンドウの構築を終えることです。それが無理なときは、内容やレイアウトを変
えたあとで、ウィンドウに命令します:

1) AWTでは:

  ウィンドウのinvalidate()を呼んで、次にvalidate()を呼びます。

2) Swingでは:

  ウィンドウがJComponent(たとえばJPanel)なら、revalidate()を呼びます。

  ウィンドウをinvalidate()してからpack()するやりかたもあります。

  validate()/revalidate()のあとにrepaint()を呼ぶ必要がある場合には、
paintComponent()の冒頭でsuper.paintComponent()を呼ぶのを忘れていないか、
paint()の実装が不完全でないか、チェックしましょう。

以下の項目も見てください:
  Q8.1 AWTのCanvasのようなものは, Swingでは何ですか?
  Q8.2 JPanelの上で描画をすると、背景がごみになります。
  Q3.4 Canvas/JPanel/JComponentなどの上でグラフィクスがうまく描けません。
あるいは, 描画をしようとするとNullPointerExceptionになります。どうしたら
いいですか?


Q5.14プログラムの起動時にスプラッシュスクリーンを表示したい
のですが、どうやったらいいですか?

あなたのアプリケーションにスプラッシュスクリーンを加えるときには、それを面倒に
感じるユーザのために、offにできるオプションを付けるべきです。スプラッシュスク
リーンは、何度も見ていると煩わしくなりがちです。

1)Java 1.5まで

AWTのWindowを使って画像を表示します。スプラッシュスクリーンのためには、Swingの
コンポーネントを使わないほうがよいでしょう。AWTでもVMの立ち上げを待たなければ
なりませんが、Swingのコンポーネントを多数使う場合に比べると待ち時間は短いです。

2)1.6以降

VMに対してスプラッシュスクリーンの画像を指定するコマンドラインオプションがあり
ます。その画像は、VMがJavaのコードの実行を開始する前に表示されます。アニメーシ
ョンGIFも使えます:

  java -splash:splashImage.gif ...

Java 1.6以降には、Javaプログラムからスプラッシュスクリーンを操作できるAPIがあ
ります。java.awt.SplashScreenクラスを見てください。

またJARファイルのManifestファイルで、スプラッシュスクリーンの画像を指定でき
ます:

  SplashScreen-Image: splashImage.gif



6 [J]Component(基本ウィジェット)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6.1一般的な質問

Q6.1.1  ウィンドウ内のコンポーネント(ウィジェット)の位置を自由に決められ
	ますか?

コンポーネントの配置には、レイアウトマネージャを必ず使います。位置の正確な計算
は、レイアウトマネージャが行います。Java API(AWT/Swing)の中にも、そしてネット
上の広い世界にも、さまざまなレイアウトマネージャが作られ、提供されています。

AWT/Swingのプログラミングには、レイアウトマネージャの勉強が欠かせません。多く
の人が、なんとかレイアウトマネージャなしですませたい、と考えます。そして、さま
ざまなフォーラムの上で、コンポーネントの配置がうまくできない、と泣き言を述べる
のです。うまくできないのは、レイアウトマネージャを使えという警告です。

まず、ここから勉強を開始しましょう:

    http://java.sun.com/books/tutorial/uiswing/layout/index.html

〔訳者注:簡単かつ静的な目的では、自己責任で、次のようにする:

  container.setLayout(null);
  container.add(component);
  component.setBounds(x, y, w, h); //位置と大きさを指定

〕


Q6.1.2  透明なウィジェットをどうやって作りますか?

まず重要なのは、透明なウィジェットを作れることイコール透明なウィンドウを作れ
ることでにはなりません。ウィジェットはJavaアプリケーションが支配しても、ウィ
ンドウはデスクトップの支配下にあります。ですから一般的に、アプリケーションの
トップレベルのウィンドウだけは、どうあがいても透明にはできません。

Java 1.1から、軽量フレームワークが導入されたことによって、Componentのサブクラ
スは(軽量コンポーネントなら)、正しく実装すれば透明な部分を持つことができま
す。Swingの軽量コンポーネントは特別です。それらのほとんどは、背景を透明/不透
明に切り換えることができます。

そこで、次のような三つのケースがあります:

1)Componentのサブクラス(Swingと重量コンポーネントを除く)

Componentのサブクラスを書き、paint()の中では透明でない部分だけを描画します。

既存の軽量コンポーネントのサブクラスを作って、透明なコンポーネントにするときに
は、paint()の中でスーパークラスが背景を背景色で塗りつぶさないように気をつけま
しょう。

2)SwingのJComponentのサブクラス

SwingのJComponentのサブクラスは、自分の区画内のすべてのピクセルを塗るか/塗ら
ないか(ペイントするか/しないか)を指定できます。このことの単なる副作用とし
て、プログラマはJComponentの背景を透明にしたり不透明にしたりできます。

これは、JComponentとSwingのリペイントマネージャ(repaint manager)との間の
《不透明性契約(opaque contract)》の副作用です。

    setOpaque(false)

と書くと、JComponentの区画内のすべてのピクセルを塗らないことを指示します。こ
れによって、Swingのコンポーネントのほとんどは、背景が透明になります。不透明性
(opaque)がfalseなら、コンポーネントのpaintComponent()メソッドは背景を塗らずに
コンポーネントを描画します。またリペイントマネージャは、isOpaque()==falseのコ
ンポーネントを見つけると、コンポーネントの階層を一段下りて、そのコンポーネン
トの下のコンポーネントを見つけます。そしてそれをまずリペイントすることによっ
て、背景を作ります。

ただしJScrollPaneなどの、複合的/ネスティングしたコンポーネントでは、
この方法は無効です。また、一部のルック&フィールは、setOpaque()の指定を無視し
て、色を塗ってしまうことがあります。しかしそれも、JComponentとSwingのリペイン
トマネージャとの間の不透明性契約(opaque contract)で認められています。ただ
しもちろん、その場合、期待した透明性は得られません。

3)重量級コンポーネント

JavaのSunによる実装では、透明な重量級はサポートされていません。

Q6.1.3“矩形でないウィジェット”とQ3.5“透明な/矩形でないウィンドウ”も見てください。


Q6.1.3  矩形でないウィジェットをどうやって作りますか?

Javaのコンポーネントの輪郭はつねに矩形です。背景を透明にすることによって、矩形でな
いコンポーネントのふりができますが、しかしJavaはそれをあくまでも矩形のウィジェット
として扱います。レイアウトも、矩形を前提として行われます。任意の形のコンポーネント
を任意にレイアウト(したふり)が必要なら、そんなレイアウトマネージャを自作してくだ
さい(実際には、複数の矩形が部分的に重なっているレイアウトになります)。

Q6.1.2“透明なウィジェット”とQ3.5“透明な/矩形でないウィンドウ”も見てください。


Q6.1.4  インセット(insets)って何ですか?

1)ウィンドウのような矩形のコンポーネントの、「枠」や「縁」(外周)部分のこ
とです。

2)より詳しく言うと、AWTではウィンドウのデコレーションのサイズ(幅)のことでし
た。Frameのタイトルバーや、GridBagLayoutのボーダーの幅などです。やがて、
Insetsという言葉がAWTやSwingの至る所で使われるようになりました。それと並行し
て、言葉の意味も曖昧になりました。

しかし一般的には、ウィンドウやコンポーネントの外周の、ユーザが使えない部分がイ
ンセットだ、と考えるとよいでしょう。次のどちらの式が成り立つか、インセットとい
う言葉に出会うたびに、確認してください(アイテムはコンポーネントやウィンドウの
ことです):

    利用可能サイズ=アイテムのサイズ−インセット
    全サイズ=利用可能サイズ

または

    利用可能サイズ=アイテムのサイズ
    全サイズ=アイテムのサイズ+インセット

ただし、Insets= {0,0,0,0}のときは、これらの式は無関係です。


Q6.1.5  コンポーネントのトップレベルのコンテナ(ウィンドウ)を、どうやって見つ
	けますか? 

    SwingUtilities.getRoot()

を使ってください。


6.2 JTree
Q6.2.1 JTreeのデータや構造を変えても、表示が変わりません。どうして? 

データをTreeModelから変えずに、TreeNodeを直接操作していませんか?。TreeNode
は、変更をJTreeに伝える能力を持っていません。それはTreeModelの仕事です。

DefaultTreeModelを使うなら、イベント通知の仕組みがすでに実装されています。
TreeModelの自分の実装を使うなら、必要なイベントの発火も自分で実装する必要
があります。

JTreeのrepaint()を呼んではいけません。JTreeの表示は壊れませんが、イベント通
知の仕組みが壊れます。


Q6.2.2ノードのアイコンをカスタマイズしたいのですが?

すべてのノードのアイコンをデフォルト以外のものに変えたいなら、
DefaultCellRendererを取得して、そのsetXxxIcon()メソッドを呼び出し、
画像を指定します。

しかし、個々のノードのアイコンを変えたいなら、次の3つのステップが必要です:

[ステップ1]
TreeNodeをimplementsしたクラス(または既存のそんなクラスをextendsしたクラス)
を作ります。以下のコード例で、いくつかのやり方をお見せします。

    public class ABCTreeNode implements TreeNode {
        //
        //   a.このTreeNodeが自分を識別するためのIDを設ける。
        //
        public int getType() { /*タイプIDを返す */ }

        //  
        //   b.またはTreeNodeが特定のアイコンを返すようにする。
        //      (すべてのノードが共用するアイコンでもよい):
        //
        // public Icon getLeafIcon()   { /*アイコンを返す */  }
        // public Icon getOpenIcon()   { /*アイコンを返す */  }
        // public Icon getClosedIcon() { /*アイコンを返す */  }

        //
        //   c.または、ノードのタイプごとに異なるサブクラスを作り
        //      instanceof演算子でタイプを調べます。異なるアイコン
        //      ひとつひとつに対して、それ専用のサブクラスが必要で
        //      す。
        //

        //
        //   d.または、このTreeNodeがレイアウト情報を表すオブジェク
        //      トを返すようにして、そのオブジェクトがgetXXXIcon()メ
        //      ソッドを備える。
        //
        // public TreeNodeInfo getInfo() { /*情報オブジェクトを返す */ }
        //

        ...
    }

[ステップ2]
DefaultTreeCellRendererのサブクラスを作り、getTreeCellRendererComponent()を
オーバライドします:

    public class ABCTreeCellRenderer extends DefaultTreeCellRenderer {
        Component getTreeCellRendererComponent(
            JTree tree,
            Object value,
            boolean sel,
            boolean expanded,
            boolean leaf,
            int row,
            boolean hasFocus)
        {

            //
            //  以下の部分はABCTreeNodeをどう実装したかによって
            //  変わります。
            //

            //
            // a. getType()メソッドを使った場合:
            //
            ABCTreeNode node = (ABCTreeNode)value;
            switch(node.getType()) {
            case: ...
                    setLeafIcon(...);
                    setOpenIcon(...);
                    setClosedIcon(...);
                    break;
            }

            //
            // b. getIcon()メソッドを使った場合:
            //
            // ABCTreeNode node = (ABCTreeNode)value;
            // setLeafIcon(node.getLeafIcon());
            // setOpenIcon(node.getOpenIcon());
            // setClosedIcon(node.getClosedIcon());
            //

            //
            // c. TreeNodeのサブクラスがノードのタイプごとに異なる場合:
            //
            // if(value instanceof ABCTreeNode) {
            //      setLeafIcon(...);
            //      setOpenIcon(...);
            //      setClosedIcon(...);
            // } else if(value instanceof ...) ...
            //

            //
            // d.レイアウト情報オブジェクトを使う場合:
            //
            // ABCTreeNode node = (ABCTreeNode)value;
            // ABCTreeNodeInfo info = node.getInfo();
            // setLeafIcon(info.getLeafIcon());
            // setOpenIcon(info.getOpenIcon());
            // setClosedIcon(info.getClosedIcon());
            //

            //
            //  そして最後に:
            //
            return super.getTreeCellRendererComponent(
                    tree, value,
                    sel, expanded, leaf,
                    row,
                    hasFocus);
        }
        ...
    }

[ステップ3]
JTree.setCellRenderer()を呼び出して、このレンダラをセットします。


Q6.2.3 JTreeのすべてのノードを一挙に削除したいのですが?

モデルを置換するだけです。すべてのノードを個々に削除するのは、時間の無駄です。

JTreeのAPIのドキュメンテーションは、nullをモデルとして使えると書いてありませ
んが、Sunの参考実装では使えることが知られています:

    tree.setModel(null);

これがだめなら、空のモデルを作ってnullの代わりに使ってください。


6.3スタイルドテキスト, JEditorPane, JTextPane
Q6.3.1 Wordで作ったRTF文書をRTFEditorKitを使って読めますか?

やってみましょう。しかしRTFEditorKitは機能が限られています。そのドキュメンテー
ションには、微妙なヒントが書かれています。つまりSwingの開発チームは、このクラ
スを将来的には改良したい、ということです。この言葉は、何年も前の最初ののリリー
スからずっとそのままです。

新しいバージョンのWordで作ったRTFドキュメントは、RTFEditorKitで読めない確率が
高いでしょう。プログラムがクラッシュする、という報告もあります。


Q6.3.2 SwingのHTMLパーサを使ってパースできないHTMLがあります。それは正常なこと
	ですか? 

残念ながら、それは正常です。SwingのHTMLパーサは、昔のHotJava(SunがJavaで書
いたWebブラウザ)のパーサです。それは機能が不十分で、しかも、その後長年アップ
デートされていません。HTML 3.2とスタイルシートは扱えますが、不安定です。

問題があれば、ほかのパーサを使うか、またはHTMLのHTML Tidyに変換します。Javaに
移植されたJTidyもあります:

    http://tidy.sourceforge.net/
    http://jtidy.sourceforge.net/


Q6.3.3 CSSのスタイルが無視される場合があります。それは正常なことですか?

上と同じ理由で、それは正常です。javax.swing.text.html.CSSクラスのドキュメンテ
ーションに、JavaがサポートしているCSSの属性が書かれています。それらが不十分で
あることは、覚悟しましょう。


Q6.3.4 SwingのHTMLサポートを使ってWebブラウザを書けますか?

できますが、SwingのHTMLパーサとCSSの処理が完全でありませんから、それなりのも
のしか作れません。そのパーサは、SunのHotJavaブラウザ用に開発されたものです
が、それは何年も前のことであり、HotJavaはブラウザとしてメジャーになることがで
きませんでした。

参考までに、このページを見てください:

http://java.sun.com/developer/onlineTraining/GUI/Swing1/shortcourse.html#JFCEditorPane


Q6.3.5 SwingのHTMLサポートを使ってオンラインヘルプやeブックを作れますか?

もちろん作れます。SunのJavaHelp APIを使ってもいいでしょう。このAPIは、Swing
のHTML機能を使ってHTMLで書かれたヘルプテキストのパーシングやレンダリング(書き
出し)をやっています。このほかナビゲーションなどのヘルプ機能も実装しています。


Q6.3.6 JavaのHTMLサポートがそんなにだめなら、それは何のためにあるのですか?  

HTMLの生成そのものをあなたが制御できるなら、十分使い物になります。たとえば
JavaHelpはSwingのHTMLパーサとHTML表示機能を利用しています。

あなたが制御できない、最近のさまざまな既存のHTMLドキュメントを扱いたいなら、ほ
かのパーサを探すべきです。たとえばこれは:

  http://htmlparser.sourceforge.net/

多くの人びとが推薦しています。

6.4 [J]TextArea
Q6.4.1 JTextAreaにテキストをアペンドしたとき,必ずテキストの末尾までスクロール
	させたいのですが?

    textarea.setCaretPosition(textarea.getDocument().getLength());


Q6.4.2  ひとつの[J]TextAreaの中でいろんな(スタイルやサイズの)フォントを使え
	    ますか? 

それはできません。JEditorPaneやJTextPaneを使ってください。


6.5 [J]Label, [J]Button
Q6.5.1 [J]Labelのテキストを複数行にしたいのですが?

1)Label

できません。TextAreaを使い、その編集機能をoffにします。

2)JLabel

  2.a)HTMLを書きます:

  theJLabel.setText("<html>Line 1<br>Line 2<br>Line 3</html>");

  2.b)あるいはJTextAreaを使います。


Q6.5.2 [J]Labelの中にHTMLのリンクを入れられますか?

ラベルよりも、ボタンのほうがいいでしょう。

リンクのように見えるボタンを作ります。ボタンのボーダーは、取り去ります:

         b = new JButton("<html><a>http://java.sun.com</a><html>");
        b.setBorderPainted(false);

そのボタンのアクションリスナの中に、やりたいこと/やらせたいことを書きます。た
とえば、リンクのURLを引数としてWebブラウザを起動してもよいでしょう。

        b.addActionListener(new ActionListener() {
                actionPerformed(ActionEvent e) {
                        // Webブラウザを始動する、など
                }
        });


Q6.5.3自分が作ったJButtonをJDialogのボタンにしたい? 

これは、かなり理解しづらい方法です。JDialogのルートペインに対して、ボタンを指
定するのです:

    theJDialog.getRootPane().setDefaultButton(theJButton);

ルック&フィールによっては、これが無視されます。


7. JScrollPane
~~~~~~~~~~~~~~
Q7.1 コンポーネント(たとえば画像を載せたJPanel)をスクロールペインに入れま
した。でも、スクロールペインが正しいサイズになりません、スクロールバーが出
ません。

そのコンポーネントのgetPreferredSize()が、必要なサイズを返すようにしてくださ
い。たとえばJPanelに画像が載っているなら、getPreferredSize()がその画像のサイ
ズを返すようにします。


8 グラフィクスと描画
~~~~~~~~~~~~~~~~~~~~
“最も多い5つの質問”も見てください。

Q8.1 AWTのCanvasのようなものは, Swingでは何ですか?

a) paintComponent()を正しくオーバライドして(※)、UI実装部(UI delegate)がコン
ポーネントのバックグラウンドの不透明の設定を維持する、“完全な”コンポーネント
が欲しければ、JPanelを使います:

(※訳者注記:paintComponent()の冒頭でsuper.paintComponent(g);を呼び出すこと
で、不透明性が維持されます。)

b) コンポーネントの全領域のひとつひとつのピクセルを描画したいとき(そしてバッ
クグラウンドの不透明性がなくなってもよいとき)には、JComponentを使います。ま
た、マウスやキーの独自のイベント処理をしたいときも、やはりJComponentをextends
し、独自のUI実装部(UI delegate)をあなたが作ります。

c) もっとさかのぼって、java.awt.Componentをextendsすることもできます。
Componentは、Java 1.1以降は軽量コンポーネントです。しかし、ダブルバッファリン
グのようなSwingの機能は、Componentにはありません。

d) 冗談ではなく、Canvas。特殊な状況(ゲーム、アクセレータの使用、など)では、
Swingの中でもAWTのCanvasを使うのが正しいかもしれない。ただし重量コンポーネン
トと軽量コンポーネントの混用はトラブルを招くことがあるので、ふつうの状況では
やるべきでない。

以上のお話を難解に感じたかたは、JPanelを使ってください。そして、JPanelや
JComponentを使うときには、paint()ではなくpaintComponent()をオーバライドすること
を、忘れないようにしましょう。


Q8.2 JPanelの上で描画をすると、背景がごみになります。

コンポーネントの不透明性の扱いを、あなたが破壊したんですね。JPanelのインスタン
スは(getOpaque()を介して)、その扱いの下で各ピクセルを描く約束ですが、その約
束が破られています。

paintComponent()の冒頭でsuper.paintComponent(g)を呼んでください。それによって
不透明性が保たれ、背景を背景色で満たします。opaqueフラグのセッティングもチェッ
クしましょう。"Painting"に関するTSCの記事を読みましょう(10.1を見よ)。

Q8.3 Javaで図表や図面を描くには, どうしたらいいですか?

図表などを描画したいときは、既製品のライブラリの利用を考えましょう。たとえば
これは、人気があります。そのほかのライブラリのリストも、ここにあります:

         http://www.jfree.org/jfreechart/index.html
         http://www.jgraph.com/

計測データなどをプロットしたいときは、gnuplotのようなCで書かれたプログラムを
使うとよいでしょう:

         http://www.gnuplot.info/

世界中の何百万もの科学論文の挿し絵が、gnuplotで描かれています。

Runtime.exec()を使ってgnuplotを起動してもよいし、あるいはJavaでデータファイル
を作り、gnuplotを単独で使ってもいいでしょう。


Q8.4 Javaでグラフを描きたいのですが?。

本格的なグラフ作成は、けっこう大仕事です。全部自分でやるなら、グラフを描くアル
ゴリズムを本格的に勉強してください(Q8.8を見てください)。並行して、Java 2D API
を勉強してください。

あるいは、既製のライブラリを使う手もあります:

  http://jgrapht.sourceforge.net/
  http://jung.sourceforge.net/

J2SE(JDK)に含まれているデモプログラムの、ソースも、参考になるでしょう:

  demo/applets/GraphLayout

C言語で書かれているThe Dotも、良いライブラリです:

  http://www.research.att.com/sw/tools/graphviz/refs.html

UNIXの上でtroff + picをインストールしているなら、picを使って簡単なグラフを描け
ます(Q8.8を見てください)。



Q8.5 回路図などのエディタ〔グラフィカルエディタ)を作りたいのですが, 最初に何
	をやるべきですか?

まず、既製のフレームワークの利用を考えましょう。たとえばこれ:

         http://www.jhotdraw.org/
         http://www.jgraph.com/jgraphpad.html
         http://gef.tigris.org/

また、この本を読んでデザインパターンと仲良くなってください:

         Gamma, E.; Helm, R.; Johnson, R.; Vlissides, J.: Design
         Patterns: Elements of reusable object-oriented Software.
         Addison-Wesley professional computing series. Brian W.
         Kernighan, Consulting Editor. Reading, MA: Addison-Wesley,
         1994.「オブジェクト指向における再利用のためのデザインパタ
         ーン」ソフトバンク刊

著者の一人のVlissidesがUniDrawやIDrawを(C++で)書いたときのドキュメンテーシ
ョンも(もし見つかれば)読んでみましょう。


Q8.6 JPanelの上で。複数のJLabelを線で結びたいのですが?

あなたは通常のウィジェットを使ってグラフを描こうとしているのでしょうが、それ
は、あまり良い考えではありません。Java 2D API(今ではJ2SEの一部)を使って、グ
ラフ全体を描いてください。java.awt.geomには、いくつかの図形(Shape)があらかじ
め定義されています。また、Sunの2D Programmer's Guideも読みましょう(このペー
ジの最後(9章)の“参考資料”のところに、リンクがあります)。


Q8.7 グラフの描画をデバッグするには?

たぶん最良の方法は、デバッグを使ってpaint()やpaintComponent()の振る舞いをトレ
ースすることです。JComponentのsetDebugGraphicsOptions()メソッドという、分かり
にくいメソッドがあります。これは、何種類かのデバッグ出力をon/offします。

ただしsetDebugGraphicsOptions(0)は、デバッグをon/offしません。デバッグをoffに
するには、setDebugGraphicsOptions(DebugGraphics.NONE_OPTION)を呼び出します。

このページの最後の“参考文献”のところも見てください。


Q8.8 ツリーを描きたいのですが?

これは、よくある宿題の質問みたいですから、わざと簡単にお答えします。“ニューズ
グループで歓迎されない質問”のところを読んで、その理由を理解してください。

JTreeの今のままのレイアウトでよければ、まずJTreeのAPIのドキュメンテーションを
読んでください。

あるいは、次のような再帰的なアルゴリズムを使ってもいいでしょう:

         x(node) = K * level(node), and
         y(node) = M * inorder_rank(node).

これはとても醜いツリーを作りますが、しかしツリーです。これで満足できないなら、
あなたの先生のアドバイスを求めてください。ツリーの(間順の)走査については、
参考書を読んだり、あるいは次のサイトを訪ねてください:

         http://home.earthlink.net/~patricia_shanahan/beginner.html

Q8.9 描画のアルゴリズムを知りたい。

まず、news:comp.graphics.algorithmsのFAQを読みましょう:

  http://www.magic-software.com/CgaFaq.pdf


Q8.10 JPanelやJComponentのサブクラスを作るときは、paint()をオーバライドするん
	  ですよね?。

ちがいますよ。paint()じゃなくpaintComponent()をオーバライドするんです。
paint()をオーバライドするのは、Canvas(など、AWTのコンポーネント)のサブクラス
を作るときです。

Swingのコンポーネントの描画は、AWTとやや違っています。TSCのpainting関連記事を
読みましょう(12.1も見よ)。それらは、コンポーネントを自作するときの必読のドキュ
メンテーションです。


Q8.11 ロードしたイメージをdrawImage()で表示できません。ロードしたイメージの
	幅と高さがどちらもゼロなのはなぜですか?。

イメージのロードが完了していないんですね。イメージのロードをモニタするには、
java.awt.MediaTrackerを使います。説明と使用例は、MediaTrackerクラスのAPIドキ
ュメンテーションを見てください。

あるいは、javax.swing.ImageIconを使って画像をロードしてもいいですね。それは、
内部でMediaTrackerの処理を自分でやっています。


Q8.12グラフィックをリサイズ(ズームイン/ズームアウト)するには、どうしますか?

たかが表示の問題ですから、そのために表示するデータそのものをいじくるのは、絶対
にやめましょう。

単なる表示のためのリサイズなら、次の三点を考えます:

1. AffineTransformを使って、適切な変形を構築します(そのscale()メソッドを見て
ください)。Graphics2Dのscale()メソッドを使っても、おんなじです。どちらを使っ
ても、paintComponent()の中で、リターンする前にGraphics2Dオブジェクトをリセット
して、もとの形に戻すことが重要です。

2.ズームイン/アウトをするときには、グラフィクスをスケールするだけでなく、描画
をしているJPanelをリサイズして、それを収めているJScrollPaneのスクロールバーが
更新されるようにしましょう。ただし、JPanelのサイズはデバイスの座標系ですが、ア
プリケーションの座標データはユーザ空間の座標系でしょうから、気をつけましょう。

        double zf = 1.0;

        public void setZoom(double zf) {
             //引数のズーム係数を
             //ここでチェックしたほうがいい

            this.zf = zf;
            theJPanel.setPreferredSize(baseWidth * zf, baseHeight *zf);
            theJPanel.repaint();
        }


        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            //
            //Graphicsオブジェクトの元のAffineTransformステートを保存する。
            //AffineTransformを記憶してもいいし、あるいはGraphicsオブジェク
            //トのコピーを保存してもよい。
            //
            //方法a:元のAffineTransformを保存する
            Graphics2D g2d = (Graphics2D)g;
            AffineTransform orig = g2d.getTransform();
            //
            //方法b:Graphicsオブジェクトのコピーを使う
            // Graphics2D g2d = (Graphics2D) ((Graphics2D)g).create();

            //
            // Graphicsコンテキストをスケールする
            //
            g2d.scale(zf, zf);

            // 〜〜ここでグラフィクスを描画する〜〜

            //
            // リターンの前にステートをリセットする
            // 方法a:AffineTransformを元に戻す
            //              Reset transformation
            g2d.setTransform(orig);
            //
            // 方法b:Graphicsのコピーを破壊する
            // g2d.dispose();
        }

3.グラフィクスの一部をセレクトしたり、マウスを使ってグラフィクスと対話している
プログラムは、マウスイベントの座標をスケール(ズーム係数で割る)しなければなり
ません。AffineTransformの逆スケーリングをそのために使えますが、簡単な線型のス
ケーリングなら、座標値に対する割り算だけでOKでしょう。

マウスのイベントハンドラの中でその計算を行い、同時にその中でグラフィクスとの対
話的操作もします。JPanelのマウスイベントをグラスペインを使って捕捉し、変形操作
をしてから(計算結果を)転送する方法が、ときには便利です。

Q8.13 Swingが使っているアイコンは、どこにあるのですか?。

一部はjavax.swing.plaf.basic.BasicIconFactorにあり、Metal用のは
javax.swing.plaf.metal.MetalIconFactorにあります。

Q8.14 アプリケーションのための一般的なアイコンをどこで見つけられますか?。

12.3 アイコン を見てください。


9 フォント
~~~~~~~~~~
Q9.1 どのフォントを使えますか?。<xyz>フォントは使えますか?。

  まず、FontクラスのAPIドキュメンテーションを見てください:

http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Font.html

Q9.2 Swingでテキストのアンチエイリアシングをonにするには?。

  Swingのアンチエイリアシングの効果は、フォントの種類やサイズ、フォント
レンダラ、モニタの解像度、などによってまちまちです。したがって、この機
能はアプリケーションのオプション機能にすることと、ユーザの環境でテスト
することが重要です。

1) Java 1.5より前は:

  テキストのアンチエイリアシングを個々のコンポーネントに対して指定する
のは簡単でしたが、GUIのすべてのコンポーネントに対してonにするのは悪夢
でした。

  ひとつのコンポーネントに対してonにするには、サブクラスを作って
paintComponent()を次のように実装します:

       public void paintComponent(Graphics g) {
          Graphics2D g2 = (Graphics2D) g;

          g2.setRenderingHint(
              RenderingHints.KEY_TEXT_ANTIALIASING,
              RenderingHints.VALUE_TEXT_ANTIALIAS_ON
          );

          g2.setRenderingHint(
              RenderingHints.KEY_RENDERING,
              RenderingHints.VALUE_RENDER_QUALITY
          );

          super.paintComponent(g2);
          }
      }

  すべてのコンポーネントでonにするには、アプリケーションで使用するすべ
てのコンポーネントを、上のようなサブクラスとして作ります。または、次の
ようなサイトで、アンチエイリアシングのできるPLAF(pluggable look and feel)
を探します:

    http://smoothmetal.sourceforge.net/
    http://wraplf.l2fprod.com/

2) Java 1.5以降:

  コマンドラインでシステムプロパティswing.aatextをtrueにセットすると、
アンチエイリアシングがグローバルにonになります。
  以前の方法も、使えます。


Q9.3  一部の文字が白い(黒い)四角になります。なぜですか?

1)それがGUIで起きる場合

該当するフォントが見つからないのです。対策は:

1a)その文字を実際にGUIで表示したい場合には、フォントを見つけてインストールし
ます。次のページ:

  http://java.sun.com/j2se/1.5.0/docs/guide/intl/font.html

には、Java 1.5に同梱されている物理的フォントがサポートしている文字や記号が表
で示されています。

また以下のページ:

  http://java.sun.com/j2se/1.4.2/docs/guide/intl/fontprop.html
  http://java.sun.com/j2se/1.5.0/docs/guide/intl/fontconfig.html

には、Javaのフォント参照の方式や、VMのレベルでの変え方が説明されています。
ただし、エンドユーザにVMのコンフィギュレーションを変えさせるよりは、
java.awt.createFont()を使うほうがずっとましです。

1b)その四角が文字ではなく、改行などの制御記号を表しているときがあります。
たとえばJLabelやJButtonは改行記号に従って改行ができずに、その記号を四角で
表します。そんなときは、こうではなく:

  JLabel jl = new JLabel("Line1\nLine2");

HTMLを使ってこのようにしてください:

  JLabel jl = new JLabel("Line1
Line2"); 制御記号そのものが不要なら、文字列からそれらを取り除いてください。 2)テキストコンソールで文字化けするとき これはGUI関連の問題ではありません。多くの場合コンソールが、その文字を含む文字 セットをサポートしていないのです。 10 そのほかのよくある質問 ~~~~~~~~~~~~~~~~~~~~~~~~~ Q10.1 トップのPanelの上でJMenuをオープンすると, GUIの描画がおかしくなります... Swingのコンポーネント(JMenu)とAWTのコンポーネント(Panel)を、混ぜて使わないほう がよいでしょう。どうしても混ぜて使いたいときは、次のページを読んでください: http://java.sun.com/products/jfc/tsc/articles/mixing/index.html Q10.2 アプレットでSwingを使えますか?。 ユーザのブラウザのJavaプラグインがSwingをサポートしていればOKです。あ なたは古いバージョンのJavaの上で開発をしないでしょうから、ユーザのプラ グインも最新であるのが理想です。ダウンロードはここから: プログラマなら: http://java.sun.com/products/plugin/index.jsp 消費者ユーザなら: http://www.java.com/ Swingのアプリケーションをアプレットではなくアプリケーションとして提供 し、Java WebStartで動かしてもらう方法もありますね。JavaWebStartは今では JREに含まれています。詳しくは: http://java.sun.com/products/javawebstart/ Q10.3 アプリケーション全体のフォントや色を変えるには、どうしま すか?。 1)Metalを使ってるなら、javax.swing.plaf.metal.MetalThemeを自分で実装するの がベストです。そしてそれを、 javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme()でセットします。 2)そのほかのPLAFには、そんなAPIがありませんから、なんとか方法を探し出すか、 または未知のUIDefaultsを見つけるしかありません。 Q10.4 UIDefaultsをすべて取得するにはどうしますか?。それらの 意味は何ですか?。 UIDefaultsには現在のPLAFのデフォルトのセッティング(色、アイコン、フォントな ど)があります。意味は、名前から推測できます。ただしキーの名前は、PLAFによっ て、またはVMの実装系によって違うことがあります。 UIManager.getDefaults()がUIDefaultsを返します。このメソッドが返すデータはMapイ ンタフェイスをimplementsしていますから、そこから[key : value]のペアを取り出せ ます。そのための小さなプログラムがいくつかあります。有名なのは、 ShowUIDefaults.javaです。 〔訳注:リソースバンドルタイプのものは、APIのソースからしか取り出せない。 参考URL(1), 参考URL(2)。〕 Q10.5 なぜSwingは遅いのですか? Swingは経験の浅いGUIプログラマが使うと遅いです。ていうか、彼らは自分の欠点を 棚にあげて、遅い原因をSwingのせいにするのです。欠点とは、たとえばSwingのイベ ントやリペイントの仕組みを理解していないことです。レイアウトマネージャの無視 /虐待/誤用も、彼らの多くがおおっぴらにやっていますね。 Q3.1「GUIがフリーズしてしまい,画面が変わりません。どうしたらいいですか?」, 3.2,「GUIを別のスレッドから更新したいのですが,どうしたらいいですか?」, 3.4「Canvas/JPanel/JComponentなどの上でグラフィクスがうまく描けません。ある いは,描画をしようとするとNullPointerExceptionになります。どうしたらいいです か?」, 4.2「Swingのシングルスレッド問題って,何ですか?」も見てください 11 GUI以外の質問 ~~~~~~~~~~~~~~~~ Q11.1 Javaでコンソール上のテキストUIを実装したいのですが…? Javaは、GUI以外のユーザインタフェイスにあまり向いていません。高度なテキストUI を実現するためには、個々のプラットホームに依存するライブラリが必要です。 たとえばUNIXのcurses/ncursesライブラリを使うJCursesというライブラリがあります: http://sourceforge.net/projects/javacurses/ また、Linuxのテキストコンソールの上でSwing APIの物真似をするcharvaがあります: http://www.pitman.co.za/projects/charva/index.html Q11.2 JavaScriptで, こんなことをしたいのですが? JavaとJavaScriptは互いに別物です。comp.lang.javascriptや、そのほかの JavaScriptフォーラムを訪ねてください。 Q11.3 〜〜を作りたいのですが? プログラムは、“作る”ものではなくて、“書く”ものですね。Javaのようなプログラ ミング言語と、アルゴリズムと、データ構造について最初に勉強することがたいせつで す。とくにJavaでは、オブジェクト指向という考え方をよく身につけることも重要で す。優れたプログラミング言語は、ほかのプログラマたちとのコミュニケーションを円 滑にし、充実します。しかし、勉強すべきことは、もっともっとあります。こんなサイ トを見てみましょう: http://www.norvig.com/21-days.html 日本語訳 このFAQはJavaのGUIに関するFAQですから、優れたグラフィカルユーザインタフェイ ス(GUI)の開発にもセンスと技術が必要であることを、強調しておきましょう。セン ス、趣味、細かい丁寧な仕事、色やフォントに関する知識、 HCI(human-computer-interaction,人間とコンピュータの対話)、スタイルガイドなど が重要です。JavaのGUIプログラミングは、HTMLページを作ることとかなり違います。 “書く”のは面倒、Javaの勉強も面倒、とにかく何かを手っとり早く“作り”たい、と いうかたは、もっと簡単なツールを探しましょう。 12 参考情報 ~~~~~~~~~~~ JavaのGUIプログラミングに関するオンラインの情報は、豊富にあります。以下のリス トは、それらの中でも、comp.lang.java.guiで推奨される機会の多いものです。中には、 comp.lang.java.guiの常連のページもあります。 12.1 SunのJava関連サイト SunのSwing初心者チュートリアル: http://java.sun.com/docs/books/tutorial/uiswing/mini/index.html Swingの本格的なチュートリアル http://java.sun.com/docs/books/tutorial/uiswing/index.html [TSC](Swingデベロッパサイト) http://www.javadesktop.org http://java.sun.com/products/jfc/tsc/index.html 技術記事アーカイブ: http://java.sun.com/products/jfc/tsc/articles/ 技術記事のインデクス: http://www.javadesktop.org/tsc/index.html SunのAWT FAQ http://java.sun.com/docs/books/faq/faqawt.html 12.2そのほかのSunのサイト ここにも、GUIに関する記事(その一部は古い)があります: http://java.sun.com/developer/technicalArticles/GUI/ 12.3アイコン アイコンは、使用する前に、ライセンス条件をよく読むこと。以下に紹介するものの一 部は、オープンソースのフリーウェアです。 Metalルック&フィール用のSunの隠れたアイコン集 http://developer.java.sun.com/developer/techDocs/hi/repository/ そのほかのアイコン・サイト: http://sourceforge.net/projects/icon-collection/ Ximian Open-Officeのアイコン(とても良い): http://www.novell.com/coolsolutions/nnlsmag/assets/ooo-stock.zip Gnomeのアイコン: http://art.gnome.org/themes/icon/ SVG BlueSphereのアイコンとテーマ: http://svgicons.sourceforge.net/ KDEのアイコン: http://www.buzzard.me.uk/jonathan/kde-icons.html http://www.kde-look.org/ 12.4 その他 Swingの上手な使い方に関するリンク集(中には古いものもある): http://www.physci.org/codes/tame/ 元は: http://www2.gol.com/users/tame/swing/examples/SwingExamples.html (今はない) Chirstian KaufoldのJavaとSwing情報(JTable情報など)): http://www.chka.de/ JeanetteのJavaとSwing情報(JTable情報など): http://www.mycgiserver.com/~Kleopatra/swing/swingentry.html Marco SchmidtのJava情報ページ(画像処理関連) http://www.geocities.com/marcoschmidt.geo/java.html Karsten Lentschの会社のWebページ: http://www.jgoodies.com/ 12.5スタイルガイド Java Look and Feel Design Guidelines: http://java.sun.com/products/jlf/ed2/book/index.html Java Look and Feel Design Guidelines: Advanced Topics: http://java.sun.com/products/jlf/at/book/index.html 12.5.1 レイアウトマネージャ(訳者補記/040925) ・RiverLayout(060221追記) ・TableLayoutHIGLayoutFormLayoutRelativeLayoutExplicitLayoutJGoodies Forms --comp.lang.java.guiの常連回答者IchBin氏は、JGoodies Formsを強力に推しています:"For that I have found The "JGoodies Forms" the best". [超やさしい*高級な*グリッドレイアウト] ・GridAlocLayout ... An ultra easy *advanced* grid layout by hiwa. -- You need to use a special constraint class. ・RainLayout by Andrey Kuznetsov [A Kuznetsov's sites] Unified I/O for Java Java image reader Java GUI components and utilities 12.6 SDKのドキュメンテーション J2SEの標準ドキュメンテーションに含まれるGUI関連情報(読んでない人が多い): AWT http://java.sun.com/j2se/1.5.0/docs/guide/awt/index.html Swing http://java.sun.com/j2se/1.5.0/docs/guide/swing/index.html 2Dグラフィクスと画像処理 http://java.sun.com/j2se/1.5.0/docs/guide/2d/index.html イメージI/O http://java.sun.com/j2se/1.5.0/docs/guide/imageio/index.html 印刷 http://java.sun.com/j2se/1.5.0/docs/guide/jps/index.html インプットメソッド http://java.sun.com/j2se/1.5.0/docs/guide/imf/index.html アクセシビリティ http://java.sun.com/j2se/1.5.0/docs/guide/access/index.html ドラッグ&ドロップ http://java.sun.com/j2se/1.5.0/docs/guide/dragndrop/index.html Swingのプログラム例 あなたのJavaのdemo/jfcディレクトリを見ましょう。 12.7そのほかのSwing情報 Swingのクラス階層図 http://www.holub.com/goodies/java.swing.html jGuruのSwing FAQ http://www.jguru.com/faq/Swing CodeGuruのコード事例 http://www.codeguru.com/java/Swing/index.shtml 12.8オンライン雑誌 JavaWorldにはGUIの記事が載ることが多い。このオンライン雑誌は2004年1月に“廃刊” になり、3月に復刊した。 http://www.javaworld.com/ 12.9 Java 2D API プログラマーズガイド http://java.sun.com/j2se/1.5.0/docs/guide/2d/spec/j2d-bookTOC.html 2Dチュートリアル(やさしい入門編) http://java.sun.com/docs/books/tutorial/2d/index.html サンプルコード(JDKのdemo/jfcも見ましょう) http://java.sun.com/products/java-media/2D/samples/suite/index.html 12.10 Java 3D API 専門のニューズグループがある: news:comp.lang.java.3d http://groups.google.com/groups?group=comp.lang.java.3d 12.11 Java一般 Javaチュートリアル http://java.sun.com/docs/books/tutorial/ いろいろなチュートリアル http://developer.java.sun.com/developer/onlineTraining/ RoedyのJava Glossary http://www.mindprod.com/jgloss/jgloss.html 12.12 もっと? Q12.12 もっとほかにないの? ソースコードを見ましょう。ソースコードはSDKのsrc.zipや(古いSDKなら) src.jarに含まれています。それは、インストールしたJavaのトップレベルの ディレクトリ内にあります。 Googleなどのサーチエンジンの使い方を覚えましょう: http://www.google.com 13.提案・意見 ~~~~~~~~~~~~~ このFAQに関する日本語の提案・意見は、HGA03630@nifty.ne.jp(岩谷 宏)にメール すれば、翻訳してcljg(comp.lang.java.gui)へポストします。英語で書けるかたはご本 人が直接、cljgへポストしてください(リンクは本ページ冒頭に)。
[mailto to hiwa]
著者にメールで送るときには、タイトル中に必ず [cljg] の計6文字を含めてください。 新しいFAQ項目の提案には、なるべく、質問だけでなく答えも書いてください。 14.謝辞 ~~~~~~~ このFAQの言い出しっぺならぬ書き出しっぺはThomas Weidenfeller ですが、その後今日までは、以下のかたがたをはじめ、多くのかたの寄与から成り立っ ています。したがってこのFAQの著作権は、100%、Thomas Weidenfellerに帰属するもの ではありません: Andrew Thompson, David Postill, Manish Hatwalne, Hiwa, Jeanette.



©2004 Google

AWTとSwingのペイント(paint)の仕組み Java API javadoc改善運動! Javaの手帖 Javaの手帖--GUI分冊 /ひとつ上をゆくJavaの教科書 「JavaServer Faces完全ガイド」補遺
javacのエラーメッセージ解説 「Javaの哲学」の恥かき 「Javaによるテキスト処理」の恥かき 「モア・サーブレット」の恥かき 恥かきのホームページ フォーラム「JavaBeginner」
UIDefaultsのkeyとデフォルト値「コア・サーブレット」の恥かき comp.lang.java.guiのFAQ日本語訳 「入門 正規表現」 「Javaネットワークプログラミングの真髄」 「Java並行処理プログラミング」