独自のレンダラーを定義したJList。

JLabelを使ったレンダラー


今回作成したレンダラーは、薄い青の背景上に濃い青のテキストで項目を表示します。また選択された項目は、淡い赤に背景が変わります。簡単なものですが、JListの項目の表示が独自のものに変わっていることはわかるでしょう。

JListの項目表示に使われるレンダラーは、「ListCellRenderer」と呼ばれるインターフェイスとして用意されています。これをimplementsしたクラスを用意し、それを、

[JList].setCellRenderer( [ListCellRenderer] );

このようにしてJListに設定すれば、項目の表示にこのレンダラーが使われるようになります。このListCellRendererクラスは、以下のような形で定義されます。

classクラス名 implements ListCellRenderer {
  
  @Override
  public Component getListCellRendererComponent(
      JList list, Object object,int index,
      boolean isSelected, boolean hasFocus) {

    ……ここで、項目の表示に用いるコンポーネントを用意する……

    return コンポーネント;
  }

}

ListCellRendererでは、「getListCellRendererComponent」というメソッドを定義する必要があります。これは、項目を表示するのに用いられるコンポーネント(Componentインスタンス)を作成し、returnするものです。ここで用意されたコンポーネントが、そのままその項目の表示として用いられるのです。

このメソッドでは、5つの引数が用意されています。これらは、それぞれ以下のようなものを示します。

JList list――項目が表示されるJList
Object object――項目のデータ(Objectにキャストして渡される)
int index――その項目のインデックス番号
boolean isSelected――選択されているかどうか
boolean hasFocus――フォーカスがあるかどうか

ここでは、JLabelインスタンスを作成し、(String)objectをJLabelに表示テキストとして設定していますね。そして、項目が選択されているときには赤、そうでないときには青に背景色を設定します。

if (isSelected){
  label.setBackground(new Color(255,220,220));
} else {
  label.setBackground(new Color(220,220,255));
}

このように、引数で渡される値に応じて表示を変えることで、項目が選択されているときとそうでないときの表示をそれぞれ設定することができます。同様に、hasFocusの値に応じた処理を用意することで、フォーカスがあるときとそうでないときの表示を指定することもできます。

「あれ? 選択されているときと、フォーカスがあるときって、どこが違うの?」と思った人。たとえば、JListで複数項目を選択できるようにしたときを考えてみてください。複数の項目を選択状態にしたとき、最後にクリックした項目は「選択されていて、かつフォーカスがある」状態になっています。が、それ以外の選択された項目は「選択されているが、フォーカスはない」状態でしょう?

こうして、引数の値をチェックしながら、そのときの状況にあわせて設定されたコンポーネントを用意し、returnすると、そのコンポーネントが項目の表示に用いられ、画面に表示されるようになる、というわけです。レンダラーの仕組みそのものは、意外と簡単ですね?