当前位置: 首页 > 知识库问答 >
问题:

在JTable中,当编辑单元格唯一的JComboBoxes时更新显示的项

朱运诚
2023-03-14

以下是SSCE以我所能做到的最简洁的方式来说明设计:

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

@SuppressWarnings("serial")
public class ComboBoxTableGUI extends JFrame {

    public List<SampleCollection> masterList;

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

    public ComboBoxTableGUI() {
        // create a collection of 10 collections, each with 1-10 Strings
        masterList = new ArrayList<SampleCollection>();
        Random rnd = new Random();
        for (int i = 0; i < 10; i++) {
            SampleCollection sc = new SampleCollection("Option " + i + ":");
            int choices = rnd.nextInt(9) + 1;
            for (int j = 0; j < choices; j++) {
                sc.choices.add("Choice " + j);
            }
            sc.selectedChoice = sc.choices.get(0);
            masterList.add(sc);
        }

        this.setSize(500, 500);
        this.setLocationRelativeTo(null);

        TableModel optionTableModel = new OptionTableModel();
        JTableWithCustomEditors optionsTable = new JTableWithCustomEditors(optionTableModel);

        this.add(optionsTable);

        TableColumn optionCol = optionsTable.getColumnModel().getColumn(1);
        optionCol.setCellRenderer(new CustomComboBoxRenderer());

        List<TableCellEditor> editors = new ArrayList<TableCellEditor>();
        for (SampleCollection collection : masterList) {
            JComboBox<String> cb = new JComboBox<String>();
            for (String choice : collection.choices) {
                cb.addItem(choice);
            }
            DefaultCellEditor editor = new DefaultCellEditor(cb);
            editors.add(editor);
        }
        optionsTable.editors = editors;

        this.setVisible(true);
    }

    public class SampleCollection {
        public String name, selectedChoice;
        public List<String> choices;

        public SampleCollection(String name) {
            this.name = name;
            this.choices = new ArrayList<String>();
        }
    }

    public class JTableWithCustomEditors extends JTable {
        public List<TableCellEditor> editors;

        public JTableWithCustomEditors(TableModel model) {
            super(model); // lol
        }

        @Override
        public TableCellEditor getCellEditor(int row, int column) {
            if (column == 1)
                return editors.get(row);
            else
                return super.getCellEditor(row, column);
        }
    }

    class CustomComboBoxRenderer extends JComboBox<String> implements
            TableCellRenderer {
        public CustomComboBoxRenderer() {
            setBorder(new EmptyBorder(0, 0, 0, 0));
        }

        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {

            removeAllItems();
            addItem(((SampleCollection) value).selectedChoice);

            this.setSelectedIndex(0);
            return this;
        }
    }

    public class OptionTableModel implements TableModel {
        private List<TableModelListener> listeners;

        public OptionTableModel() {
            listeners = new ArrayList<TableModelListener>();
        }

        @Override
        public void addTableModelListener(TableModelListener l) {
            listeners.add(l);
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex == 1)
                return SampleCollection.class;
            else
                return String.class;
        }

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

        @Override
        public String getColumnName(int columnIndex) {
            if (columnIndex == 0)
                return "Name";
            else
                return "Selection";
        }

        @Override
        public int getRowCount() {
            if (masterList == null)
                return 0;
            else
                return masterList.size();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            if (columnIndex == 0)
                return masterList.get(rowIndex).name;
            else
                return masterList.get(rowIndex);// also tried .choices
        }

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

        @Override
        public void removeTableModelListener(TableModelListener l) {
            listeners.remove(l);
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            // the values are grabbed when the user clicks an OK button, right
            // now I just need to get it rendering
        }
    }
}

共有1个答案

程枫
2023-03-14

您的TableModel实现不正确。

首先,数据应该存储在模型中,而不是作为类中的实例变量。

setValueat(...)方法应更新列表中的数据,然后调用FireTableCellUpdated(...),这将告诉表数据已更改,以便可以重新绘制单元格。

 类似资料:
  • 问题内容: 我有此代码从如何突出显示jtable中的多个单元格: 但是,当我用它突出显示一个单元格时,它会执行错误的操作,就像丢失整个数据一样。Iam是Java Swing的新手。请帮助使单元格在按钮按下动作事件中突出显示。 更新:添加我的示例代码: 我想要的是单击按钮,我只想突出显示单元格编号1(Row1-Column1)。 问题答案: 我使用此类来设置JTables的样式 创建此类的实例,并将

  • 我有一个JTable,它应该是2列(String,JComboBox)。当我初始化表时,一切看起来都很好。只要一个I在表中选择了一个值,JComboBox单元格就会获取所选项的数据类型。 我想保持JCOmboBox在那里,让它触发数据更改事件,表忽略该列中的数据更改,并保持ComboBox填充。 我的表将此作为覆盖

  • 我想要一个有4列的jtable。一列必须是组合框。其他列是字符串。 只要找到问题:在注释语句jcb.seteditable(true)时;,如果我在comboxcell上单击一次,它就会打开这个单元格。但我不知道为什么效果更好。此外,我希望combox可编辑。 我怎么能对其他细胞有同样的行为。 再次您好,我已经更新了代码,以便使-如果我通过重写方法在单元格上单击一次,单元格可以编辑-如果我通过重写

  • 问题内容: 我想在JTable中将不可编辑的单元格显示为灰色。我正在使用这样的TableCellRenderer: 这有效,但有一个令人讨厌的伪像:最初,“复选框”是“左排列的”,当我按鼠标左键时,它移到“居中”,而当我释放鼠标按钮时,它又移回“左排列”。 如何避免这种令人讨厌的伪像,并且可能对我的问题有更好的简单解决方案? 问题答案: 返回的实例中。 附录:从美学角度,你可能想调理渲染的和基于编

  • 问题内容: 我需要在jTable中显示数字,精确到小数点后两位。为此,我创建了一个自定义单元格编辑器,如下所示: 该单元格编辑器非常适合将点用作小数点的英语语言环境。但是在德语语言环境中,它不接受逗号作为小数点的值。请让我知道我的代码中有问题的地方。提前致谢。 编辑:这是我如何使其工作: 问题答案: 使用语言环境来发挥您的优势:

  • 我在更新JTable的单元格值时遇到了一个问题。我想做的是在从JTable中选择一个特定的单元格之后,我应该能够进行编辑,并且该操作必须反映后端的数据库。我在用HSQL。我的表有4列,有一个PK。请给我一个替代和/或提供一些代码,替换的*。我是新来的,只是个初学者。