概要

JListのレンダラーにJTextAreaを使って、異なる高さのセルを作成します。

サンプルコード

class TextAreaRenderer extends JTextArea implements ListCellRenderer<String> {
  private Border focusBorder;
  private static final Border NOMAL_BORDER =
    BorderFactory.createEmptyBorder(2, 2, 2, 2);
  private static final Color EVEN_COLOR = new Color(230, 255, 230);
  @Override public Component getListCellRendererComponent(
      JList list, String str, int index,
      boolean isSelected, boolean cellHasFocus) {
    //setLineWrap(true);
    setText(Objects.toString(str, ""));
    if (isSelected) {
      setBackground(list.getSelectionBackground());
      setForeground(list.getSelectionForeground());
    } else {
      setBackground(index % 2 == 0 ? EVEN_COLOR : list.getBackground());
      setForeground(list.getForeground());
    }
    if (cellHasFocus) {
      if (focusBorder == null) {
        focusBorder = new DotBorder(
            new Color(~list.getSelectionBackground().getRGB()), 2);
      }
      setBorder(focusBorder);
    } else {
      setBorder(NOMAL_BORDER);
    }
    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;
}
view all

解説

左が複数行に対応したJList、右が通常のJListになります。左のJListでは、JList#getFixedCellHeight()-1で、ListCellRendererJTextAreaを使用しているため、テキストに\nを含めることで複数行を作成することができます。

セルの区切りを分かりやすくするために、偶数奇数で行の背景色を変更しています。

  • セルの選択状態
    • JTextAreaにセルフォーカスがある状態を表現するために、LineBorderを継承して作成したDotBorderを使用
    • UIManager.getBorder("List.focusCellHighlightBorder")を使用するように変更

参考リンク

コメント