JTable中的JComboBox显示无效数据

时间:2014-09-08 06:34:24

标签: java swing jdbc jtable jcombobox

我有一个JTable,我根据数据库select查询动态填充其列。此JTable的一列将接受JComboBox。现在,请看下面的代码。

private class ViewClientsDisplayData extends ComponentAdapter
     {
        @Override
        public void componentShown(ComponentEvent e) 
        {
            dbConnector = new DBHandler();
            dbConnector.makeConnection();

            ResultSet rs =  dbConnector.selectAllDetails("select client_id, Name from Client");

            DefaultTableModel model = (DefaultTableModel) ViewClientsTable.getModel();
            model.setRowCount(0);

            try {
                if(rs.isBeforeFirst()==false)
                {
                    JOptionPane.showMessageDialog(null,"The table is empty");
                }
                else
                {
                    try
                    {
                        while(rs.next())
                        {
                            int id = rs.getInt("client_id");
                            String name = rs.getString("Name");

                            ResultSet getPortfolios =  dbConnector.selectAllDetails("select portfolio_id from Portfolio where Client_Name = '"+name+"'");
                            JComboBox combo = new JComboBox();
                            combo.removeAllItems();

                            while(getPortfolios.next())
                            {
                                combo.addItem(getPortfolios.getString("portfolio_id"));
                            }

                            JButton update = new JButton("Update");
                            JButton delete = new JButton("Delete");

                            JPanel btnPanel = new JPanel();
                            btnPanel.setLayout(new FlowLayout());
                            btnPanel.add(update);
                            btnPanel.add(delete);


                            Object[]row = {id, name, 0, "", new ButtonColumn(ViewClientsTable,null,"delete",4)};

                            model.addRow(row);
                            ViewClientsTable.getColumn("Portfolio").setCellEditor(new DefaultCellEditor(combo));

                        }
                        dbConnector.closeConnection();
                    }
                    catch(SQLException sqlE)
                    {
                        sqlE.printStackTrace();
                        JOptionPane.showMessageDialog(null,sqlE.getLocalizedMessage());
                        dbConnector.closeConnection();
                    }
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
     }

dbConnector.selectAllDetails()方法

public ResultSet selectAllDetails(String query)
    {
        ResultSet r = null;
        try
        {
            Statement st = con.createStatement();

            r = st.executeQuery(query);
        }
        catch(SQLException sql)
        {
            sql.printStackTrace();
        }

        return r;
    }

这里的问题是我的JComboBox未按预期填充。它应该根据提供的搜索查询来填充数据,而是在所有行中显示相同的项目,项目 03 ,这是客户名称​​ AAA的项目组合ID

下面是我的client表(带虚拟输入)

enter image description here

下面是我的Portfolio表(带虚拟输入)

enter image description here

为什么会这样?为什么JComboBox没有显示相关数据,而不是重复相同的数据?

PS:我知道我们不应该基于name进行搜索,但是我们应该从“唯一ID”进行搜索,但这是对SO帖子的快速编辑。

2 个答案:

答案 0 :(得分:2)

首先将数据与其视图分开,模型数据不应包含任何类型的UI组件或UI相关信息。做出这些决定并不是模型的责任。该模型携带数据,这就是全部。

表中的单个单元格只包含一个值,无论它可能设置为什么。它只携带一个单一的状态或价值。

如何在屏幕上显示值是渲染器的域,如何修改值是编辑器的域。

为您构建TableModel并填入数据,将其传递给JTableimport java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumnModel; public class TableComboBox { public static void main(String[] args) { new TableComboBox(); } public TableComboBox() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } DefaultTableModel model = new DefaultTableModel(new Object[]{"A", "B", "C", "D"}, 5); JTable table = new JTable(model); JComboBox bCombo = new JComboBox(new Object[]{"Apples", "Bannans", "Pears", "Grapes"}); JComboBox cCombo = new JComboBox(new Object[]{"Elephants", "Monkeys", "Cats", "Dogs"}); JComboBox dCombo = new JComboBox(new Object[]{"Unicorns", "Dragons", "Pixis", "Blobs"}); DefaultCellEditor bEditor = new DefaultCellEditor(bCombo); DefaultCellEditor cEditor = new DefaultCellEditor(cCombo); DefaultCellEditor dEditor = new DefaultCellEditor(dCombo); TableColumnModel cm = table.getColumnModel(); cm.getColumn(1).setCellEditor(bEditor); cm.getColumn(2).setCellEditor(cEditor); cm.getColumn(3).setCellEditor(dEditor); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new JScrollPane(table)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } } 已配置了所需的渲染器和编辑器,以显示和编辑您的数据...

TableEditor

{{1}}

查看How to Use TablesUsing Other EditorsConcepts: Editors and Renderers了解详情

答案 1 :(得分:1)

如果您在JTable中显示此JCombobox,则应根据该行在JComboBox中设置正确的vallue。 为此,我正式使用我扩展的AbstractTableModel。 在方法getValueAt中你得到一个rowindex一个columnindex,你应该使用行索引来正确初始化JComboBox。 Als为每个显示的行使用单独的JComboBox。

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Object value = null;
    if(rowIndex > rows.size())
        return null;
    Item item = rows.get(rowIndex);

    switch (columnIndex) {
    case 0: //Your combobox
        JComboBox value= new JComboBox(listitems);
        jc.setSelectedItem(item.name);
        break;

.......

    return value;
}

我希望这会有所帮助。