Back

JAVAメモ

とりあえず、JAVAもやっておかないとね、ってことで


JRE 1.4.1_03/04 にバグ

2003/08/05 現在、Sun のサイトでダウンロードできる、このプラグインにはバグがあるようです。インストールしてしまった人は、古いバージョンに差し替えてください

症状

SAX/DOM 等の XML パーサーを使ったアプレットを読み込むと、以下のいずれかのエラーが発生します

※通常、JAVAコンソールに表示されます

対処法1.古いバージョンに戻す

  1. 開いている全てのブラウザを閉じる
  2. 「スタート」→「設定」→「コントロールパネル」→「アプリケーションの追加と削除」を開く
  3. Java 2 Runtime Environment.SE v1.4.1_03」または「Java 2 Runtime Environment.SE v1.4.1_03」を削除
  4. Java(TM) 2 SDK, Standard Edition 1.4.1_02 (J2SE(TM)) を開く
  5. Windows (all languages, including English)」の「JRE」にある「DOWNLOAD」をクリック
  6. 画面の一番上に見える、「download」をクリック(※下図参照)
    Keep Informed
    Fill out the optional information below or proceed with download.
  7. Java(TM) 2 Runtime Environment, Standard Edition 1.4.1_02」を一番下までスクロールさせ、「ACCEPT」ボタンを押す
  8. Download j2re-1_4_1_02-windows-i586-i.exe .をクリックし、インストーラを適当なフォルダにダウンロード
  9. ダウンロードしたインストーラをダブルクリックし、起動する
  10. インストールが完了したらPCを再起動する

対処法2.java.policy を書き換える

書き間違いがあると大変なことになるので、あまりお勧めできませんが、一番簡単な方法ではあります。念のため、作業の前に「java.policy」をバックアップしておいてください
  1. 開いている全てのブラウザを閉じる
  2. 「C:\Program Files\Java\j2re1.4.1_03\lib\security」、または「C:\Program Files\Java\j2re1.4.1_04\lib\security」フォルダをエクスプローラ等で開く
    ※利用している環境によっては違う場合もあります
  3. 「java.policy」と言うファイルをメモ帳などで開く
  4. 以下の2行を書き加える
    permission java.util.PropertyPermission "entityExpansionLimit", "read";
    permission java.util.PropertyPermission "disallowDoctypeDecl", "read";
    ※一番下に見える「};」の上に挿入。場所を間違えないこと
  5. ファイルを上書保存する
  6. メモ帳を終了させる

paint と update の使い分け

java.awt.Canvas などを使って、コンポーネントの表面に絵を描く状況を考えてみましょう。この時、真っ先にやらなければいけないのは、コンポーネントに絵を描くメソッドを探し出すこと。後は、このメソッドをオーバーライドしてしまえばいいのです。簡単なもんです

そんなワケで、先人たちの知恵を拝借に、その手のサイトにあるサンプルソースを眺めに旅立つことにします。もちろん、書籍もOK。要は書き方さえわかればいいのですから

さて。ほとんどの人は、ここで「はぁ?」となるはずです。何しろサンプルソースごとに、オーバーライドするメソッドがupdate だったり paint だったりと、てんでバラバラなんですから。本当に迷います

結論から言うと。「両方ともオーバーライドする」が正解。この2つのメソッドには、それぞれにちゃんと役割があるので、その役割を活かせるように、しっかりとオーバーライドしてあげるのが筋と言うものです

役割分担

ひとまず repaint メソッドを呼んだとき、コンポーネントがどんな手続きを経て再描画されるのか、調べてみることにします

  1. repaint( )
  2. update( ) コンポーネント全体を背景色で塗りつぶし、paint メソッドを呼ぶ
  3. paint( ) コンポーネントの表面に絵や文字を描く

まずは、update。「コンポーネント全体を背景色で塗りつぶす」と言うのは、お絵描き用のまっさらな紙を用意すること。update の役割は、これに尽きます

