リスト


項目の選択

リストは、複数の選択可能オブジェクトをユーザーに選択させるコンポーネントです
これは javax.swing.JList クラスで実装されています
java.lang.Object
  |
  +--java.awt.Component
        |
        +--java.awt.Container
              |
              +--javax.swing.JComponent
                    |
                    +--javax.swing.JList

public class JList extends JComponent
	implements Scrollable, Accessible
このクラスは次のようなコンストラクタを公開しています

public JList()
public JList(Vector listData)
public JList(Object[] listData)
public JList(ListModel dataModel)

listData には、リストが表示する項目を表す配列や Vector を指定します
detaModel はリストのデータモデルを直接指定します

リストは javax.swing.ListModel インターフェイスから項目を作成します
ListModel は項目数と項目の Object を返す役割を与えられています

public interface ListModel

項目数は ListModel.getSize() メソッドで取得し
項目の内容は ListModel.getElementAt() メソッドで取得することができます

public int getSize()
public Object getElementAt(int index)

index には、取得したい項目のリスト内のインデックスを指定します
また、データモデルが変更された時のイベントを処理するためのリスナを
ListModel.addListDataListener() メソッドで追加し
ListModel.removeListDataListener() メソッドで解除できます

public void addListDataListener(ListDataListener l)
public void removeListDataListener(ListDataListener l)

l には追加する、または解除するリスナを指定します
javax.swing.event.ListDataListener はデータモデルが変更されると通知されます

public interface ListDataListener extends EventListener

項目の挿入には ListDataListener.intervalAdded() メソッドが
項目の解除には ListDataListener.intervalRemoved() メソッドが
置き換えなどの変更は ListDataListener.contentsChanged() が呼び出されます

public void intervalAdded(ListDataEvent e)
public void intervalRemoved(ListDataEvent e)
public void contentsChanged(ListDataEvent e)

e にはイベントの発生情報を格納した ListDataEvent を指定します
javax.swing.event.ListDataEvent はリストへの変更をカプセル化しています
java.lang.Object
  |
  +--java.util.EventObject
        |
        +--javax.swing.event.ListDataEvent

public class ListDataEvent extends EventObject
今回は、特に重要ではないのでこのクラスについては省略します
リストモデルの項目の変更に対する処理を行いたい場合に使うことができるでしょう

リストは、スクロールペインを持たないので、スクロールバーは存在しません
項目が表示しきれなくなった時に備え、スクロールペイント併用すると良いでしょう
import java.awt.*;
import javax.swing.*;

public class Test extends JApplet {
	public void init() {
		String item[] = {
			"涼宮 遙" , "速瀬 水月" , "涼宮 茜" ,
			"大空寺 あゆ" , "玉野 まゆ"
		};

		JList list = new JList(item);
		JScrollPane scroll = new JScrollPane(list);
		getContentPane().add(scroll);
	}
}


このプログラムは、スクロールペインにラベルを追加し
ラベルを付加したスクロールペインをアプレットに追加しています

項目は JList.setListData() メソッドか
JList.setModel() メソッドを用いて、構築後も変更することができます
モデルを取得するには JList.getModel() メソッドを使います

public void setListData(Object[] listData)
public void setListData(Vector listData)
public void setModel(ListModel model)
public ListModel getModel()

listData には項目の配列、または Vector を指定します
model には新しいリストモデルを指定します
リストの情報は getModel() を使い ListModel インターフェイスから得ることができます

プログラムは、選択されている項目を知る必要があるでしょう
選択されている項目のインデックスは JList.getSelectedIndex() メソッドで
選択されているオブジェクトは JList.getSelectedValue() で得られます
これとは逆に、set_() メソッドを使ってプログラムから項目を選択することもできます

public void setSelectedIndex(int index)
public void setSelectedValue(Object anObject , boolean shouldScroll)
public int getSelectedIndex()
public Object getSelectedValue()

