JComboBox作为Jtable单元格编辑器,具有覆盖停止CellEditing修改错误的表格单元格

时间:2013-11-14 12:40:03

标签: java swing combobox jtable tablecelleditor

我有一个使用JComboBox作为单元格编辑器的自定义TableModel的自定义JTable。 ComboBox还有一个自定义的ComboBoxModel ComboBox模型包含多个字段,用于更新JTable后面的数据,然后更新数据库。

以下是一个显示我遇到的问题的简单示例。重现的步骤:

  1. 单击一个单元格
  2. 从ComboBox下拉列表中选择一个值
  3. 点击其他单元格
  4. 点击第一个选定的单元格
  5. 第二个单元格将从第一个单元格中获取值。

    为什么会这样?为什么在stopCellEditing存在之前ComboBox模型会发生变化?

    import javax.swing.DefaultCellEditor;
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTabbedPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    
    public class TestComboCellEditor {
    
        public static void main(String[] args) {
    
            TestComboCellEditor test = new TestComboCellEditor();
            test.go();
        }
    
        public void go() {
    
            //create the frame
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // create and add a tabbed pane to the frame
            JTabbedPane tabbedPane = new JTabbedPane();
            frame.getContentPane().add(tabbedPane);
            //create a table and add it to a scroll pane in a new tab
            final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
            JScrollPane scrollPane = new JScrollPane(table);
            tabbedPane.addTab("test", scrollPane);
    
            // create a simple JComboBox and set is as table cell editor on column A
            Object[] comboElements = {"aaaaa1", "aaaaaa2", "b"};
            final JComboBox comboBox = new JComboBox(comboElements);
            comboBox.setEditable(true);
            table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox) {
                @Override
                public boolean stopCellEditing() {
                    if (comboBox.isEditable()) {
                        DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
                        String selectedItem = (String) comboModel.getSelectedItem();
                        int selectedIndex = comboModel.getIndexOf(selectedItem);
                        if (!(selectedIndex == -1)) {
                            // the selected item exists as an Option inside the ComboBox
                            DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
                            int selectedRow = table.getSelectedRow();
                            int selectedColumn = table.getSelectedColumn();
                            tableModel.setValueAt(selectedItem, selectedRow, selectedColumn);
                        } else if (selectedItem != null) {
                            // missing code - adding new info to a custom JComboBox model and to alter info inside a custom table model
                        }
                    }
                    return super.stopCellEditing();
                }
            });
    
            // pack and show frame
            frame.pack();
            frame.setVisible(true);
    
        }
    }
    

2 个答案:

答案 0 :(得分:4)

这是一种将所有代码保存在编辑器中的方法:

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

public class TestComboCellEditor {

    public static void main(String[] args) {

        TestComboCellEditor test = new TestComboCellEditor();
        test.go();
    }

    public void go() {

        //create the frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create and add a tabbed pane to the frame
        JTabbedPane tabbedPane = new JTabbedPane();
        frame.getContentPane().add(tabbedPane);
        //create a table and add it to a scroll pane in a new tab
        final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
        JScrollPane scrollPane = new JScrollPane(table);
        tabbedPane.addTab("test", scrollPane);

        // create a simple JComboBox and set is as table cell editor on column A
        Object[] comboElements = {"aaaaa1", "aaaaaa2", "b"};
        final JComboBox comboBox = new JComboBox(comboElements);
        comboBox.setEditable(true);
        table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox)
        {
            private Object originalValue;

            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
            {
                originalValue = value;
                return super.getTableCellEditorComponent(table, value, isSelected, row, column);
            }

            @Override
            public boolean stopCellEditing()
            {
                JComboBox comboBox = (JComboBox)getComponent();
                DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
                Object editingValue = getCellEditorValue();

                //  Needed because your TableModel is empty

                if (editingValue == null)
                    return super.stopCellEditing();

                int selectedIndex = comboModel.getIndexOf(editingValue);

                //  Selecting item from model

                if (! (selectedIndex == -1))
                    return super.stopCellEditing();

                //  Confirm addition of new value

                int result = JOptionPane.showConfirmDialog(
                    comboBox.getParent(),
                    "Add (" + editingValue + ") to table?",
                    "Update Model",
                    JOptionPane.YES_NO_OPTION);

                if (result == JOptionPane.YES_OPTION)
                {
                    comboBox.addItem(editingValue);
                    return super.stopCellEditing();
                }
                else
                {
                    comboBox.removeItem(editingValue);
                     comboBox.setSelectedItem(originalValue);
                    return false;
                }
            }
        });

        // pack and show frame
        frame.pack();
        frame.setVisible(true);

    }
}

答案 1 :(得分:0)

好的,我做了一些改变,我觉得我有所作为。如果这不是最佳实践,并且您有更好的实施,请发表答案。

编辑:请勿按照以下示例进行操作!根据kleopatra的评论,这是一个错误的实现。我将它留在这里,所以你知道如何

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TestComboCellEditor {

    public static void main(String[] args) {

        TestComboCellEditor test = new TestComboCellEditor();
        test.go();
    }

    public void go() {

        //create the frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create and add a tabbed pane to the frame
        JTabbedPane tabbedPane = new JTabbedPane();
        frame.getContentPane().add(tabbedPane);
        //create a table and add it to a scroll pane in a new tab
        final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
        JScrollPane scrollPane = new JScrollPane(table);
        tabbedPane.addTab("test", scrollPane);

        // create a simple JComboBox and set is as table cell editor on column A
        Object[] comboElements = {"aaaaa1", "aaaaaa2", "b"};
        final JComboBox comboBox = new JComboBox(comboElements);
        comboBox.setEditable(true);
        table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox) {
            @Override
            public boolean stopCellEditing() {
                if (comboBox.isEditable()) {
                    DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
                    String selectedItem = (String) comboModel.getSelectedItem();
                    int selectedIndex = comboModel.getIndexOf(selectedItem);
                    if (!(selectedIndex == -1)) {
                        comboBox.actionPerformed(new ActionEvent(this, selectedIndex, "blabla"));
                    } else if (selectedItem != null) {
                        // missing code - adding new info to a custom JComboBox model and to alter info inside a custom table model
                    }
                }
                return super.stopCellEditing();
            }
        });

        comboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // the selected item exists as an Option inside the ComboBox
                if (e.getActionCommand().equals("blabla")) {
                    DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
                    String selectedItem = (String) comboModel.getSelectedItem();
                    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
                    int selectedRow = table.getSelectedRow();
                    int selectedColumn = table.getSelectedColumn();
                    tableModel.setValueAt(selectedItem, selectedRow, selectedColumn);
                }
            }
        });

        // pack and show frame
        frame.pack();
        frame.setVisible(true);

    }
}