続いて、paint。これは「updateが用意してくれた下地に絵を描く」メソッドです。実際の描画処理は、このメソッドをオーバーライドすれば良いことがわかります

update でやること

何も考えずに描画だけしたいのであれば、これでじゅうぶん。背景を塗りつぶしたり、paint メソッドを呼ぶ作業は、みんな基底クラスがやってくれます

    public void update(Graphic g)
    {
        super.update(g);
    }

基底クラスがみんなやってくれるのに、なぜわざわざオーバーライドするのか? 実はこれ、後で紹介する「ダブルバッファ」への布石だったりするのです。詳細はそっちで説明するので、今はこう言うものだと考えといてください

paint でやること

画像を貼るなり、線を引くなり、心のおもむくまま描いてください

    public void paint(Graphic g)
    {
        // TODO:Grapchi オブジェクト g を使ってお絵描き
    }

ただし、Panel などの Container クラスから派生したクラスの場合は、基底クラスを呼び出して、コンテナに配置されたサブコンポーネントを描画する必要があります

    public void paint(Graphic g)
    {
        // TODO:Grapchi オブジェクト g を使ってお絵描き

        // サブコンポーネントを描画
        super.paint(g);
    }

JAR や ZIP にまとめたデータ(リソース)を読み込む

アプレットを公開する時、通常は<APPLET>タグを使います。書き方は以下のとおりです

<APPLET archive="kisekae.jar" code="kisekae.class"></APPLET>

この例の場合、アプレットのプログラムは、「kisekae.jar」に圧縮して保存されています。通常、JAVA は複数の class ファイルで構成されているので、こうやって一個のファイルにまとめてしまえば、サイトにアップロードするのも簡単になるわけです

でも、アプレットはプログラムだけで作られているわけではありません。例えば着せ替えアプレットの場合、着せ替え用の服の画像データなども、たくさんあります。こう言った画像を始めとするデータは、「リソース」と呼ばれています。JAR には、このリソースも一緒にまとめて圧縮保存することができます。Flash 作ったことがある人なら、たぶん、ピンと来るものがあるでしょう

ここでは、JAR に圧縮保存されたリソースを読み込む方法について説明します。なお、JAR に圧縮保存する方法については、jar コマンドのヘルプなんかを参考に自力で探ってください。DOSプロンプトで「jar /?<Enter>」とすれば表示されるはずです

画像を読み込む

画像の場合、専用のメソッドが用意されています

Image Applet#getImage(URL)
とりあえず、アプレットクラスの init( ) メソッド等から読み込むと、以下のようになります
Image img=getImage(new URL(getCodeBase(),"images/hontai.png"));

画像以外のリソースを読み込む

例えば着せ替えアプレットでは、服の重なりや座標などを管理するテキストデータが、これにあたります
        Class               inClass=null;
        InputStream         inStream=null;
        URL                 inResource=null;
        try{
            inClass=getClass();
            inStream=inClass.getResourceAsStream(path);
            inResource=inClass.getResource(path);
        }catch(Exception e){
            // エラーです
        }

pathには、リソースのファイル名を記述してください。この例の場合、inStreamを使えば、ストリームの形でリソースを読み出すことができます。また、inResource を使えば、URL の形でリソースにアクセスすることができます。もっとも、ストリームで取れてしまえば、URLなんかに用はないわけですが

リソースだけ別ファイルにしてみる

JAR の正体が ZIP ファイルだと言うことは、JAVA をやっている人なら、大抵は知っているでしょう。そんなわけで、このような書き方も許されています

<APPLET archive="kisekae.jar,resource.zip" code="kisekae.class"></APPLET>

この例では、「kisekae.jar」にプログラムを、「resource.zip」にリソースを、それぞれ圧縮保存しています。またまた着せ替えを例にするならば、新しい服の画像を「resource.zip」で供給する時などに便利でしょう

