java - 如何动态地将不同的JComboBox放入JTable的每一行中

标签 java swing jtable jcombobox

我想在我的应用程序中创建一个 JTable。 该表将包含两个列,第一个是软件模块的名称。 第二列需要包含一个 JComboBox,其中包含第一列中软件模块的修订号。

这是否可能,或者我需要找到另一种方法来做到这一点? (例如:在单元格上放置一个按钮,然后从弹出窗口中选择修订版本)

提前谢谢您!

最佳答案

这是使用 DefaultComboBoxModel<Integer> 的一种可能的实现方式作为表列的数据类型:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class EditableComboCellEditorTest {
  private JComponent makeUI() {
    String[] columnNames = {"version", "revision"};
    Object[][] data = {
      {"1.7.0", makeModel(76, 79, 80)},
      {"1.8.0", makeModel(91, 92, 101, 102)},
    };
    TableModel model = new DefaultTableModel(data, columnNames) {
      @Override public Class<?> getColumnClass(int column) {
        return column == 1 ? DefaultComboBoxModel.class : String.class;
      }
    };
    JTable table = new JTable(model);
    table.setRowHeight(32);
    table.setAutoCreateRowSorter(true);

    TableColumn col = table.getColumnModel().getColumn(1);
    col.setCellRenderer(new ComboCellRenderer());
    col.setCellEditor(new ComboCellEditor());

    return new JScrollPane(table);
  }
  private static DefaultComboBoxModel<Integer> makeModel(Integer... items) {
    return new DefaultComboBoxModel<Integer>(items) {
      @Override public String toString() {
        return Objects.toString(getSelectedItem(), "");
      }
    };
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new EditableComboCellEditorTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class ComboCellRenderer implements TableCellRenderer {
  private final JPanel p = new JPanel(new GridBagLayout());
  private final JComboBox<Integer> cb = new JComboBox<>();
  @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected, boolean hasFocus,
    int row, int column) {
    p.removeAll();
    p.setOpaque(false);
    p.add(cb);
    cb.setEditable(true);
    cb.removeAllItems();
    if (value instanceof DefaultComboBoxModel) {
      DefaultComboBoxModel m = (DefaultComboBoxModel) value;
      Object o = m.getSelectedItem();
      if (o instanceof Integer) {
        cb.addItem((Integer) o);
      }
    }
    return p;
  }
}
//https://java-swing-tips.blogspot.jp/2016/08/use-editable-jcombobox-as.html
class ComboCellEditor extends AbstractCellEditor implements TableCellEditor {
  private final JPanel p = new JPanel(new GridBagLayout());
  private final JComboBox<Integer> cb = new JComboBox<>();
  protected ComboCellEditor() {
    super();
    cb.setEditable(true);
    cb.addActionListener(e -> fireEditingStopped());
    p.add(cb);
    p.setOpaque(false);
  }
  @Override public Component getTableCellEditorComponent(
    JTable table, Object value, boolean isSelected, int row, int column) {
    if (value instanceof ComboBoxModel) {
      @SuppressWarnings("unchecked")
      ComboBoxModel<Integer> m = (ComboBoxModel<Integer>) value;
      cb.setModel(m);
    }
    return p;
  }
  @Override public Object getCellEditorValue() {
    @SuppressWarnings("unchecked")
    DefaultComboBoxModel<Integer> m = (DefaultComboBoxModel<Integer>) cb.getModel();
    if (cb.isEditable()) {
      Object o = cb.getEditor().getItem();
      if (o instanceof Integer && m.getIndexOf((Integer) o) < 0) {
        Integer value = (Integer) o;
        int n = m.getSize();
        Vector<Integer> list = new Vector<>(n + 1);
        for (int i = 0; i < n; i++) {
          list.add(m.getElementAt(i));
        }
        list.add(value);
        Collections.sort(list);
        m = new DefaultComboBoxModel<Integer>(list);
        cb.setModel(m);
        cb.setSelectedIndex(m.getIndexOf(value));
      }
    }
    return m;
  }
}

关于java - 如何动态地将不同的JComboBox放入JTable的每一行中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39717014/

相关文章:

Java在线程中的循环中向JButton添加点击监听器

java - 渲染器中未设置 RowSorter

java - 如何在 Javaeditor jTable 中为单元格设置文本?

java - FileProvider.getUriForFile 返回空对象引用

java - getPosition 已弃用 我应该改用什么?

java - 如何验证输入是否匹配特定的时间戳格式?

java - 是否有像 "changeSelection()"这样的函数来选择行但在表格顶部而不是底部?

java - 无法使用java API连接到orientdb数据库

java - 创建一个 Squircle

java - 如何在Java中创建Listview[Swing]?