• 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

解説

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

参考リンク

コメント