• category: swing folder: PanelCellEditorRenderer title: JTableのCellEditorにJPanelを使用して複数コンポーネントを配置 tags: [JTable, TableCellEditor, TableCellRenderer, JPanel, JButton, JSpinner] author: aterai pubdate: 2014-11-17T00:00:08+09:00 description: JTableのCellEditor、CellRendererにJPanelを使用することで、内部に複数コンポーネントを配置したり、セル内の余白を追加します。 image: https://lh4.googleusercontent.com/-_MCc8pkoFGY/VGitX9B0RsI/AAAAAAAANpg/zAG38GESdsU/s800/PanelCellEditorRenderer.png

概要

JTableCellEditorCellRendererJPanelを使用することで、内部に複数コンポーネントを配置したり、セル内の余白を追加します。

サンプルコード

class ButtonsPanel extends JPanel {
  public final List<JButton> buttons = Arrays.asList(
      new JButton("+"), new JButton("-"));
  public final JLabel label = new JLabel() {
    @Override public Dimension getPreferredSize() {
      Dimension d = super.getPreferredSize();
      d.width = 50;
      return d;
    }
  };
  public int i = -1;
  public ButtonsPanel() {
    super();
    label.setHorizontalAlignment(SwingConstants.RIGHT);
    setOpaque(true);
    add(label);
    for (JButton b : buttons) {
      b.setFocusable(false);
      b.setRolloverEnabled(false);
      add(b);
    }
  }
}

class ButtonsRenderer extends ButtonsPanel implements TableCellRenderer {
  public ButtonsRenderer() {
    super();
    setName("Table.cellRenderer");
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    this.setBackground(isSelected ? table.getSelectionBackground()
                                  : table.getBackground());
    label.setForeground(isSelected ? table.getSelectionForeground()
                                   : table.getForeground());
    label.setText(Objects.toString(value, ""));
    return this;
  }
}

class ButtonsEditor extends ButtonsPanel implements TableCellEditor {
  public ButtonsEditor() {
    super();
    buttons.get(0).addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        i++;
        label.setText("" + i);
        fireEditingStopped();
      }
    });

    buttons.get(1).addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        i--;
        label.setText("" + i);
        fireEditingStopped();
      }
    });

    addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        fireEditingStopped();
      }
    });
  }
  @Override public Component getTableCellEditorComponent(
    JTable table, Object value, boolean isSelected, int row, int column) {
    this.setBackground(table.getSelectionBackground());
    label.setForeground(table.getSelectionForeground());
    i = (Integer) value;
    label.setText("" + i);
    return this;
  }
  @Override public Object getCellEditorValue() {
    return i;
  }

  //Copied from AbstractCellEditor
  //...
View in GitHub: Java, Kotlin

解説

  • 0列目: JPanel + JSpinner
  • 1列目: JPanel + JLabel + JButton
    • TableCellEditor, TableCellRendererJLabel2つのJButtonを配置したJPanelを使用
    • JPanelにはFlowLayoutを指定
      • カラム幅が狭くなって折り返しが発生してもセルの高さは変化しないので、コンポーネントが見切れてしまう
    • JTableのセルに複数のJButtonを配置する

参考リンク

コメント