広告 |
---|
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■ 2012年10月08日 Java総合講座 - 初心者から達人へのパスポート 2009年11月開講コース 064号 セルゲイ・ランダウ バックナンバー: http://www.flsi.co.jp/Java_text/ ■□■□■□■□■□■□■□■□■□■□■□■□■□■□■ ------------------------------------------------------- ・現在、このメールマガジンは以下の2部構成になっています。 [1] 当初からのコース:vol.xxx(xxxは番号)が振られています。 これは現在、中級レベルになっています。 [2] 2009年11月開講コース:xxx号(xxxは番号)が振られています。 これは現在、初心者向けのレベルになっています。 ・このメールマガジンは、画面を最大化して見てください。 小さな画面で見ていると、不適切な位置で行が切れてしまう など、問題を起すことがあります。 ・このメールマガジンに掲載されているソース・コード及び 文章は特に断らない限り、すべて筆者が著作権を所有してい ます。また、これらのソース・コードは学習用のためだけに 提供しているものです。 ------------------------------------------------------- ======================================================== ◆ 01.グラフィックスのプログラミング ======================================================== 今回は、時計に目覚まし(アラーム)の機能をつけましょう。 普通の目覚まし時計では、目覚ましの機能を有効にするためには、 (1) アラームを鳴らしたい時刻を設定する。 (2) アラーム機能をオンにする。 という2つの操作を行います。 逆にアラームが鳴っているときにそれを止めるためには、 (3) アラーム機能をオフにする。 という操作を行います。 今回のプログラムでは、(1)の操作のためにアラームの時刻を JComboBoxを使って数値で設定する機能を追加し、(2)と(3)のため にJToggleButtonを使ってアラーム機能をオン/オフに設定する 機能を追加することにします。 (ただし、JToggleButtonはオン/オフがちょっとわかりにくいの で、わかりやすくしたい人は、代わりにJCheckBoxなどを使用して みてください。JCheckBoxの使用は演習にします。) そして、設定された時刻が来るまで監視し、時刻が来たらアラーム音 を鳴らすための処理を別のスレッドで実行するようにします。 このプログラムでは、アラーム音の音声ファイルが必要になりますが、 アラーム音のファイルは下記のホームページの064号の項に掲載し てありますので、ダウンロードしてください。 http://www.flsi.co.jp/Java_text/ アラーム音のファイル名はalarm01.auです。 ダウンロードしましたら、このファイルをJavaWorksフォルダーの中 のJStudy1フォルダー配下のbinフォルダーの中にコピーしてください。 ┌補足─────────────────────────┐ この.auという拡張子がついているファイルは、Sun audio file と呼ばれる(auはaudioの略)音声ファイルの形式です。圧縮さ れた音声ファイルなので、サイズがかなり小さくて済み、インター ネットなどでダウンロードして利用するのには都合がいい形式で すが、その代わりに音質が悪いという欠点があります。 └───────────────────────────┘ では、さっそくEclipseを起動して、作業を始めましょう。 jp.co.flsi.lecture.clockパッケージの中にアラーム関連の処理 を行うためのAlarmJPanelというクラスをJPanelのサブクラスとし て作成しましょう。 (1) パッケージ・エクスプローラーの中のJStudy1のsrc配下の jp.co.flsi.lecture.clock を右クリックし、「新規」→「その他」を選択します。 (2) 「新規」ウインドウにおい「WindowBuilder」配下の 「Swing Designer」配下の「JPanel」を選択し、「次へ」ボタンを クリックします。 (3) 「ソース・フォルダー」に「JStudy1/src」が入力されていること を確認し、「パッケージ」がjp.co.flsi.lecture.clockになっていること を確認し、「名前」の欄に AlarmJPanel と入力しましょう。 (4) 「スーパークラス」が「javax.swing.JPanel」になっていることを確認し、 「完了」ボタンをクリックします。 AlarmJPanelのエディターが開きましたら、class文に「implements Runnable」 を追加しておきましょう。つまり、ソース・コードを -------------------------------------------------------- package jp.co.flsi.lecture.clock; import javax.swing.JPanel; public class AlarmJPanel extends JPanel implements Runnable { /** * Create the panel. */ public AlarmJPanel() { } } -------------------------------------------------------- というふうに編集します。 そうすると、AlarmJPanelに赤い下線が表示されますね。これは インターフェースRunnableのメソッドが実装されていないから (コンパイル)エラーになるためです。 そこで、AlarmJPanelの部分にカーソルを入れてCtrl+1する(Ctrlキーを押し ながら、数字の1キーを押す)と表示されるメニューの中から「実装されていない メソッドの追加」を選択して下さい。 (ついでながら、「Eclipseでエラーや警告に対処するためのメニューを表示する には該当箇所にカーソルを入れてCtrl+1」と覚えておいて下さい。059号を参照の こと。) そうすると、ソース・コードが -------------------------------------------------------- package jp.co.flsi.lecture.clock; import javax.swing.JPanel; public class AlarmJPanel extends JPanel implements Runnable { /** * Create the panel. */ public AlarmJPanel() { } @Override public void run() { // TODO 自動生成されたメソッド・スタブ } } -------------------------------------------------------- というふうに、自動的にrun()メソッドが追加されますね。 ┌補足─────────────────────────┐ ちなみにコメント行に「TODO」と書かれているのは、あとで編集 すべきことを意味します。ここでは、自動生成されたメソッドに 対して「TODO」が自動的に書かれていますが、編集を後回しに しておきたい(やり残しの作業がある)行などに対して自分で // TODO ・・・(何をすべきかの説明文)・・・ といった形式で「TODO」を書いておけば、目印になります。 └───────────────────────────┘ 続いて、Designビューを開き、このパネル(JPanel)を適切な サイズにしておきましょう。 JPanelの部分を選択(画面の中の灰色の部分をクリックするか、 または、Components欄の(javax.swing.JPanel)という文字列を クリックすると選択できる)し、Properties欄の 「Show advanced properties」ボタン(マウス・ポインターをのせる と「Show advanced properties」と表示されるボタン)をクリックし、 sizeプロパティーの値を 130,70 に変更して下さい。(sizeプロパティーの右端の「・・・」ボタンを クリックし、「サイズ」ウインドウで「幅」欄、「高さ」欄に それぞれ、130と70を入力して「OK」ボタンをクリックします。) なお、このパネルはサイズが小さいですから、あとでGUI部品を 貼り付けるときには、きれいに収まるように各GUI部品を小さめ に調整してください。 続いて、このパネルのLayoutManagerをnullにしておきましょう。 すなわちJPanelの画像を右クリックして「Set Layout」→ 「Absolute layout」を選択します。 また、このパネルの背景(background)を白色にしておきましょう。 パネルの画像の中をクリックして選択状態にし、Properties欄の のbackgroundプロパティーの値をColor.WHITE(backgroundプロパ ティーの右端の「・・・」ボタンをクリックし、「Color chooser」 ウインドウの「AWT colors」タブのページでWHITEを選択し、 「OK」ボタンをクリック)にしておきます。 ┌補足─────────────────────────┐ パネルが白色だと、パネルが選択状態でないときには背景の白色と 区別がつかなくなって、パネルがどこにあるのか分からなくなって しまいますが、そういうときはComponents欄の(javax.swing.JPanel) を選択してやればパネルが選択状態になって分かります。) └───────────────────────────┘ では、このパネルに、以下のようにGUI部品を貼り付けていきましょう。 (1) アラームの時刻設定の説明書き用にJLabelを貼り付けましょう。 パネルの上端近くに貼り付けて下さい。 そのtextプロパティーを「アラームの時刻:」にしておきましょう。 文字列がきちんと表示されるように、サイズを適当に調整しておいて ください。 (2) その下に、JComboBoxを貼り付けましょう。これは、アラームの時刻 のうち時(hour)を設定するためのものです。 変数名は comBoxAlarmHH にしておきましょう。 サイズを適当に調整しておいてください。 (3) その右隣にJLabelを貼り付けましょう。 そのtextプロパティーを「時」にしておきましょう。 サイズを適当に調整しておいてください。 (4) その右隣にJComboBoxを貼り付けましょう。これは、アラームの時刻 のうち分(minute)を設定するためのものです。 変数名は comBoxAlarmMM にしておきましょう。 サイズを適当に調整しておいてください。 (5) その右隣にJLabelを貼り付けましょう。 そのtextプロパティーを「分」にしておきましょう。 サイズを適当に調整しておいてください。 (6) パネルの下端近くにJToggleButtonを貼り付けましょう。 パネルが小さくて貼り付けが難しいので注意して下さい。 「10 x 49」などのように「数字 x 数字」が表示されている位置に貼りつける 必要があります。「数字 x 数字」が表示されない位置ではパネルからはみ出て しまい、正しく機能しません。 貼りつけたあと、textプロパティーの値は無し(デフォルトの文字列はすべて 削除して空文字にする)にして、サイズ(幅)を調整して(幅を縮めて)、 位置を右端のほうにずらしておいてください。 変数名は toggleButtonAlarmOnOff にしておきましょう。 (7) その左隣にJLabelを貼り付けましょう。 そのtextプロパティーを「アラーム:」にしておきましょう。 サイズを適当に調整しておいてください。 続いて、comBoxAlarmHHとcomBoxAlarmMMの2つのJComboBoxに対して、 表示する値を以下のようにして設定しましょう。 まずcomBoxAlarmHHのほうですが、自動生成されたコードは -------------------------------------------------------- JComboBox comBoxAlarmHH = new JComboBox(); comBoxAlarmHH.setBounds(0, 23, 46, 19); add(comBoxAlarmHH); -------------------------------------------------------- というふうになっていますね。(ただし、数値は設定した位置・サイズ によって異なります。) これを次のように編集しましょう。 -------------------------------------------------------- JComboBox comBoxAlarmHH = new JComboBox(); comBoxAlarmHH.setBounds(0, 23, 46, 19); for (int i = 0; i < 24; i++) { comBoxAlarmHH.addItem(Integer.toString(i)); } add(comBoxAlarmHH); -------------------------------------------------------- 何を編集したのかわかりますね。これでcomBoxAlarmHHには0時から23時 までの時刻が選択できるようになります。 続いてcomBoxAlarmMMのほうですが、自動生成されたコードは -------------------------------------------------------- JComboBox comBoxAlarmMM = new JComboBox(); comBoxAlarmMM.setBounds(68, 23, 46, 19); add(comBoxAlarmMM); -------------------------------------------------------- というふうになっていますね。(ただし、数値は設定した位置・サイズ によって異なります。) こちらも同様に次のように編集しましょう。 -------------------------------------------------------- JComboBox comBoxAlarmMM = new JComboBox(); comBoxAlarmMM.setBounds(68, 23, 46, 19); for (int i = 0; i < 60; i++) { comBoxAlarmMM.addItem(Integer.toString(i)); } add(comBoxAlarmMM); -------------------------------------------------------- これでcomBoxAlarmMMには0分から59分までの時刻が選択できるように なります。 実際に動作を確認するには、パッケージ・エクスプローラーからAlarmJPanel.java を右クリックし、「実行」→「Java Bean」を選択します。 このとき、JLabelの文字が表示しきれていない(端が欠けてしまっている等)など 貼りつけたGUI部品の位置やサイズが不適切であることが発覚した場合は、Designビュー に戻ってGUI部品の位置やサイズを調整し直してください。 Designビューでの見え方と、実際にアプリケーションを実行したときの見え方には 多少違いがありますので、このような調整が必要になります。 なお、comBoxAlarmMMやcomBoxAlarmMMは、のちに外部からアクセスする(つまり、 外部から目覚しを鳴らす時刻を設定する)可能性がありますので、外部からアクセス できるように設定しておきましょう。そのためには、Designビューにおいて、 これらのコンボボックス(comBoxAlarmMMとcomBoxAlarmMM)をそれぞれ、右クリック し、「Expose component...」を選択します。そして「Expose component」ウインドウ が開いたら、「OK」ボタンをクリックします。(comBoxAlarmMMとcomBoxAlarmMMの それぞれに対して同じ操作を行います。) そうすると、comBoxAlarmMMとcomBoxAlarmMMが(元々はローカル変数だったものが) それぞれ自動的にフィールドに変更され、かつ、自動的にgetter(getメソッド)が 生成されます。 では次に、設定された時刻になったらアラーム音を鳴らすためのコード を書きましょう。 「1分ごとに時刻をチェックして、現在時刻が設定された時刻と等しければ アラーム音を鳴らす」という処理をループで実行します。 (目覚まし機能はそんなに正確である必要はありません(目覚しが鳴っても もう少し寝たいというのが人情で、普通の人はそれより遅れて起床する??) から、1分ごとのチェックで充分だと考えます。) 前回お話したように、このようなループの処理は別のスレッドで行う 必要がありますから、run()メソッドに記述します。 その前に、アラーム機能がオンになっているかオフになっているかを 示すフィールドとして、下記のようなフィールドを追加しておいて ください。 -------------------------------------------------------- private boolean alarmMode = false; -------------------------------------------------------- また、アラーム音のオブジェクトを入れるフィールドとして下記の ようなフィールドを追加しておいてください。 -------------------------------------------------------- private AudioClip audioClip = null; -------------------------------------------------------- (AudioClipはjava.appletパッケージにはいっています。) さらに、このフィールドにアラーム音のオブジェクトをセットしたり、 逆に取り出したりするために次のようなsetter(setメソッド)、 getter(getメソッド)を追加しておきましょう -------------------------------------------------------- public void setAudioClip(AudioClip audioClip) { this.audioClip = audioClip; } public AudioClip getAudioClip() { return audioClip; } -------------------------------------------------------- また、現在の時刻がアラームの設定時刻と等しいかどうかをチェック するための下記のようなメソッドも追加しておきましょう。 -------------------------------------------------------- private boolean isAlarmTime() { GregorianCalendar newTime = new GregorianCalendar(); int alarmHH, alarmMM; try { alarmHH = Integer.parseInt((String)(getComBoxAlarmHH().getSelectedItem())); alarmMM = Integer.parseInt((String)(getComBoxAlarmMM().getSelectedItem())); } catch (NumberFormatException e) { return false; } if (newTime.get(Calendar.HOUR_OF_DAY) == alarmHH && newTime.get(Calendar.MINUTE) == alarmMM) { return true; } return false; } -------------------------------------------------------- では、run()メソッドのプログラミングをしましょう。 ソース・コード上の下記の部分 -------------------------------------------------------- @Override public void run() { // TODO 自動生成されたメソッド・スタブ } -------------------------------------------------------- を次のように編集しましょう。 -------------------------------------------------------- @Override public void run() { if (audioClip == null) return; while (alarmMode) { if (isAlarmTime()) { while (alarmMode) { getAudioClip().play(); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } try { Thread.sleep(60000); } catch (InterruptedException e) { } } } -------------------------------------------------------- 続いて、このスレッドを起動するための下記のようなメソッドを 追加しましょう。 -------------------------------------------------------- public void alarmThreadStart() { alarmMode = true; Thread aThread = new Thread(this); aThread.start(); } -------------------------------------------------------- また、このスレッドを停止するための下記のようなメソッドを追加 しましょう。 -------------------------------------------------------- public void alarmThreadStop() { alarmMode = false; } -------------------------------------------------------- 最後に、toggleButtonAlarmOnOffのトグル・ボタンがオンにされた ときにalarmThreadStart()メソッドを呼び出し。オフにされたときに alarmThreadStop()が呼び出されるようにプログラミングしましょう。 Designビューでトグル・ボタン(toggleButtonAlarmOnOff)を右クリッ クし、「Add event handler」→「アクション」→「actionPerformed」 を選択します。 下記のコードが自動生成されていますから、 -------------------------------------------------------- toggleButtonAlarmOnOff.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); -------------------------------------------------------- これを下記のように編集しましょう。 -------------------------------------------------------- toggleButtonAlarmOnOff.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (toggleButtonAlarmOnOff.isSelected()) alarmThreadStart(); else alarmThreadStop(); } }); -------------------------------------------------------- すると、例によってtoggleButtonAlarmOnOff変数がfinal指定されていない ことに対してエラー・メッセージが出ます(toggleButtonAlarmOnOffに赤色 の下線が引かれるので、そこにマウス・ポインターを持って行くとメッセージ が表示される)ので、toggleButtonAlarmOnOff変数をfinal指定にしましょう。 -------------------------------------------------------- JToggleButton toggleButtonAlarmOnOff = new JToggleButton(""); -------------------------------------------------------- という行にfinalを指定して -------------------------------------------------------- final JToggleButton toggleButtonAlarmOnOff = new JToggleButton(""); -------------------------------------------------------- というふうに編集して下さい。 以上で、AlarmJPanelは完成です。 次に、このAlarmJPanelをClockAppletに貼り付ける作業に移ります。 ClockAppletのソース・コードを開きましょう。 まず、AlarmJPanelのオブジェクトを入れるフィールドとして下記の行を ソース・コードに追加して下さい。 -------------------------------------------------------- private AlarmJPanel alarmJPanel; -------------------------------------------------------- 続いて、ClockApplet()コンストラクターの最後に下記のようなコードを 追加しましょう。 -------------------------------------------------------- alarmJPanel = new AlarmJPanel(); alarmJPanel.setBounds(170, 0, 130, 70); getContentPane().add(alarmJPanel); -------------------------------------------------------- では、続いてClockAppletのinit()メソッド -------------------------------------------------------- public void init() { this.setSize(300, 200); this.setContentPane(getContentPane()); clockJPanel.clockStart(); } -------------------------------------------------------- を編集して、次のようにアラーム音のファイルを取り込んで AlarmJPanelに渡すコードを追加しましょう。 -------------------------------------------------------- public void init() { this.setSize(300, 200); this.setContentPane(getContentPane()); clockJPanel.clockStart(); AudioClip audioClip = getAudioClip(getDocumentBase(), "alarm01.au"); alarmJPanel.setAudioClip(audioClip); } -------------------------------------------------------- getAudioClip()メソッドはAppletのメソッドで、指定された場所 (ここではgetDocumentBase()メソッドを呼び出すことによって、 アプレットが置かれているHTMLの場所と同じ場所を指定している) から指定されたファイル名(ここではalarm01.au)の音声ファイル を取り出して、AudioClip型のオブジェクトにしてくれます。 そこで、そのAudioClipオブジェクトをAlarmJPanelのsetAudioClip() メソッドを呼び出すことによって、AlarmJPanelに渡しています。 以上で、アラームの機能は完成です。 ClockAppletを起動してテストしてみてください。 アラームの時刻をセットしてアラームをオンにすれば、ちゃんとセット した時刻にアラーム音が鳴りますね。(ただし、1分おきにチェックして いるので、タイミングが悪ければ最大1分ほどアラームが遅れることが あります。) また、アラーム音が鳴っているときにアラームをオフにすれば、ちゃん と音が止まりますね。 では、今回はここまでにします。なお、今回作成したアプレットはホー ムページにも掲載しておきますので、完成したアプレットの動きを確認 したい人は下記ホームページの064号の項目から実行してみてください。 http://www.flsi.co.jp/Java_text/ 何か、わからないところがありましたら、下記のWebページまで質問を お寄せください。 (続く) ======================================================== ◆ 02.文法解説 [アプレット(5)] ======================================================== [アプレット(5)「アプレットの情報」] AppletのgetAppletInfo()メソッドを実装(オーバーライド)する ことにより、アプレットビューアでアプレットを起動したときに アプレットの情報を表示させることができます。 たとえば、アプレットのソース・コードの中に -------------------------------------------------------- public String getAppletInfo() { return "Title: ClockApplet \n" + "Author: Sergei Landau, 2007 \n" + "A sample alarm clock."; } -------------------------------------------------------- というようにgetAppletInfo()メソッドをコーディングしておくと、 このreturn文で返す内容が、アプレットビューアの「アプレット」 メニューの中の「情報」というメニュー項目を選択することによっ て表示されます。 このとき同時にパラメーターの情報も表示されます。これは、Applet のgetParameterInfo()メソッドを実装(オーバーライド)することに より表示されます。 たとえば057号の「アプレットのパラメーター」のサンプルに合わせ た情報にすると、 -------------------------------------------------------- public String[][] getParameterInfo() { String[][] info = { {"rectwidth", "positive integer", "The width of the rectangular. Default is 100."}, {"rectheight", "positive integer", "The height of the rectangular. Default is 50."} }; return info; } -------------------------------------------------------- というようなコードを書いておけばいいのです。 それぞれ、パラメーター名、型の種類、説明、という3種類の情報を パラメーターごとに書いておきます。 これらの情報を提供するコードは、アプレットの一般ユーザーには 役に立ちませんが、開発者にとっては覚書として利用することがで きます。 (続く) 以上、今回は ┌───────────────────────────┐ ・アプレットでの音声ファイルの取り込み(getAudioClip()メソッドの使用)方法 ・音声ファイルからの音の鳴らし方(AudioClipのplay()メソッド) ・指定された時刻に処理を実行するためのプログラミング ・アプレット情報のコーディング方法 └───────────────────────────┘ を学習しました。 では、また来週。 (続く) ================================================ ◆ 03.演習問題 ================================================ アラーム機能のオン/オフの設定に使ったGUI部品がJToggleButtonでは ちょっとわかりにくいので、JToggleButtonの代わりにJCheckBoxを使用 してプログラムを修正してみてください。 やり方がわからない人は、下記Webページにて質問をお寄せください。 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ★ホームページ: 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) 2012 Future Lifestyle Inc. 不許無断複製 |