Swing/ButtonsInListCell のバックアップ(No.11)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - Visual を表示
 - ソース を表示
 - Swing/ButtonsInListCell へ行く。
  
- 1 (2011-10-05 (水) 00:35:28)
 - 2 (2012-12-16 (日) 01:45:20)
 - 3 (2013-08-09 (金) 20:59:23)
 - 4 (2013-08-17 (土) 01:12:43)
 - 5 (2013-11-20 (水) 16:13:40)
 - 6 (2015-01-14 (水) 15:45:25)
 - 7 (2016-04-19 (火) 16:04:48)
 - 8 (2016-11-18 (金) 14:34:33)
 - 9 (2017-11-22 (水) 15:25:47)
 - 10 (2019-07-19 (金) 17:06:18)
 - 11 (2021-03-21 (日) 04:16:32)
 - 12 (2024-02-02 (金) 11:32:13)
 - 13 (2025-01-03 (金) 08:57:02)
 - 14 (2025-01-03 (金) 09:01:23)
 - 15 (2025-01-03 (金) 09:02:38)
 - 16 (2025-01-03 (金) 09:03:21)
 - 17 (2025-01-03 (金) 09:04:02)
 - 18 (2025-06-19 (木) 12:41:37)
 - 19 (2025-06-19 (木) 12:43:47)
 
 
- category: swing
folder: ButtonsInListCell
title: JListのセル内にJButtonを配置する
tags: [JList, JButton, ListCellRenderer]
author: aterai
pubdate: 2011-10-03T14:43:12+09:00
description: JListのセル内に複数のJButtonを配置します。
image: 

 
概要
JListのセル内に複数のJButtonを配置します。
Screenshot

Advertisement
サンプルコード
class ButtonsRenderer<E> extends JPanel implements ListCellRenderer<E> {
  protected static final Color EVEN_COLOR = new Color(0xE6_FF_E6);
  protected final JTextArea textArea = new JTextArea();
  protected final JButton deleteButton = new JButton("delete");
  protected final JButton copyButton = new JButton("copy");
  protected final List<JButton> buttons = Arrays.asList(deleteButton, copyButton);
  protected final DefaultListModel<E> model;
  protected int targetIndex;
  protected int pressedIndex = -1;
  protected int rolloverIndex = -1;
  protected JButton button;
  protected ButtonsRenderer(DefaultListModel<E> model) {
    super(new BorderLayout()); // *1
    this.model = model;
    setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0));
    setOpaque(true);
    textArea.setLineWrap(true);
    textArea.setOpaque(false);
    add(textArea);
    deleteButton.addActionListener(e -> {
      boolean isMoreThanOneItem = model.getSize() > 1;
      if (isMoreThanOneItem) {
        model.remove(targetIndex);
      }
    });
    copyButton.addActionListener(e -> model.add(targetIndex, model.get(targetIndex)));
    Box box = Box.createHorizontalBox();
    buttons.forEach(b -> {
      b.setFocusable(false);
      b.setRolloverEnabled(false);
      box.add(b);
      box.add(Box.createHorizontalStrut(5));
    });
    add(box, BorderLayout.EAST);
  }
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.width = 0; // VerticalScrollBar as needed
    return d;
  }
  @Override public Component getListCellRendererComponent(
      JList<? extends E> list, E value, int index,
      boolean isSelected, boolean cellHasFocus) {
    textArea.setText(Objects.toString(value, ""));
    this.targetIndex = index;
    if (isSelected) {
      setBackground(list.getSelectionBackground());
      textArea.setForeground(list.getSelectionForeground());
    } else {
      setBackground(index % 2 == 0 ? EVEN_COLOR : list.getBackground());
      textArea.setForeground(list.getForeground());
    }
    buttons.forEach(ButtonsRenderer::resetButtonStatus);
    if (Objects.nonNull(button)) {
      if (index == pressedIndex) {
        button.getModel().setSelected(true);
        button.getModel().setArmed(true);
        button.getModel().setPressed(true);
      } else if (index == rolloverIndex) {
        button.getModel().setRollover(true);
      }
    }
    return this;
  }
  private static void resetButtonStatus(AbstractButton button) {
    ButtonModel model = button.getModel();
    model.setRollover(false);
    model.setArmed(false);
    model.setPressed(false);
    model.setSelected(false);
  }
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JListのセルに2つのJButtonを配置するListCellRendererを設定しています。
JButtonのクリックイベントは、JList本体に追加したマウスリスナーでSwingUtilities.getDeepestComponentAt(...)を使用してListCellRendererから対象のJButtonを取得し、JButton#doClick()を呼び出しています。