【问题标题】:Setting JComboBox as table column doesn't work将 JComboBox 设置为表格列不起作用
【发布时间】:2018-03-04 01:19:57
【问题描述】:

现在用 MCVE 编辑:

我想将一个 JTable 单元格视为一个 JComboBox。我在 Oracle 教程中尝试过,但它不起作用。本教程没有说明如何更改表格模型以使其正常工作。代码如下:

表模型:

import javax.swing.*;
import javax.swing.table.AbstractTableModel;

public class TableModel extends AbstractTableModel {

@Override
public int getColumnCount() {
    // TODO Auto-generated method stub
    return 2;
}

@Override
public int getRowCount() {
    // TODO Auto-generated method stub
    return 2;
}

@Override
public Object getValueAt(int row, int col) {
    if (row == 0) {
        return 2;
    } else if (col == 1 ) {
        return 1;
    } else {
        return null;
    }
}

}

以及显示组件的视图:

import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.table.TableColumn;

public class View extends JFrame {
public View() {
    super();
    TableModel tableModel = new TableModel();
    JTable testTable = new JTable(tableModel);

    JScrollPane scrollpane = new JScrollPane(testTable);
    // scrollpane.setOpaque(false);
    // scrollpane.getViewport().setOpaque(false);
    JPanel testTablePanel = new JPanel();
    testTablePanel.setBorder(
            BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Testkonfiguration"));
    testTablePanel.setLayout(new BorderLayout());
    testTablePanel.add(scrollpane);

    TableColumn sportColumn = testTable.getColumnModel().getColumn(1);

    JComboBox comboBox = new JComboBox();
    comboBox.addItem("Snowboarding");
    comboBox.addItem("Rowing");
    comboBox.addItem("Chasing toddlers");
    comboBox.addItem("Speed reading");
    comboBox.addItem("Teaching high school");
    comboBox.addItem("None");
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

    add(scrollpane);

    pack();
    setVisible(true);
}
public static void main(String[] args) {
    new View();
}

}

我必须在 tablemodel 中进行哪些更改才能使其正常工作?

【问题讨论】:

  • 如果你能创建和发布一个有效的minimal reproducible example 最有帮助的——一个小型可编译和可运行的程序,小到可以发布在这里,这完全说明了我们的问题。请考虑这样做。
  • @HovercraftFullOfEels 我现在写了一个,谢谢
  • @Phreneticus 你只需要正确地实现你的模型。首先,对于第 1 列,它应该返回您已添加到组合框中的值之一。第二:您需要实现方法setValueAt(Object aValue, int rowIndex, int columnIndex) 来存储您在组合框中选择的值。您还需要实现isCellEditable(int rowIndex, int columnIndex),它为索引为 1 的列返回 true。

标签: java swing jtable jcombobox tablecelleditor


【解决方案1】:

在您的示例中,您没有使 1 列可编辑。您首先需要这样做,例如在您的模型中:

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
    return columnIndex == 1;
}

另外你的模型没有很好的处理数据,没有办法获取到事实上的数据并且实际上是固定的,这样编辑器就没有可能的效果。您需要覆盖 setValueAt 并让它更新模型的核心。

例如使用您的简单示例:

import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;

public class View extends JFrame {
    public View() {
        super();
        TableModel tableModel = new TableModel();
        JTable testTable = new JTable(tableModel);

        JScrollPane scrollpane = new JScrollPane(testTable);
        // scrollpane.setOpaque(false);
        // scrollpane.getViewport().setOpaque(false);
        JPanel testTablePanel = new JPanel();
        testTablePanel.setBorder(BorderFactory
                .createTitledBorder(BorderFactory.createEtchedBorder(), "Testkonfiguration"));
        testTablePanel.setLayout(new BorderLayout());
        testTablePanel.add(scrollpane);

        TableColumn sportColumn = testTable.getColumnModel().getColumn(1);

        JComboBox<String> comboBox = new JComboBox<>();
        comboBox.addItem("Snowboarding");
        comboBox.addItem("Rowing");
        comboBox.addItem("Chasing toddlers");
        comboBox.addItem("Speed reading");
        comboBox.addItem("Teaching high school");
        comboBox.addItem("None");
        sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        add(scrollpane);

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new View();
    }

}

class TableModel extends AbstractTableModel {
    Object[][] innerModel = new Object[][]{{2, 1}, {2, null}};

    public TableModel() {

    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public int getRowCount() {
        return innerModel.length;
    }

    @Override
    public Object getValueAt(int row, int col) {
        return innerModel[row][col];
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        innerModel[rowIndex][columnIndex] = aValue;
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 1;
    }

}

【讨论】:

  • 就是这样,我只是忘了调用 setValueAt() facepalm 谢谢!
  • 我的代码现在可以工作了,但是,只要我单击该列中的表格单元格,我就只能看到表格列由组合框组成。一旦我选择了组合框的另一个选项,我就不再看到属于组合框的箭头。有没有办法总是在每个单元格上显示这个箭头?
猜你喜欢
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多