index には選択する項目のインデックスを、anObject には選択する項目を指定します
shouldScroll はリストをスクロールして選択した項目を表示する場合は true
スクロールの必要がないのであれば false を指定してください

選択項目が変更するタイミングを受けるリスナは
JList.addListSelectionListener() メソッドで追加できます
解除するには JList.removeListSelectionListener() を使います

public void addListSelectionListener(ListSelectionListener listener)
public void removeListSelectionListener(ListSelectionListener listener)

listener には追加、または解除するリスナを指定します
javax.swing.event.ListSelectionListener インターフェイスは
リストの選択範囲が変更されたときに通知されるメソッドを提供します

public interface ListSelectionListener extends EventListener

リストは ListSelectionListener.valueChanged() メソッドを呼び出します
このインターフェイスは、この valueChanged() メソッドのみを宣言しています

public void valueChanged(ListSelectionEvent e)

e にはイベント情報を表す ListSelectionEvent を指定します
javax.swing.event.ListSelectionEvent はリストイベント情報を保有します
java.lang.Object
  |
  +--java.util.EventObject
        |
        +--javax.swing.event.ListSelectionEvent

public class ListSelectionEvent extends EventObject
このクラスのコンストラクタは次のようになっています
public ListSelectionEvent(
	Object source , int firstIndex ,
	int lastIndex, boolean isAdjusting
)
source にはイベント発生元オブジェクトを指定します
firstIndex は変更された最初のインデックス、lastIndex は最後のインデックスを指定します
isAbjusting は、連続的にイベントが発生している場合に true を指定します
これは、リスト項目上でマウスをドラッグしながら選択を繰り返している場合などです

ListSelectionEvent クラスは、コンストラクタで指定した情報を
リスナメソッドが取得するための get_() メソッドを公開していますが
今回は使わないので、省略します
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet implements ListSelectionListener {
	JLabel label = new JLabel("項目を選択してください");
	JList list = new JList();

	public void init() {
		String item[] = {
			"涼宮 遙" , "速瀬 水月" , "涼宮 茜" ,
			"大空寺 あゆ" , "玉野 まゆ"
		};

		list.setListData(item);
		list.addListSelectionListener(this);

		getContentPane().add(label , BorderLayout.NORTH);
		getContentPane().add(new JScrollPane(list) , BorderLayout.CENTER);
	}
	public void valueChanged(ListSelectionEvent e) {
		label.setText(list.getSelectedValue().toString());
	}
}


このプログラムは、リストを選択すると上部のラベルに文字を表示させます

因みに、Swing のリストはデフォルトで複数選択可能状態です
しかし、リストは単一選択と連続区域選択モードもサポートしています
これは JList.setSelectionMode() で設定できます
現在の選択モードは JList.getSelectionMode() で取得できます

public void setSelectionMode(int selectionMode)
public int getSelectionMode()

selectionMode には、選択モードを表す整数を指定します
ここで指定する整数は javax.swing.ListSelectionModel インターフェイスの
フィールド定数として宣言されている次の値です

public interface ListSelectionModel

定数解説
public static final int SINGLE_SELECTION リストインデックスを 1 回に 1 つ選択します
public static final int SINGLE_INTERVAL_SELECTION インデックスの連続範囲を 1 回に 1 つ選択します
public static final int MULTIPLE_INTERVAL_SELECTION インデックスの連続範囲を 1 回に 1 つ以上選択します

複数選択モードの場合、当然複数の項目が選択されている可能性があり
これは、getSelectedValue() などのメソッドでは得ることができません
複数選択状態で単一項目を取得した場合、最初に選択された項目が返ります

そこで JList.getSelectedIndices() メソッドを使います
このメソッドは、選択されている項目のインデックス配列を返します
同様に JList.getSelectedValues() オブジェクト配列を返してくれます
複数選択を行うには JList.setSelectedIndices() メソッドを使います

public void setSelectedIndices(int[] indices)
public int[] getSelectedIndices()
public Object[] getSelectedValues()

