I have added a combobox in a JTable, the adding code as follows:
Vector<String> header = new Vector<String>();
Vector data = new Vector();
String[] h = new String[]{"Music", "Movie", "Sport"};
header.add("Code");
header.add("Name");
header.add("Salary");
header.add("Hobby");
loadData(); // Add some data to the table
DefaultTableModel tblModel;
tblModel = (DefaultTableModel) this.tblEmp.getModel();
tblModel.setDataVector(data, header);
// Adding combobox to the last column
TableColumn hobbyColumn = tblEmp.getColumnModel().getColumn(3);
hobbyColumn.setCellEditor(new MyComboBoxEditor(h));
Things worked fine until I dynamically add a new row to the table using the code:
Vector v = new Vector();
v.add("E333");
v.add("Peter");
v.add(343);
v.add(""); // This last colum is the combobox so I put it as ""
data.add(v);
tblEmp.updateUI();
Data is added to the table but the combobox in the last column cannot be selected anymore. The combobox is still displayed when I click on the row but cannot select a value.
How can I handle this problem, please?
Never use the updateUI() method. Read the API to see what this method actually does. It has nothing to do with changing the data in a model.
JTable already supports a combo box editor so there is no need to create a custom MyComboBoxEditor. Read the JTable API and follow the link to the Swing tutorial on "How to Use Tables", for a working example of using a combo box as an editor.
Related
I have a Jtable, whose first column uses a JComboBox as editor. The combobox model contains data objects fetched from a sql database.
If I manually enter a value inside the combobox and then leave the editor, the entered value is lost. This doens't happen if the value is selected from the popup, or if the JComboBox's model is instantiated with simple Strings instead of bean objects.
Note that I need to add row dinamically, but this seems irrelevant since the issue appears both in the default row and in the added rows.
This is a working NetBeans sample project that reproduces my issue: https://drive.google.com/open?id=0B89FsS48-Yy4V09YRVozRzJGMkk
Here is the relevant code:
public NewJFrame() {
initComponents();
//bean objects used to populate the combobox:
Item item1 = new Item("one", 1);
Item item2 = new Item("two", 2);
Item item3 = new Item("three", 3);
JComboBox<Item> comboBox = new JComboBox<>(new Item[]{item1, item2, item3});
comboBox.setEditable(true);
DefaultCellEditor defaultCellEditor = new DefaultCellEditor(comboBox);
defaultCellEditor.setClickCountToStart(1);
jTable1.getColumnModel().getColumn(0).setCellEditor(defaultCellEditor);
}
private void addRowButtonActionPerformed(java.awt.event.ActionEvent evt) {
((DefaultTableModel) jTable1.getModel()).addRow(new Object[]{null, null});
}
Update: when the JComboBox in the table is populated via a model instead of the constructor like this,
items = new Item[]{item1, item2, item3};
JComboBox<Item> comboBox = new JComboBox<>();
comboBox.setModel(new DefaultComboBoxModel<>(items));
a manually inserted value is kept displayed, only if no selection has been made before; that is, if I first select a choice and then edit the choice, when leaving the combobox the previously selected item reappears.
None of the reported behaviours occur in a JComboBox outside the table, so this led me to think it's something related to the CellEditor.
Update 2: here's a bug report of this issue from the year 2000! They said they solved it back then but this is far from solved after 15 years.
This question already has answers here:
JComboBox in a JTable cell
(4 answers)
Closed 7 years ago.
I am trying to add two jcombobox in two row cells using DefaultTableModel addrow() method. Like this:
DefaultTableModel dtm = new DefaultTableModel();
JComboBox jcb1 = new JComboBox;
JComboBox jcb2 = new JComboBox;
JComboBox[] row={jcb1,jcb2};
dtm.addRow(row);
myTable.setModel(dtm);
It happens that the table takes the whole thing and displays into each cell the JComboBox.toString, the properties of each JComboBox instead of displaying the combobox itself the object. Can anyone help me? Thanks
To set the combo box as an editor on a column, you have to get the column using:
TableColumn comboColumn = table.getColumnModel().getColumn(1);
Instead of 1, put the actual column index (0 is for the first column, 1 is for the second etc.). And then:
comboColumn.setCellEditor(new DefaultCellEditor(comboBox));
Also, consider creating your own class that will extend AbstractTableModel and then using your class as table model instead of DefaultTableModel - maybe you don't have to do this, but it will give you more flexibility with defining behavior of jTable.
I have an instance of JTable in my java swing application. I want to deselect a selected row from this table. From This answer, JTable has provided clearSelection() method that deselect all selected rows in the table. But I want to deselect one row. How can I do this?
Have you tried:
ListSelectionModel.removeSelectionInterval(int index0, int index1)?
See this it toggles the selection of a row in jtable.
You can do this like that:
JTable table = new JTable(); // your table instance
TableModel dataModel = new DefaultTableModel(); // table model
DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); //table selection model
table.setModel(dataModel);
table.setSelectionModel(selectionModel);
int desiredRow = 0; // row which you want to deselect
selectionModel.removeSelectionInterval(desiredRow, desiredRow); // Removing selection for desired row
I have a JTable whose cells are editable. However if i edit a cell and refresh the table. The changes are not saved. This is how i have defined the table:
String [] columnNames = {"Application number",
"Name",
"date",
"fileLoc",
"Country"};
//Data for the table
String [][] data = table.tableArray;//tableArray is an array of array of strings.
TableModel model = new DefaultTableModel(data, columnNames);
JTable mainTable = new JTable(model);
model.isCellEditable(data.length,columnNames.length);
contentPane.add(new JScrollPane (mainTable));
I've had a look online but can't seem to find any advice on saving the changes made to a cell. Any help would be very welcome!
I guess i'm not refreshing the table as such. I use frame.dispose()
and then create a new frame with the table in.
then you lost all changes made in the current DefaultTableModel
don't top create a new JFrame with a new DefaultTableModel and a new JTable
all changes from TableCellEditor are changes dispayed in JTables view
JTable (with its model) is prepared for this job, don't to reacreate these Objects on runtime
DefaultTableModel has implemented all notifiers, there no needed to override any others events, nor to fireXxxXxx() programatically, but those events are required for AbstractTableModel
define add this code line for your JTablemainTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
DefaultTableModel respesenting your required 2D array
I try to add header row to my JTable and next put table on panel.
This is my sample code :
Map <String, Float> tmpCart = new HashMap<String , Float>();
MainPanel.removeAll();
MainPanel.repaint();
tmpCart = cart.GetMap();
DefaultTableModel tab = new DefaultTableModel();
tab.setColumnIdentifiers(new String[] {"Name", "Price"});
for (String key : tmpCart.keySet())
tab.addRow(new Object[] {key, tmpCart.get(key)});
JTable jTab = new JTable(tab);
jTab.setBounds(10, 10, 200, 200);
jTab.setBackground(Color.orange);
jTab.setRowHeight(25);
JScrollPane pan =new JScrollPane(jTab);
MainPanel.add(pan);
// MainPanel.add(jTab);
// pan.repaint();
How do I write it properly?
//answer
I try create JTable dynamically, after push button, I want get data from Hashtable, create table and put this table on panel.
First step is remove all components from panel, and next create JTable using data from Hashmap`
full function:
private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {
Map <String, Float> tmpCart = new HashMap<String , Float>();
MainPanel.removeAll();
MainPanel.repaint();
tmpCart = cart.GetMap();
DefaultTableModel tab = new DefaultTableModel();
tab.setColumnIdentifiers(new String[] {"Name", "Price"});
for (String key : tmpCart.keySet())
tab.addRow(new Object[] {key, tmpCart.get(key)});
JTable jTab = new JTable(tab);
jTab.setBounds(10, 10, 200, 200);
jTab.setBackground(Color.orange);
jTab.setRowHeight(25);
// MainPanel.add(pan);
MainPanel.add(jTab);
}
This code works, create table and put it on panel, but doesn't set first row with column names ( text : "Names" and "Price").
Can't tell exactly what you are doing from the code sample.
If you are trying to dynamically update a table on a visible GUI, then there is not need to create a new table, just reset the TableModel.
table.setModel( model );
If you need more help then post your SSCCE that demonstrates the problem.
Edit:
First step is remove all components from panel,
Why are your removing components from the panel?
If you need to "swap" panels, then use a CardLayout.
If you need to "refresh" existing components, then just reset the model as explained above.
// MainPanel.add(pan);
MainPanel.add(jTab);
The scrollPane should be added to the GUI, not the table.
The table header is another component that only gets added automatically when the table is inside a JScrollPane. Your best bet is to create a JScrollPane via
new JScrollPane(table)
and add that to your MainPanel.
The other option is to added the header directly wherever you want it, and for that you can do:
panel.add(table.getTableHeader())
Try putting it into a JScrollPane.