JComboBox作为Jtable CellEditor与Overriden stopCellEditing修改错误的表格单元格 [英] JComboBox as Jtable CellEditor with Overriden stopCellEditing modifies wrong table cell

查看:607
本文介绍了JComboBox作为Jtable CellEditor与Overriden stopCellEditing修改错误的表格单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 will be used to update the data behind the JTable and afterwards update a database.

下面是一个简单的例子来展示我遇到的问题。重现步骤:

The following is a simple example to show the problem I am encountering. Steps to reproduce:


  1. 点击某个单元格

  2. 从ComboBox下拉列表中选择一个值

  3. 点击其他单元格

  4. 点击第一个选择的单元格

  1. Click on an cell
  2. Select a value from the ComboBox drop-down list
  3. Click on a different cell
  4. Click back on the first selected cell

第二个单元格将从第一个单元格获取值。

The second cell will get the value from the first one.

为什么会发生这种情况?为什么在stopCellEditing存在之前ComboBox模型改变了?

Why is this happening? Why does the ComboBox model change before stopCellEditing exists?

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);

    }
}


推荐答案

这里是一种保留编辑器中所有代码的方法:

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);

    }
}

这篇关于JComboBox作为Jtable CellEditor与Overriden stopCellEditing修改错误的表格单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