• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JListで異なる高さのセルを使用
#navi(../)
*JListで異なる高さのセルを使用 [#v5f5cc63]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2006-05-15~
更新日:&lastmod;
---
category: swing
folder: DifferentCellHeight
title: JListで異なる高さのセルを使用
tags: [JList, JTextArea, ListCellRenderer]
author: aterai
pubdate: 2006-05-15T09:36:24+09:00
description: JListのレンダラーにJTextAreaを使って、異なる高さのセルを作成します。
image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTK2Z8UOTI/AAAAAAAAAWo/7GoDkuVX8Fc/s800/DifferentCellHeight.png
---
* 概要 [#summary]
`JList`のレンダラーに`JTextArea`を使って、異なる高さのセルを作成します。

#contents
#download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTK2Z8UOTI/AAAAAAAAAWo/7GoDkuVX8Fc/s800/DifferentCellHeight.png)

**概要 [#x1d27318]
JListのレンダラーにJTextAreaを使って、異なる高さのセルを作成します。
* サンプルコード [#sourcecode]
#code(link){{
class TextAreaRenderer<E extends String> extends JTextArea
                                         implements ListCellRenderer<E> {
  private static final Color EVEN_COLOR = new Color(230, 255, 230);
  private Border noFocusBorder;
  private Border focusBorder;

#screenshot
  @Override public Component getListCellRendererComponent(
      JList<? extends E> list, E value, int index,
      boolean isSelected, boolean cellHasFocus) {
    // setLineWrap(true);
    setText(Objects.toString(value, ""));
    if (isSelected) {
      // Nimbus
      setBackground(new Color(list.getSelectionBackground().getRGB()));
      setForeground(list.getSelectionForeground());
    } else {
      setBackground(index % 2 == 0 ? EVEN_COLOR : list.getBackground());
      setForeground(list.getForeground());
    }
    if (cellHasFocus) {
      setBorder(focusBorder);
    } else {
      setBorder(noFocusBorder);
    }
    return this;
  }

**サンプルコード [#r38aaded]
#code{{
 class TextAreaRenderer extends JTextArea implements ListCellRenderer {
   private final Border border = new DotBorder(2,2,2,2);
   private final Color evenColor = new Color(230,255,230);
   public Component getListCellRendererComponent(
       JList list, Object object, int index,
       boolean isSelected, boolean cellHasFocus) {
     setText((object==null) ? "" : object.toString());
     setBorder(cellHasFocus ? border 
                 : BorderFactory.createEmptyBorder(2,2,2,2));
     if(isSelected) {
       setBackground(list.getSelectionBackground());
       setForeground(list.getSelectionForeground());
     }else{
       setBackground(index%2==0 ? evenColor : list.getBackground());
       setForeground(list.getForeground());
     }
     return this;
   }
 }
 
 private DefaultListModel makeList() {
   DefaultListModel model = new DefaultListModel();
   model.addElement("一行");
   model.addElement("一行目\n二行目");
   model.addElement("一行目\n二行目\n三行目");
   model.addElement("四行\n以上ある\nテキスト\nの場合");
   return model;
 }
  @Override public void updateUI() {
    super.updateUI();
    focusBorder = UIManager.getBorder("List.focusCellHighlightBorder");
    noFocusBorder = UIManager.getBorder("List.noFocusBorder");
    if (Objects.isNull(noFocusBorder) && Objects.nonNull(focusBorder)) {
      Insets i = focusBorder.getBorderInsets(this);
      noFocusBorder = BorderFactory.createEmptyBorder(
          i.top, i.left, i.bottom, i.right);
    }
  }
}

private DefaultListModel makeList() {
  DefaultListModel model = new DefaultListModel();
  model.addElement("一行");
  model.addElement("一行目\n二行目");
  model.addElement("一行目\n二行目\n三行目");
  model.addElement("四行\n以上ある\nテキスト\nの場合");
  return model;
}
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#deb3ece5]
左が複数行に対応したJList、右が通常のJListになります。左のJListでは、ListCellRendererにJTextAreaを使用しているため、テキストに\nを含めることで複数行を作成することができます。
* 解説 [#explanation]
- 右: デフォルトの`JList`
- 左: 複数行に対応した`JList`
-- `JList#getFixedCellHeight()`が`-1`で`ListCellRenderer`に`JTextArea`を使用しているため、テキストに`\n`を含めることで複数行が表示可能
- セルの選択状態
-- `UIManager.getBorder("List.focusCellHighlightBorder")`を使用するように変更

セルの区切りを分かりやすくするために、偶数奇数で行の背景色を変更しています。
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JList.html#setFixedCellHeight-int- JList#setFixedCellHeight(int) (Java Platform SE 8)]

JTextAreaにセルフォーカスがある状態を表現するために、EmptyBorderを継承して作成したDotBorderを使用しています。

//**参考リンク
**コメント [#h396eb78]
* コメント [#comment]
#comment
#comment