JComboBox as Jtable CellEditor with Overriden stopCellEditing modifies wrong table cell

前端 未结 2 1057
暗喜
暗喜 2021-01-24 17:25

I have a custom JTable with a custom TableModel using a JComboBox as a cell editor. The ComboBox also has a custom ComboBoxModel The ComboBox model holds multiple fields that wi

相关标签:
2条回答
  • 2021-01-24 18:07

    Ok, I've done some changes and I think I got something working. If it is not the best practice and you got a better implementation, please post an answer.

    Edit: Do not follow the example below! Following kleopatra's comments it is a wrong implementation. I'm leaving it here so you know how not to do it.

    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);
    
        }
    }
    
    0 讨论(0)
  • 2021-01-24 18:21

    Here is an approach that keeps all the code in the editor:

    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);
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题