Firing itemStateChanged event on Combo box inside jTable
As discussed here, you can use a JComboBox
as a TableCellEditor
. There's an example here using DefaultCellEditor
.
Adding a JComboBox to a JTable cell. Selected item doesn't stay
Normally you should use the default cell renderer to display your cell contents and only show the combobox when editting.
A key concept to understand with JTable cell renderers is that a single cell renderer is generally used to draw all of the cells that contain the same type of data.
If you particularly want a combobox to be used for rendering cells, the reason that your cells are blank is that the custom renderer combobox does not have the items added to it. You should populate the cell renderer combobox with the same values as your cell editor combobox.
Change content of a JComboBox in a single cell based on the selection in another JComboBox using Java Swing
You need to change the editor for each row in the table.
Here is an example that shows how to display a different editor for each row:
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableComboBoxByRow extends JPanel
{
List<String[]> editorData = new ArrayList<String[]>(3);
public TableComboBoxByRow()
{
setLayout( new BorderLayout() );
// Create the editorData to be used for each row
editorData.add( new String[]{ "Red", "Blue", "Green" } );
editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
editorData.add( new String[]{ "Apple", "Orange", "Banana" } );
// Create the table with default data
Object[][] data =
{
{"Color", "Red"},
{"Shape", "Square"},
{"Fruit", "Banana"},
{"Plain", "Text"}
};
String[] columnNames = {"Type","Value"};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model)
{
// Determine editor to be used by row
public TableCellEditor getCellEditor(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
if (modelColumn == 1 && row < 3)
{
JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
return new DefaultCellEditor( comboBox1 );
}
else
return super.getCellEditor(row, column);
}
};
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableComboBoxByRow() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You will obviously need to customize the logic since your editor will be based on a value in another column, not the row, but the code should get you started.
JComboBox remembering other selections
First of all don't use "==" when comparing strings. Instead you should be using the equals(...)
method:
if (someString.equals(anotherString))
// do something
However, that is not the cause of the problem.
You are using the JComboBox incorrectly for a JTable. You should NOT be using a ItemListener (or any listener).
The combo box is just used as an editor for the table. That means when you select a value from the combo box, the TableModel
of the table is updated. So if you have custom logic based on the selected value you need to override the setValueAt(...)
method of your TableModel
.
@Override
public void setValueAt(Object value, int row, int column)
{
super.setValueAt(value, row, column);
// add your custom logic here
}
How can I disable this, so that the default selection is always -1
The value displayed in the combo box is taken from the TableModel
. So if you set the default value to be null the combo box will not have a selection when you start editing.
Read the section from the Swing tutorial on How to Use Tables for more information and working examples. Keep the tutorial link handy for future reference on Swing basics.
setSelectedItem of JCombobox in a JTable
If you click in such a
JComboBox
, you will notice it always chooses the first entry and not the entry with the number you saw before clicking at it.
Focusing on this aspect of the problem, the following simplified, complete example always displays the selected entry when the cell's editor is active. You can replace the combo's default renderer to display a different result as needed. In addition,
Override
getPreferredScrollableViewportSize()
to establish the desired size of the table.Use type parameters where possible; override
getColumnClass()
as needed, for example.Override
getValueAt()
, as shown here and here, for dependent data.Note the simplified implementation of
isCellEditable()
below.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/**
* @see https://stackoverflow.com/q/39993746/230513
*/
public class TableComboTest {
private Vector<Vector<String>> createData() {
Vector<Vector<String>> data = new Vector<Vector<String>>();
for (int i = 0; i < 5; i++) {
Vector<String> rowVector = new Vector<String>();
rowVector.add(String.valueOf(i));
rowVector.add("name");
rowVector.add(String.valueOf(i + 1));
rowVector.add(String.valueOf(i + 1));
rowVector.add(String.valueOf(i + 1));
data.add(rowVector);
}
return data;
}
private void display() {
Vector<Vector<String>> data = createData();
Vector<String> names = new Vector<>(Arrays.asList("ID", "Name", "OK", "Other", "Error"));
DefaultTableModel tableModel = new DefaultTableModel(data, names) {
@Override
public boolean isCellEditable(int row, int column) {
return column > 1;
}
};
JTable table = new JTable(tableModel) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(getPreferredSize().width, getRowHeight() * 4);
}
};
TableColumn column_ok = table.getColumnModel().getColumn(2);
TableColumn column_other = table.getColumnModel().getColumn(3);
TableColumn column_error = table.getColumnModel().getColumn(4);
String[] choices = new String[]{"1", "2", "3", "4", "5"};
JComboBox<String> combobox_ok = new JComboBox<>(choices);
JComboBox<String> combobox_other = new JComboBox<String>(choices);
JComboBox<String> combobox_error = new JComboBox<String>(choices);
column_ok.setCellEditor(new DefaultCellEditor(combobox_ok));
column_other.setCellEditor(new DefaultCellEditor(combobox_other));
column_error.setCellEditor(new DefaultCellEditor(combobox_error));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new TableComboTest()::display);
}
}
Conditional JComboBox inside JTable - How to Automatically change values
use code example from official Oracle tutorial How to use Table - Using a Combo Box as an Editor, in model is stoere only selected value from JComboBox, not JComboBox
you have to override
setValueAt
, 1st part insidesetValueAt
is about to storeinteger value
from currentJComboBox as CellEditor
toXxxTableModel
, second part is about to set value to (another JTables cell) another cell in XxxTableModel
I'd be
to use
DefaultTableModel
there is to override
getColumnClass
forJComboBox
(to have to contains integer to avoiding parsing)isCellEditable
setValueAt
in SSCCE form
JTable with JComboBox as editor - removing current row
As recommended by mKorbel, just implement that logic in your TableModel
setValueAt(...)
method. here is simple example:
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class Example extends JFrame {
private JTable table;
public Example(){
table = getTable();
add(new JScrollPane(table));
pack();
setVisible(true);
}
private JTable getTable() {
table = new JTable(new DefaultTableModel(3,3){
@Override
public void setValueAt(Object aValue, int row, int column) {
super.setValueAt(aValue, row, column);
if(column == 2){
if(aValue.toString().isEmpty()){
removeRow(row);
} else {
addRow(new Object[] {null, null, null});
}
}
}
});
TableColumn column = table.getColumnModel().getColumn(2);
JComboBox<String> comboBox = new JComboBox<>(new String[]{"","1","2","3","4","5"});
column.setCellEditor(new DefaultCellEditor(comboBox));
return table;
}
public static void main(String[] values){
new Example();
}
}
Object in JComboBox in JTable is not associated with same object in combo list
Finally I found what was wrong. I didn't override equal method in my class, and that is why these components couldnt recognise same item. Anyway, thank you all.
Related Topics
Resolving Dependency Problems in Apache Spark
Type List VS Type Arraylist in Java
Difference Between Class.Getresource() and Classloader.Getresource()
Compare Two Objects With .Equals() and == Operator
Capturing Stdout When Calling Runtime.Exec
Java.Net.Socketexception: Connection Reset
Using Threads to Make Database Requests
Maven: Add a Dependency to a Jar by Relative Path
Close a Scanner Linked to System.In
Difference Between a Static and a Non-Static Initialization Code Block
Difference Between Final and Effectively Final
"Expected Begin_Object But Was String At Line 1 Column 1"
What Do 3 Dots Next to a Parameter Type Mean in Java
Java Order of Initialization and Instantiation
How to Iterate Over a Jsonobject