前のページまでで作ったプログラムのクラス図を示します。
Javaでは宣言だけで実体がないメソッドを abstract メソッドと呼びます。
そして、これまで紹介した各種インターフェイス
(ActionListener、MouseListener、KeyListener)は、
abstract メソッドだけで作られるている特別なクラス
といえます。
そして、Javaのイベント用の
処理は、このようにインターフェイスで提供されており、利用する場合は、
インターフェイスをimplementsで指定して、
abstract メソッドをオーバーライドする形で作ります。
上記クラスのプログラムでは、TestFrm043クラス定義の先頭が次のようになっていまいした。
class TestFrm043 extends TestFrm042 implements KeyListener,ActionListener
これは次の意味です。
extendsキーワードでTestFrm042を継承し、TestFrm043を作っています。
そして同様に、
implementsキーワードでKeyListenerと
ActionListenerを継承し、TestFrm03を作っています。
つまり、extends、implementsキーワード共に、継承したクラスを
作るという指定です。
実際、このように作ったオブジェクトは、その継承元の型の変数で、
次のように参照することができます。
TestFrm04 f1 = new TestFrm042(); //f1で管理
ActionListener f2 = new TestFrm042();//f2で管理
MouseListener f3 = new TestFrm042();//f3で管理
KeyListenerをimplementsしたのはTestFrm043で、TestFrm042は実装してません。よって次はエラーです。
KeyListener f4 = new TestFrm042();//f4で管理
では、extends と implementsの違いは何でしょうか?
extendsの後に指定できるクラスは一つだけしかできません。
またその時に、継承元クラスにあるabstract メソッドを実体として
オーバーライドしなければならないということはありません。
対して、implementsで指定するインターフェイス名は、
インターフェイス名が異なれば、何個指定して構いません(コンマで区切って並べます)。
但し、指定したインターフェイスのabstract メソッド(宣言)は
全て実体を作らなくてはならない規則になっています。
これまで、インターフェイスにより分けて、TestFrm041、TestFrm042、TestFrm043と
作成しましたが、一つのファイルで全てを作ることもできます。
それをTestFrm044クラスで作成した例として、クラス図とコードを以下に示します。
方が良い。
←『未選択』の箇所を選択して評価ボタンをクリックください
package test; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestFrm044 extends JFrame implements ActionListener, KeyListener, MouseListener// 3つのインターフェイス実装 { JButton btn1 = new JButton("Set"); JLabel lbl1 = new JLabel("ラベル1"); JList lst1 = new JList(); JTextField txt1 = new JTextField("変更して入力"); JTextArea txtArea1 = new JTextArea("複数の\r\n行を\r\n入力"); DefaultListModel listModel = new DefaultListModel(); public TestFrm044(){ Container container = getContentPane(); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setTitle("TestFrm04"); container.add(btn1, BorderLayout.EAST); container.add(this.lbl1, BorderLayout.NORTH); this.lbl1.setOpaque(true);//ラベルを「不透明な」設定にします。 this.lbl1.setBackground(new Color(100, 255, 100));//ラベルの背景色設定 container.add(new JScrollPane(lst1), BorderLayout.WEST); this.lst1.setModel(this.listModel); this.listModel.add(0, "abc");//先頭に追加挿入 this.listModel.add(1, "123 45");//1番目に追加挿入 this.listModel.add(2, "あいう");//2番目に追加挿入 container.add(this.txt1, BorderLayout.SOUTH); container.add(new JScrollPane(txtArea1), BorderLayout.CENTER); this.txtArea1.setFont(new Font("Serif", Font.BOLD, 20)); //フォント設定 this.txtArea1.setBackground(new Color(255, 255, 100));//テキストエリアの背景色設定 this.setBounds(0, 0, 200, 160); this.setVisible(true); this.btn1.addActionListener(this); this.lst1.addMouseListener(this); this.txt1.addKeyListener(this); } public void actionPerformed(ActionEvent e){//ActionListenerの実装 if (this.btn1.getText().equals("削除") == false){ String s = this.txt1.getText();//txt1のテキストを取得 this.lbl1.setText("「" + s + "」を追加しました");//ラベルの文字列を設定 int idx = this.lst1.getSelectedIndex();//リスト選択項目の添え字取得 if (idx == -1){ idx = listModel.getSize();//サイズを返す。 } this.listModel.add(idx, s);//idxのリスト位置に追加挿入 }else{//削除処理 int リスト選択添え字 = this.lst1.getSelectedIndex(); if (リスト選択添え字 != -1){//削除 this.lbl1.setText("「" + リスト選択添え字 + "」の位置を削除しました");//ラベルの文字列を設定 this.listModel.remove(リスト選択添え字); } } } public void keyPressed(KeyEvent e){//キーを押しているときに呼び出されます。 System.out.println(this.txt1.getText() + ":Rress=" + e.getKeyCode()); } public void keyReleased(KeyEvent e){//キーを離したときに呼び出されます。 System.out.println(this.txt1.getText() + ":Released=" + e.getKeyCode()); if (this.txt1.getText().equals("")) { this.btn1.setText("削除"); }else{ this.btn1.setText("追加"); if (e.getKeyCode() == 10){//Enterが押されたたか? this.actionPerformed(null);//クリックと同じ操作のメソッドを実行 } } } public void keyTyped(KeyEvent e){//キーをタイプすると呼び出されます。 System.out.println(this.txt1.getText() + ":Typed=" + e.getKeyChar()); } public void mouseEntered(MouseEvent e){// コンポーネントにマウスが入ると呼び出されます。 } public void mousePressed(MouseEvent e){// コンポーネント上でマウスボタンが押されると呼び出されます。 } public void mouseReleased(MouseEvent e){// コンポーネント上でマウスボタンが離されると呼び出されます。 } public void mouseClicked(MouseEvent e){//マウスクリック java.awt.Point p = e.getPoint();//クリック位置座標を取得 int idx = this.lst1.locationToIndex(p);//クリック位置の項目を添え字取得 this.lbl1.setText(p.x + "," + p.y + "の座標クリックで、リスト内項目添え字は" + idx + "です"); if (idx == -1) return;//クリック位置が、リスト項目でない String itemStr = (String)this.listModel.get(idx);//クリックしたリスト内項目の文字列 if (e.getClickCount() == 2){//ダブルクリックならテキストエリアに挿入 int start = this.txtArea1.getSelectionStart();//テキストの選択位置スタート位置取得 int end = this.txtArea1.getSelectionEnd();//テキストの選択位置エンド位置取得 this.txtArea1.replaceRange(itemStr, start, end); //テキストの部分置き換え } } public void mouseExited(MouseEvent e){//コンポーネントからマウスが出ると呼び出されます。 } public static void main(String[] args){ new TestFrm044(); } }
太字のようにJScrollPaneを生成すれば、JScrollPaneのフィールドで用意しなくても作れます。