TITLE:JListで異なる高さのセルを使用
Posted by at 2006-05-15

JListで異なる高さのセルを使用

JListのレンダラーにJTextAreaを使って、異なる高さのセルを作成します。
  • 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

概要

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

サンプルコード

#spanend
#spanadd
class TextAreaRenderer<E extends String> extends JTextArea
#spanend
                                         implements ListCellRenderer<E> {
  private static final Color EVEN_COLOR = new Color(230, 255, 230);
  private Border noFocusBorder;
  private Border focusBorder;

#spandel
**サンプルコード [#r38aaded]
#spanend
#spandel
#code(link){{
#spanend
#spandel
class TextAreaRenderer extends JTextArea implements ListCellRenderer {
#spanend
  private final Border border = new DotBorder(2,2,2,2);
  private final Color evenColor = new Color(230,255,230);
  @Override public Component getListCellRendererComponent(
      JList list, Object object, int index,
      JList<? extends E> list, E value, 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());
    // setLineWrap(true);
    setText(Objects.toString(value, ""));
    if (isSelected) {
      // Nimbus
      setBackground(new Color(list.getSelectionBackground().getRGB()));
      setForeground(list.getSelectionForeground());
    }else{
      setBackground(index%2==0 ? evenColor : list.getBackground());
    } else {
      setBackground(index % 2 == 0 ? EVEN_COLOR : list.getBackground());
      setForeground(list.getForeground());
    }
    if (cellHasFocus) {
      setBorder(focusBorder);
    } else {
      setBorder(noFocusBorder);
    }
    return this;
  }
#spanadd

#spanend
  @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;
}
View in GitHub: Java, Kotlin

解説

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

解説

  • 右: デフォルトのJList
  • 左: 複数行に対応したJList
    • JList#getFixedCellHeight()-1ListCellRendererJTextAreaを使用しているため、テキストに\nを含めることで複数行が表示可能
  • セルの選択状態
    • UIManager.getBorder("List.focusCellHighlightBorder")を使用するように変更
セルの区切りを分かりやすくするために、偶数奇数で行の背景色を変更しています。

参考リンク

JTextAreaにセルフォーカスがある状態を表現するために、EmptyBorder LineBorder を継承して作成したDotBorderを使用しています。
#spanend
#spandel
class DotBorder extends LineBorder {
#spanend
  public boolean isBorderOpaque() {return true;}
  public DotBorder(Color color, int thickness) {
    super(color, thickness);
  }
  @Override
  public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
    Graphics2D g2 = (Graphics2D)g;
    g2.translate(x,y);
    g2.setPaint(getLineColor());
    BasicGraphicsUtils.drawDashedRect(g2, 0, 0, w, h);
    g2.translate(-x,-y);
  }
#spandel
}
#spanend
#spandel

参考リンク

コメント

コメント