indices には、選択する各項目のインデックスを格納した配列を指定します
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet implements ActionListener {
	JList list = new JList();
	public void init() {
		String item[] = {
			"涼宮 遙" , "速瀬 水月" , "涼宮 茜" ,
			"大空寺 あゆ" , "玉野 まゆ"
		};
		list.setListData(item);

		JButton button = new JButton("Show Selected");
		button.addActionListener(this);

		getContentPane().add(button , BorderLayout.NORTH);
		getContentPane().add(new JScrollPane(list) , BorderLayout.CENTER);
	}
	public void actionPerformed(ActionEvent e) {
		JOptionPane.showMessageDialog(this , list.getSelectedValues());
	}
}


このプログラムは、複数選択に対応したイベント処理を行っています
ボタンを押すと、選択されている項目を全てダイアログに表示します


セルレンダラ

JList は、項目を描画する時に登録されているセルレンダラを呼び出します
セルレンダラは、リストに表示するコンポーネントを返します
リストは、取得したコンポーネントの描画表現を用いて項目を描画します

通常、セルレンダラは項目を表す JLabel を返します
セルレンダラは javax.swing.ListCellRenderer インターフェイスで実装します

public interface ListCellRenderer

このインターフェイスは、たった一つのメソッド
ListCellRenderer.getListCellRendererComponent() を宣言しています
public Component getListCellRendererComponent(
	JList list , Object value , int index ,
	boolean isSelected , boolean cellHasFocus
)
list はレンダラを呼び出したリスト、value は描画するセル項目の値
index は項目のインデックスを指定します
isSelected はセルが選択されているかどうか
cellHasFocus はセルにフォーカスがあるかどうかを表すブーリアンを指定します

セルレンダラは list や value などの与えられた情報を参考に
JLabel など、描画に用いるコントロールを生成してリストに返します

セルレンダラをリストに設定するには JList.setCellRenderer()
セルレンダラを取得するには JList.getCellRenderer() を使います

public void setCellRenderer(ListCellRenderer cellRenderer)
public ListCellRenderer getCellRenderer()

cellRenderer にはセルレンダラを指定します
これを用いれば、自由に項目をカスタマイズすることができるようになります

リストの選択項目の背景色は JList.setSelectionBackground() で設定し
前景色は JList.setSelectionForeground() で設定できます
セルレンダラはこれを考慮し、設定されている色に準拠するべきです
これらに対応した get_() メソッドがあるので、これから情報を取得できます

public void setSelectionBackground(Color selectionBackground)
public void setSelectionForeground(Color selectionForeground)
public Color getSelectionBackground()
public Color getSelectionForeground()

selectionBackground には選択時の背景色を
selectionForeground には選択時の前景色を指定することができます
import java.awt.*;
import javax.swing.*;

/*	<applet code="Test.class" width="300"height="300">
 	</applet>
*/

public class Test extends JApplet implements ListCellRenderer {
	JList list = new JList();
	public void init() {
		String item[] = new String[10];
		for(int i = 0 ; i < item.length ; i++) item[i] = "Kitty " + i;
		list.setListData(item);
		list.setCellRenderer(this);

		getContentPane().add(new JScrollPane(list));
	}
	public Component getListCellRendererComponent(
			JList list , Object value , int index ,
			boolean isSelected , boolean cellHasFocus) {
		Icon icon = new ImageIcon("icon.jpg");
		JLabel label = new JLabel();
		label.setOpaque(true);
		label.setPreferredSize(new Dimension(
			icon.getIconWidth() , icon.getIconHeight()
		));

		if (isSelected) {
			label.setText(value.toString());
			label.setIcon(icon);
			label.setBackground(list.getSelectionBackground());
			return label;
		}
		else {
			label.setText("◆" + value.toString());
			label.setBackground(list.getBackground());
			return label;
		}
	}
}


このプログラムでは、独自のセルレンダラをリストに登録しています
リストは、項目を描画するときにセルレンダラを呼び出してコンポーネントを求めます



前のページへ戻る次のページへ