そして、肝心のリソースの読み出し方ですが、実は JAR から読み出す時と全く同じ手順でできてしまいます。と言うわけで、説明は省きます


レイアウトの罠

着せ替えアプレットを作っていて、非常に困ったことがあります。服を消したり表示したりするボタンが、思うように並んでくれないのです。レイアウトマネージャは、Panel コンポーネントに標準で搭載されている FlowLayout。これは、Panel に追加されたコンポーネントを、何も考えずに左上から右下に配置してくれる、シンプルなレイアウトマネージャです。でも、どう言うわけか、左中央から右方向へ改行もせず1行に配置したり、ヘタすると配置したはずのボタンを表示してくれなくなったりします

いろいろ試してわかったのは、「FlowLayout をレイアウトマネージャに持つコンテナに Panel を配置するのはよろしくない」と言うことでした。でも、「なぜダメなのか」については、よくわかりません。と言うわけで、「そう言うものなんだ」と思っておくことにします

でも、思っておくだけでは解決になりません。どう言う処理をすればボタンがキレイに並んでくれるのか、具体的に調べていきましょう

別のレイアウトを使ってみる

この例のようなレイアウトなら、BorderLayout でもやれそうです。これは、上下左右の大まかな場所を指定してコンポーネントを配置することができるレイアウトマネージャです

一見、成功したかに見えますが、ちょっと違います。最初の例に比べて、ボタンの右側に余白ができていません。これは Panel が、全てのボタンが収まるギリギリいっぱいに、自分のサイズを調整しているからです。そんなわけで、ボタンの数を増やすと大変なことになります

ほら、この通り

真の敵は Panel

どうやら、悪さをしているのは、レイアウトだけではなさそうです。Panel に搭載されている、「自分のサイズを調整」する能力が原因と見たほうがいいでしょう。つまり、改造のポイントは Panel がレイアウトマネージャに、自分のサイズを報告するメソッド。こいつをオーバーライドしてみます

    public class XPanel extends Panel
    {
        // 必要なサイズを保持するプロパティ
        Dimension    size;

        public XPanel(int w,int h,Color bg)
        {
            // 自分が必要なサイズを覚える
            size=new Dimension(w,h);
            setSize(size);// サイズを変更
            setBackground(bg);// 背景色
        }

        // レイアウトマネージャに報告する最適サイズ
        public Dimension getPreferredSize()
        {
            // 最適サイズは「必要サイズ」
            return size;
        }

        // レイアウトマネージャに報告する必要サイズ
        public Dimension getMinimumSize()
        {
            // 必要サイズを返す
            return size;
        }
    };

結果はこの通り。うまくボタンが並んでくれました


ダブルバッファでちらつき無し

何も考えずに絵を描画すると、描き直す様子が見えて画面がちらちらすると思います。これは言わば、壁に紙を貼ってからポスターを描くようなもの。現実には、そんなだるいことをやる人なんていません。すでに絵や文字が描かれた紙を、ぺたりと貼るのが普通です。ダブルバッファも同じようなものと考えると、わかりやすいでしょう

左がダブルバッファを使ったもの。右は普通に書いたもの。あまり複雑な絵ではないので、描画速度はさほど変わりませんが、それでも右は書いている様子がわかるかと思います

紙を確保する

※工事中

まっさらな紙を準備する

※工事中

絵を描いて貼り付ける

※工事中


XMLを読む

XMLとは何ぞや?と言うのは聞かないでください。聞かれてもわからないので説明できません。とりあえず「HTMLのようなタグ形式で、色んなデータを表現できる便利な構文」とだけ考えといてください。思いっきり間違った解釈ですが、それで事足りる場合が多いので気にせず前に進みましょう。「嘘を教えるな!」と思った人は、XMLのなんたるかを自力で調べに旅立ってください。完全に理解できたら、多分、このサイトなんか覗く必要もなくなってるはずです。がんばれ

SAXを使ってみる

※工事中

DOMを使ってみる

※工事中