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.