■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2007年06月18日

    楽しいJava講座 - 初心者から達人へのパスポート
                  vol.058

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.グラフィックスのプログラミング
========================================================

前回、GraffitiAppletに線の太さを変える機能を組み込むことを
忘れていましたので、急遽その機能を組み込むことにしましょう。


では、Eclipseを起動し、まずGraffitiPanelのエディターを開い
てください。

(1) 以下のフィールドを追加しましょう。

--------------------------------------------------------
private Stroke drawStroke = new BasicStroke(1f);
--------------------------------------------------------

つまり、Strokeの変数としてdrawStrokeを用意し、デフォルト値
を標準的な実線の太さにしておきます。

(2) paint()メソッドの

--------------------------------------------------------
aDecoLines.setColor(lineColor);
--------------------------------------------------------

の行の下に

--------------------------------------------------------
aDecoLines.setStroke(drawStroke);
--------------------------------------------------------

を追加しましょう。

念のためにpaint()メソッド全体のソース・コードを下に提示し
ます。

--------------------------------------------------------
public void paint(Graphics g) {
   Graphics2D g2d = (Graphics2D) g;
   Image image = createImage(300, 200);
   Graphics2D g2dImage = (Graphics2D) image.getGraphics();

   DecoratedLines aDecoLines = null;

   if(freeCurveFlag) {
      aDecoLines = new DecoratedLines();

      for(int loopIndex = 0; loopIndex < ptIndex - 1; loopIndex++) {
         aDecoLines.addLine(new Line2D.Float(pts[loopIndex].x, pts[loopIndex].y, pts[loopIndex+1].x, pts[loopIndex+1].y));
      }
      aDecoLines.setColor(lineColor);
      aDecoLines.setStroke(drawStroke);
   }

   if (aDecoLines != null) {
      if (!mousePressed) {
         freeCurves.add(aDecoLines);
         ptIndex = 0;
      }
      else {
         aDecoLines.paintSelf(g2dImage);
      }
   }

   for (DecoratedLines lines : freeCurves) {
      lines.paintSelf(g2dImage);
   }

   g2d.drawImage(image, 0, 0, 300, 200, null);
}
--------------------------------------------------------

(3) 次のメソッドを追加します。

--------------------------------------------------------
public void setDrawStroke(Stroke s) {
   drawStroke = s;
}
--------------------------------------------------------

このsetDrawStroke()メソッドを呼び出せば、描画の線の太さや線の
種類を変更できるわけです。



では、GraffitiAppletのほうでこのメソッドを呼び出して線の太さを
変えられるようにGraffitiAppletのプログラムを変更しましょう。
線の太さはJListというGUI部品を使って選択できるようにすることに
します。

GraffitiAppletのVEエディターを開いてください。

(1) パレット(Palette)からJListを取り出して色ボタン(「青」ボタン)
の下に貼り付けてください。Bean NameはstrokeListにしましょう。

(2) 貼り付いたstrokeListの大きさを適当に広げてください。

(3) 下記のようなソース・コードが自動的に追加されていますね。

--------------------------------------------------------
private JList getStrokeList() {
   if (strokeList == null) {
      strokeList = new JList();
      strokeList.setBounds(new Rectangle(14, 106, 46, 41));
   }
   return strokeList;
}
--------------------------------------------------------
ただし、setBounds(Rectangle(14, 106, 46, 41))の数値はstrokeListの
位置と大きさを示しているので、上と同じである必要はありません。

これを下記のように編集しましょう。

--------------------------------------------------------
private JList getStrokeList() {
   if (strokeList == null) {
      Vector<String> stroke = new Vector<String>();
      strokeList = new JList(stroke);
      stroke.add("太さ1");
      stroke.add("太さ2");
      stroke.add("太さ5");
      strokeList.setBounds(new Rectangle(14, 106, 49, 53));
   }
   return strokeList;
}
--------------------------------------------------------

Swingのユーザー・インターフェースとモデルを分離する方式では、JListは
ListModelというインターフェースを実装したモデル・オブジェクトにデータ
を入れて使用することができます。
しかし、上のソース・コードではもっと簡単に、Vectorを使ってJListに表示
する文字列を追加する方法を取っています。その場合は、JListのコンストラ
クターのうちVectorを引数にとるコンストラクターを使用し、Vectorのadd()
メソッド(またはaddElement()メソッド)で文字列を追加しておきます。

保管したら、一度GraffitiAppletを実行してどのように見えるか確認してくだ
さい。


