简体   繁体   中英

JComboBox in JTable display invalid data

I have a JTable where I dynamically fill its columns based on the database select query. One column of this JTable will accept a JComboBox . Now, please have a look at the below code.

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

The dbConnector.selectAllDetails() method

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

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

        return r;
    }

The problem here is that my JComboBox is not getting filled as expected. It should fill the data based on the provided search query, but instead, it shows the same item in all the rows, an item 03 which is the portfolio ID for the client name AAA .

Below is my client table (with dummy input)

在此处输入图片说明

Below is my Portfolio table (with dummy input)

在此处输入图片说明

Why is this happening? Why the JComboBox is not displaying the related data, instead of repeating the same data?

PS: I know we should not search based on the name but we should search from the ``unique id`, but that is a quick edit for SO post.

Start by separating your data from it's view, model data should never contain ANY type of UI component or UI related information. It is not the responsibility of the model to make these decisions. The model carries data and that is all.

A single cell in a table contains only a single value, regardless of what it might be set to. It only ever carries a single state or value.

How a value is represented on the screen is the domain of the renderers, how a value is modified is the domain of editors.

Build you TableModel and fill it with data, pass this to a JTable , which has been configured with the required renderers and editors to display and edit you data...

表格编辑器

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

Take a look at How to Use Tables , Using Other Editors , and Concepts: Editors and Renderers for more details

If You are showing this JCombobox in a JTable you should set the correct vallue in the JComboBox based on the row. For this I normaly use a AbstractTableModel that I extend. in the method getValueAt you get a rowindex an columnindex, you should use the row index to initialize the JComboBox correctly. Als use a seperate JComboBox for every displayed row.

@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;
}

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM