带JComboBox的Java JTable

带JComboBox的Java JTable,java,swing,jtable,jcombobox,tablecelleditor,Java,Swing,Jtable,Jcombobox,Tablecelleditor,我试图在JTable的某个列中放置一个JComboBox。 我有这个代码,它正在工作: model = new DefaultTableModel(); JComboBox<String> optionComboCell = new JComboBox<String>(); optionComboCell.addItem("Option 1"); optionComboCell.addItem("Option 2"); option

我试图在JTable的某个列中放置一个JComboBox。 我有这个代码,它正在工作:

    model = new DefaultTableModel();
    JComboBox<String> optionComboCell = new JComboBox<String>();
    optionComboCell.addItem("Option 1");
    optionComboCell.addItem("Option 2");
    optionComboCell.setSelectedIndex(1);


    table = new JTable(model);
    // Adding here all the columns, removed for clarity
    model.addColumn("Options");
    TableColumn optionsColumn = table.getColumn("Options");
    optionsColumn.setCellEditor(new DefaultCellEditor(optionComboCell));
model=newdefaulttablemodel();
JComboBox optionComboCell=新的JComboBox();
optionComboCell.addItem(“选项1”);
optionComboCell.addItem(“选项2”);
optionComboCell.setSelectedIndex(1);
表=新JTable(型号);
//在此处添加所有列,为清晰起见将其删除
模型。添加列(“选项”);
TableColumn选项Column=table.getColumn(“选项”);
optionsColumn.setCellEditor(新的DefaultCellEditor(optionComboCell));
我的问题是,在选择该列中的单元格之前,它不会显示为JComboBox。 加载JFrame时,整个表看起来都一样,好像所有单元格中只有文本。 单击时,它会显示组合框的箭头和选项,但再次取消选择时,它看起来像一个常规单元格


有没有办法解决这个问题?

尝试设置单元格渲染器。

是的,使用JComboBox渲染单元格:

import java.awt.Component;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class Test4 {

    private static class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer {

        public ComboBoxCellRenderer(int column) {
            for (int i = 0; i < 10; i++) {
                addItem("Cell (" + i + "," + column + ")");
            }
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setSelectedItem(value);
            return this;
        }
    }

    protected void initUI() {
        JFrame frame = new JFrame("test");
        frame.add(getTable());
        frame.pack();
        frame.setVisible(true);
    }

    private Component getTable() {
        Vector<Vector<String>> data = new Vector<Vector<String>>();
        for (int i = 0; i < 10; i++) {
            Vector<String> row = new Vector<String>();
            for (int j = 0; j < 3; j++) {
                row.add("Cell (" + i + "," + j + ")");
            }
            data.add(row);
        }
        Vector<String> columns = new Vector<String>();
        columns.add("Column 1");
        columns.add("Column 2");
        columns.add("Column 3");
        DefaultTableModel model = new DefaultTableModel(data, columns);
        JTable table = new JTable(model);
        table.setRowHeight(20);
        int i = 0;
        Enumeration<TableColumn> c = table.getColumnModel().getColumns();
        while (c.hasMoreElements()) {
            TableColumn column = c.nextElement();
            column.setCellRenderer(new ComboBoxCellRenderer(i));
            i++;
        }
        JScrollPane scroll = new JScrollPane(table);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        return scroll;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test4().initUI();
            }
        });
    }
}
导入java.awt.Component;
导入java.util.Enumeration;
导入java.util.Vector;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableCellRenderer;
导入javax.swing.table.TableColumn;
公共类Test4{
私有静态类ComboxCellRenderer扩展了JComboBox实现了TableCellRenderer{
公共ComboxCellRenderer(int列){
对于(int i=0;i<10;i++){
附加项(“单元格(“+i+”,“+column+”));
}
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、布尔isSelected、布尔hasFocus、int行、int列){
setSelectedItem(值);
归还这个;
}
}
受保护的void initUI(){
JFrame=新JFrame(“测试”);
frame.add(getTable());
frame.pack();
frame.setVisible(true);
}
私有组件getTable(){
向量数据=新向量();
对于(int i=0;i<10;i++){
向量行=新向量();
对于(int j=0;j<3;j++){
添加(“单元格(“+i+”,“+j+”));
}
添加数据(行);
}
向量列=新向量();
列。添加(“第1列”);
列。添加(“第2列”);
列。添加(“第3列”);
DefaultTableModel=新的DefaultTableModel(数据、列);
JTable table=新的JTable(模型);
表2.设置行高(20);
int i=0;
枚举c=table.getColumnModel().getColumns();
而(c.hasMoreElements()){
TableColumn column=c.nextElement();
column.setCellRenderer(新ComboBoxCellRenderer(i));
i++;
}
JScrollPane scroll=新的JScrollPane(表);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HorizontalScrollBar,根据需要);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL\u SCROLLBAR\u根据需要);
返回滚动条;
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新的Test4().initUI();
}
});
}
}

您需要定义自己的渲染器,以便在表上显示组件,因为单元格编辑器仅用于编辑tablecell中的值(这就是为什么单击单元格时它只会做出反应)


也许可以看一看,了解更多关于JTables渲染器和编辑器的概念。

请说两三句话,你的答案太短了,因为(上周)有一个或多个用户,他们的短消息或其他非标准帖子可能会被删除。我使用了您的ComboBoxCellRenderer类,它现在显示为一个组合框,但是,一旦选择了一个选项,它仍然显示为一个空的组合框。仅当下拉列表打开时,才会显示所选项目visible@Lablabla您必须确保您尝试选择的项目(在调用
GetTableCellRenderComponent
期间)确实存在于组合框模型中,否则它将不起作用。谢谢。一个小的跟进,我如何设置默认值?因为首先,没有选项显示为选中。只有当我选择one@Lablabla在这种情况下,默认值实际上没有意义。每次调用getTableCellRenderer时,都需要选择一个项。您是否正确理解Swing中的表呈现工作原理?对于所有不同的单元格,重复使用的是完全相同的组合框,因此设置默认值没有意义,因为渲染的前一个单元格可能已更改了所选项目。@Lablabla我不确定我是否完全理解您当时的意思(可能更容易发布另一个问题来解释您试图实现的目标)。表格的值始终取自表格模型。您的单元渲染器应该提供某种方式来正确反映这些值(
null
只是另一个可接受的值)。因此,在方法getTableCellRenderComponent中,确保您的组合框正确地反映了
参数,这就是它应该做的一切。如果需要修改表显示的数据,则应通过TableModel进行修改。