では、続いてこのstrokeListの中のどれかの行を選択するとその線の太さで
自由曲線が描けるようにプログラミングしましょう。

(1) VEエディターのstrokeListを右クリックし、「Events」→「valueChanged」
を選択します。

(2) getStrokeList()メソッドの中に

--------------------------------------------------------
strokeList
      .addListSelectionListener(new javax.swing.event.ListSelectionListener() {
         public void valueChanged(javax.swing.event.ListSelectionEvent e) {
            System.out.println("valueChanged()"); // TODO Auto-generated Event stub valueChanged()
         }
      });
--------------------------------------------------------

というソース・コードが自動的に追加されましたね。JList上で選択する行が
変わると、このListSelectionListenerのvalueChanged()メソッドが呼び出さ
れることになります。
ちなみに上のソース・コードは変なところで改行されてしまっていますが、

--------------------------------------------------------
strokeList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
   public void valueChanged(javax.swing.event.ListSelectionEvent e) {
      System.out.println("valueChanged()"); // TODO Auto-generated Event stub valueChanged()
   }
});
--------------------------------------------------------

と同じです。これを下記のソース・コードのように編集しましょう。

--------------------------------------------------------
strokeList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
   public void valueChanged(javax.swing.event.ListSelectionEvent e) {
      switch (strokeList.getSelectedIndex()){
      case 0:
         getGraffitiPanel().setDrawStroke(new BasicStroke(1f));
         break;
      case 1:
         getGraffitiPanel().setDrawStroke(new BasicStroke(2f));
         break;
      case 2:
         getGraffitiPanel().setDrawStroke(new BasicStroke(5f));
         break;
      }
   }
});
--------------------------------------------------------


はい。これで線の太さを変えるための実装は完了です。

では、保管した後、GraffitiAppletを実行してテストしてみてください。


今回はここまで。


(続く)




========================================================
◆ 02.文法解説 [アプレット]
========================================================

[アプレット(2)「アプレットのメソッド」]

アプレットはアプリケーションと異なり、main()メソッドを使用しません。
Appletクラスにはmain()メソッドの代わりに下記の4つのメソッドが用意さ
れています。

(1)  init()メソッド[ public void init() ]
アプレットを含むWebページがWebブラウザーによって読み込まれ表示される
ときにアプレットがメモリー上にロードされ起動されますが、そのときに
1回だけinit()メソッドが実行されます。
init()はアプレットのデータの初期設定作業などに使用されます。
Appletクラスのinit()メソッドは何もしません。必要ならばAppletのサブ
クラスでinit()メソッドを上書きして実装します。

(2)  start()メソッド[ public void start() ]
start()メソッドはinit()メソッドが実行された後に実行されます。
また、Webブラウザーがいったん他のWebページを開くことによって、アプ
レットが含まれているWebページが表示されなくなった後、再度アプレット
が含まれているWebページが表示されると、その時点でもstart()メソッド
が実行されます。
音楽やアニメーションなどを流すアプレットではstart()メソッドでそれら
を開始するように実装することが多いです。
Appletクラスのstart()メソッドは何もしません。必要ならばAppletのサブ
クラスでstart()メソッドを上書きして実装します。

(3)  stop()メソッド[ public void stop() ]
stop()メソッドは、Webブラウザーがいったん他のWebページを開くことに
よって、アプレットが含まれているWebページが表示されなくなったときに
実行されます。
また、Webブラウザーを終了したときなど、Webページが解放されるときにも
実行されます。
音楽やアニメーションなどを流すアプレットではstop()メソッドでそれらを
停止するように実装することが多いです。
Appletクラスのstop()メソッドは何もしません。必要ならばAppletのサブク
ラスでstop()メソッドを上書きして実装します。

(4)  destroy()メソッド[ public void destroy() ]
destroy()メソッドはWebブラウザーを終了したときなど、Webページが解放
されるときに、stop()メソッドの実行後に実行されます。
アプレットのデータの後始末作業などに使用されます。
Appletクラスのdestroy()メソッドは何もしません。必要ならばAppletのサ
ブクラスでdestroy()メソッドを上書きして実装します。

なお、アプレットが含まれているWebページを表示した後、Webブラウザーの
リロード・ボタン(「更新」ボタン)をクリックしたときには、
stop()→destroy()→Webページの再読み込み→init()→start()の順に実行
されることになります。


(続く)



================================================
◆ 03.演習問題
================================================

GraffitiAppletのstrokeListに別の線の太さを追加してプログラム
を改良してみてください。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2007 Future Lifestyle Inc. 不許無断複製