I'm trying to build a table which includes JComboBoxes as both the renderer and editor components. This mostly works fine, however there are two things I can't seem to solve.
Tabbing between cells should make the JComboBox active
Clicking the drop-down arrow should immediately open the option list
Regarding 1, the editable combo should place focus within the embedded text field, the fixed combo should allow the down arrow to open the list of options.
Regarding 2, I find that this sometimes works depending on what other cell is currently active, but other times I have to double click. I cannot make this behaviour consistent.
For convenience I have included a clear example which (I believe) uses the recommended approach for embedding JComboBoxes within Jtables.
Thank you for constructive advice.
import java.awt.Component;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableCombos
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
AbstractTableModel model = new DefaultTableModel()
{
String[] columnHeaders = new String[]{"label", "combo-edit", "combo-fixed"};
Class<?>[] columnClasses = new Class<?>[]{String.class, Double.class, Double.class};
List<Object[]> data = new ArrayList<>();
{
data.add(new Object[]{"row 1", 1.0d, 2.0d});
data.add(new Object[]{"row 2", 2.0d, 3.0d});
}
#Override
public int getColumnCount()
{
return columnHeaders.length;
}
#Override
public boolean isCellEditable(int row, int column)
{
return column != 0;
}
#Override
public int getRowCount()
{
if (data == null) // race condition
return 0;
return data.size();
}
#Override
public Object getValueAt(int row, int column)
{
return data.get(row)[column];
}
#Override
public void setValueAt(Object aValue, int row, int column)
{
data.get(row)[column] = aValue;
}
#Override
public Class<?> getColumnClass(int column)
{
return columnClasses[column];
}
#Override
public String getColumnName(int column)
{
return columnHeaders[column];
}
};
JTable table = new JTable(model);
table.setSurrendersFocusOnKeystroke(true);
TableColumn c1 = table.getColumnModel().getColumn(1);
TableColumn c2 = table.getColumnModel().getColumn(2);
JComboBox<Double> editorComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
editorComboEditable.setEditable(true);
c1.setCellEditor(new DefaultCellEditor(editorComboEditable));
c2.setCellEditor(new DefaultCellEditor(new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d})));
final JComboBox<Double> rendererComboEditable = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
rendererComboEditable.setEditable(true);
final JComboBox<Double> rendererComboFixed = new JComboBox<>(new Double[]{1.0d, 2.0d, 3.0d});
c1.setCellRenderer(new TableCellRenderer()
{
#Override
public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
rendererComboEditable.setSelectedItem(value);
return rendererComboEditable;
}
});
c2.setCellRenderer(new TableCellRenderer()
{
#Override
public Component getTableCellRendererComponent(JTable t, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
rendererComboFixed.setSelectedItem(value);
return rendererComboFixed;
}
});
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
}
Both of your issues be resolved by overriding the DefaultCellEditor#isCellEditable method and returning true
You may need to set JTable#setSurrendersFocusOnKeystroke to true as well
Update
The short answer is "It's messy". The long answer is "it's very messy"
I did a "continuos editing" process some time back. Basically, I overrode the Enter and Tab key bindings.
What I'd did was basically stop any active cell editor, take note of the current cell and then tried to finding the next editable cell, looping back around to the start (cell 0x0) if required.
When I found a editable cell, I called JTable#esitCellAt to start editing the cell.
To get the popup to be visible when the cell starts editing, you will need to override the addNotify method of the JComboBox and, using SwingUtilities#invokeLater, set the popup visible
Related
I want to make a JTable , where one single cell (not all rows of a column) will contain a JComponent like JdatePicker or JComboBox.
I have written this code
DefaultTableModel dm;
dm = new DefaultTableModel() {
public boolean isCellEditable(int rowIndex, int columnIndex) {
return !(columnIndex == 0); //make 0th column non-editable
}
};
Object [] columnHeaders=new Object[]{"Field", "Value"};
Object [][] data=new Object[][]{{"ID",""},{"Reg Year",""},{"Reg Date", ""}} ;
regFormTable.setModel(dm); //regFormTable is a Jtable object
I also have a class that implements TableCellrenderer:
public class datePickerCellRenderer extends JFrame implements TableCellRenderer{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.add(new JDateChooser());
return this;
}
}
How can I use datePickerCellRenderer class to implement as I described. I tried a few ways. None of those worked.
[Using Netbeans GUI builder is there a way to do that?]
Plaese ask if any more code I need to add
I would like to make an editable table and then check the data to make sure its valid. Im not sure how to change the color of just one cell. I would like to get a cell, for example (0,0) and color the foreground to red. I have read the other posts on SO as well as Oracle about the custom ColorRenderer, but i just don't get how i would use this.
Thanks.
Say that the cell you would like to render with a different color represents a status (I'll take Rejected and Approved as examples). I'd then implement a method in my table model called getStatus(int row) which returns the status for any given row.
Then, when that is in place, I'd go about creating a cell renderer responsible for rendering the column which the cell belongs to. The cell renderer would be something in the lines of the below code.
public class StatusColumnCellRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
//Cells are by default rendered as a JLabel.
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
//Get the status for the current row.
CustomTableModel tableModel = (CustomTableModel) table.getModel();
if (tableModel.getStatus(row) == CustomTableModel.APPROVED) {
l.setBackground(Color.GREEN);
} else {
l.setBackground(Color.RED);
}
//Return the JLabel which renders the cell.
return l;
}
Then, when the renderer is in place, simply "apply" the renderer to the table with the following piece of code:
Table.getColumnModel().getColumn(columnIndex).setCellRenderer(new StatusColumnCellRenderer());
With regard to making a cell editable, simply implement the isCellEditable(int rowIndex, int columnIndex) method in your table model. You also need to implement the method
setValueAt(Object value, int rowIndex, int columnIndex) if you would like to keep the value which the user provides (which i assume you do!).
I would like to make an editable table and then check the data to make sure its valid.
Another approach would be to edit the data before it is saved to the table model to prevent invalid data from being entered.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableEdit extends JFrame
{
TableEdit()
{
JTable table = new JTable(5,5);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollpane = new JScrollPane(table);
getContentPane().add(scrollpane);
// Use a custom editor
TableCellEditor fce = new FiveCharacterEditor();
table.setDefaultEditor(Object.class, fce);
}
class FiveCharacterEditor extends DefaultCellEditor
{
FiveCharacterEditor()
{
super( new JTextField() );
}
public boolean stopCellEditing()
{
try
{
String editingValue = (String)getCellEditorValue();
if(editingValue.length() != 5)
{
JTextField textField = (JTextField)getComponent();
textField.setBorder(new LineBorder(Color.red));
textField.selectAll();
textField.requestFocusInWindow();
JOptionPane.showMessageDialog(
null,
"Please enter string with 5 letters.",
"Alert!",JOptionPane.ERROR_MESSAGE);
return false;
}
}
catch(ClassCastException exception)
{
return false;
}
return super.stopCellEditing();
}
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
Component c = super.getTableCellEditorComponent(
table, value, isSelected, row, column);
((JComponent)c).setBorder(new LineBorder(Color.black));
return c;
}
}
public static void main(String [] args)
{
JFrame frame = new TableEdit();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
I believe the correct way to do colouring in a table is via a ColorHighlighter. The table renderers have problems to render different colours in the same column.
Here is an example of how to use highlighters. In this case it is for highlighting a cell that is not editable.
public class IsCellEditablePredicate implements HighlightPredicate {
private JXTable table;
public IsCellEditablePredicate (final JXTable table) {
this.table = table;
}
#Override
public boolean isHighlighted(Component component, ComponentAdapter componentAdapter) {
return !table.isCellEditable(componentAdapter.row,
componentAdapter.column);
}
}
and then in your code for setuping the table you add the highlighter and its colour parameters:
ColorHighlighter grayHighlighter = new ColorHighlighter(new IsCellEditablePredicate(table));
grayHighlighter.setBackground(Color.LIGHT_GRAY);
grayHighlighter.setForeground(table.getForeground());
grayHighlighter.setSelectedBackground(table.getSelectionBackground().darker());
grayHighlighter.setSelectedForeground(table.getSelectionForeground().darker());
table.setHighlighters(grayHighlighter);
This is the simplest way to color a particular Column or cell in a jTable.
First just create a simple class of CustomRenderer
class CustomRenderer extends DefaultTableCellRenderer <br />
{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setForeground(Color.blue); >
return c;
}
}
This code gets the column of cell to render
TableColumn col = tblExamHistoryAll.getColumnModel().getColumn(5);
DefaultTableModel model3 = (DefaultTableModel)tblExamHistoryAll.getModel();
col.setCellRenderer(new CustomRenderer());
This is to clear all previous rows from your table. If you do not want them just remove these lines
model3.getDataVector().removeAllElements();
model3.fireTableDataChanged();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int col) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
int control = row;
control = control % 2;
control = (control == 0) ? 1 : 0;
if (control == 1) {
c.setBackground(Color.green);
} else {
c.setBackground(Color.cyan);
}
return c;
}
The most straightforward way is to write a simple TableCellRenderer by extending the DefaultTableCellRenderer and overwriting the getTableCellRendererComponent method to setBackground( Color.RED ). For example:
final JTable table = new JTable(...);
table.setCellRenderer( new DefaultTableCellRenderer() {
public Component getTableCellRenderer(JTable table, Object value, ...) {
super.getTableCellRenderer(...);
if ( value should be highlighted ) {
setBackground( Color.RED );
}
return this;
}
});
You can extend DefaultTableCellRenderer, override getTableCellRendererComponent and call something like
if (myConditions) setBackground(myColor);
before returning "this" when conditions apply but it has a very annoying side-effect of changing the default back-color due to the way DefaultTableCellRenderer.setBackGround is coded.
The trick I found was to entirely duplicate the code of DefaultTableCellRenderer in a class named HackedDefaultTableCellRenderer, add a method that calls directly the Component's setBackground implementation:
public void setComponentBackground(Color c) {
super.setBackground(c);
}
then derive my customized rendered from this hacked class instead of from DefaultTableCellRenderer, and finally call setComponentBackground instead of setBackground in my customized getTableCellRendererComponent.
The drawback is that this HackedDefaultTableCellRenderer relies on a snapshot of DefaultTableCellRenderer.
I have implemented a JTree and populated some data. The table contains three columns and based on some values on a specific cell it should have either labels or combo boxes. All the values in the 3rd column are editable. I too have a JTree from which a node is selected and based on it the table values change accordingly. The issue exists when I edit a cell in the table and move to another node in the tree (which populates a new set of data in the table), the previously edited cell values exist in the table on top of the new cell values. Below is how I implemented TableCellRenderer and TableCellEditor. I might have used some concepts wrong since I am a beginner for swing. Please help me figure out what I have done incorrectly.
public void populateTableData(List<Field> list,JTree jTree){
fieldList = null;
tcBuilderTree = jTree;
fieldList = list;
md=new PropertiesTableModel(fieldList);
getPropertieseTable().setModel(md);
final TableCellRenderer cellRenderer = new TableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable arg0,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int col) {
if(value instanceof List<?>) {
List<Value> valueList=(ArrayList)value;
return createComboBox(valueList);
}
else{
JLabel lbl=new JLabel();
lbl.setText((String)value);
return lbl;
}
}
};
propertiesTable.setDefaultRenderer(Object.class, cellRenderer);
final TableCellEditor cellEditor = new TableCellEditor() {
private DefaultCellEditor textEditor;
private DefaultCellEditor currentEditor;
#Override
public Component getTableCellEditorComponent(JTable table,
Object value,
boolean isSelected,
int row,
int column) {
textEditor = new DefaultCellEditor(new JTextField());
PropertiesTableModel model = (PropertiesTableModel) table.getModel();
List<Value> values = model.getPossibleValues(row, column);
if (values != null) {
List<Value> valueList=(ArrayList)value;
currentEditor = new DefaultCellEditor(createComboBox(valueList));
} else {
currentEditor = textEditor;
}
return currentEditor.getTableCellEditorComponent(table, value,
isSelected, row, column);
}
#Override
public Object getCellEditorValue() {
return currentEditor.getCellEditorValue();
}
#Override
public boolean isCellEditable(EventObject anEvent) {
JTable tbl = (JTable) anEvent.getSource();
int row, col;
if (anEvent instanceof MouseEvent) {
MouseEvent evt = (MouseEvent) anEvent;
row = tbl.rowAtPoint(evt.getPoint());
col = tbl.columnAtPoint(evt.getPoint());
} else {
row = tbl.getSelectedRow();
col = tbl.getSelectedColumn();
}
if(col<2){
return false;
}
else
{
return true;
}
}
#Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
#Override
public boolean stopCellEditing() {
Object obj = currentEditor.getCellEditorValue();
fieldList.get(propertiesTable.getEditingRow())
.setDefaultValue(obj);
return currentEditor.stopCellEditing();
}
#Override
public void cancelCellEditing() {
currentEditor.cancelCellEditing();
}
#Override
public void addCellEditorListener(CellEditorListener l) {
}
#Override
public void removeCellEditorListener(CellEditorListener l) {
}
};
propertiesTable.setDefaultEditor(Object.class,cellEditor);
}
The issue exists when I edit a cell in the table and move to another node in the tree (which populates a new set of data in the table), the previously edited cell values exist in the table on top of the new cell values.
I would guess you are not stopping editing of the table cell before you reload the table with new data.
You probably should add the following to your code when you create the JTable:
JTable table = new JTable(...);
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
See Table Stop Editing for more information.
The table contains three columns and based on some values on a specific cell it should have either labels or combo boxes
You may not need to create custom editors. Just have the table choose the appropriate default editor based on the cell being edited. You can do this by overriding the getCellEditor(...) method of the JTable. Check out: How to add unique JComboBoxes to a column in a JTable (Java) for an example of this approach.
Before starting, I've viewed a handful of solutions as well as documentation. I can't seem to figure out why my code isn't working the way I believe it should work. I've extended DefaultTableCellRenderer but I don't believe it is being applied - that or I messed things up somewhere.
Here are the threads / websites I've looked into before posting this question:
Swing - Is it possible to set the font color of 'specific' text within a JTable cell?
JTable Cell Renderer
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
I realize the first link uses HTML to change the font color, but I would think the way I went about it should produce the same result.
To make it easier on those who want to help me figure out the issues, I've created an SSCCE.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TableTest {
private static final int IMPORTANT_COLUMN = 2;
public static void createAndShowGUI() {
Object[][] data = new Object[2][4];
//create sample data
String[] realRowData = { "1", "One", "1.0.2", "compile" };
String[] fakeRowData = { "2", "Two", "1.3.2-FAKE", "compile" };
//populate sample data
for(int i = 0; i < realRowData.length; i++) {
data[0][i] = realRowData[i];
data[1][i] = fakeRowData[i];
}
//set up tableModel
JTable table = new JTable();
table.setModel(new DefaultTableModel(data,
new String[] { "ID #", "Group #", "version", "Action" })
{
Class[] types = new Class[] {
Integer.class, String.class, String.class, String.class
};
boolean[] editable = new boolean[] {
false, false, true, false
};
#Override
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return editable[columnIndex];
}
});
//set custom renderer on table
table.setDefaultRenderer(String.class, new CustomTableRenderer());
//create frame to place table
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setMinimumSize(new Dimension(400, 400));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(table);
f.add(scrollPane);
f.pack();
f.setVisible(true);
}
//MAIN
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
//Custom DefaultTableCellRenderer
public static class CustomTableRenderer extends DefaultTableCellRenderer {
public Component getTableCellRenderer(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
Component c = super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
String versionVal = table.getValueAt(row, IMPORTANT_COLUMN).toString();
if(versionVal.contains("FAKE")) {
//set to red bold font
c.setForeground(Color.RED);
c.setFont(new Font("Dialog", Font.BOLD, 12));
} else {
//stay at default
c.setForeground(Color.BLACK);
c.setFont(new Font("Dialog", Font.PLAIN, 12));
}
return c;
}
}
}
My goal is to highlight any value in the version column that contains the word FAKE in a red bold text.
I've extended DefaultTableCellRenderer but I don't believe it is being applied
Some simple debugging tips:
Add a simple System.out.println(...) to the method you think should be invoked
When overriding a method, make sure you use the #Override annotation (you used it in the TableModel class, but not your renderer class).
Your problem is a typing mistake because you are not overriding the proper method:
#Override
// public Component getTableCellRenderer(...) // this is wrong
public Component getTableCellRendererComponent(...)
The override annotation will display a compile message. Try it before changing the code.
Also, your first column is NOT an Integer class. Just because it contains String representations of an Integer does not make it an Integer. You need to add an Integer object to the model.
Replace your custom table cell rendere with the below.
Explanations are in comments. Basically, you should override getTableCellRendererComponent then check for correct column (there may be other methods instead of checking header value), then set cell depending on color.
Do not forget last else block to set color to default if it is not the column you want.
//Custom DefaultTableCellRenderer
public static class CustomTableRenderer extends DefaultTableCellRenderer {
// You should override getTableCellRendererComponent
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
// Check the column name, if it is "version"
if (table.getColumnName(column).compareToIgnoreCase("version") == 0) {
// You know version column includes string
String versionVal = (String) value;
if (versionVal.contains("FAKE")) {
//set to red bold font
c.setForeground(Color.RED);
c.setFont(new Font("Dialog", Font.BOLD, 12));
} else {
//stay at default
c.setForeground(Color.BLACK);
c.setFont(new Font("Dialog", Font.PLAIN, 12));
}
} else {
// Here you should also stay at default
//stay at default
c.setForeground(Color.BLACK);
c.setFont(new Font("Dialog", Font.PLAIN, 12));
}
return c;
}
}
I want to put individual JComboBoxes into each cells of a JTable. ie. The JComboBox content is not identical for each cell.
I basically would like to be able to just call the following code to add a row of JComboBox into the JTable. Anyone has any idea? Thanks
JComboBox cb1 = new JComboBox(...);
JComboBox cb2 = new JComboBox(...);
model.addRow(new Object[] {"Row name", cb1, cb2} );
JComboBox cb3 = new JComboBox(...);
JComboBox cb4 = new JComboBox(...);
model.addRow(new Object[] {"Row name 2", cb3, cb4} );
The closest example code I can find is as follows. But it is for where JComboBox content is identical for the individual column. Not the solution I need.
TableColumn col = table.getColumnModel().getColumn(vColIndex);
col.setCellEditor(new MyComboBoxEditor(values));
where
public class MyComboBoxEditor extends DefaultCellEditor {
public MyComboBoxEditor(String[] items) {
super(new JComboBox(items));
}
}
Extend JTable with this code:
#Override
public TableCellEditor getCellEditor(int row, int column) {
Object value = super.getValueAt(row, column);
if(value != null) {
if(value instanceof JComboBox) {
return new DefaultCellEditor((JComboBox)value);
}
return getDefaultEditor(value.getClass());
}
return super.getCellEditor(row, column);
}
This will create a unique JComboBox cell editor for each combo box you get the a value for.
I am sure this will solve your problem. Mention in which column you need to set the combo box in .getColumn(int column)
private void addComboToTable(JComboBox combo) {
TableColumn gradeColumn = YourTable.getColumnModel().getColumn(0);
JComboBox comboBox = combo;
comboBox.removeAllItems();
try {
comboBox.addItem("Item 1");
comboBox.addItem("Item 2");
comboBox.addItem("Item 3");
} catch (NullPointerException e) {
} catch (Exception e) {
e.printStackTrace();
}
gradeColumn.setCellEditor(new DefaultCellEditor(comboBox));
}
You need to override:
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
...in TableCellEditor. The value passed in to this method is what you can put in your JComboBox. That means that the 'value' for that particular cell needs to be something that can be translated into a collection. It could potentially just be a List of objects or it could be a POJO with fields that could be made into a JComboBox.
So just edit MyComboBoxEditor to override that method and change your model to allow for an Object that actually represents several other objects.
The JComboBox content is render identical for each row selection because
the JTable does not offer the capability to have more than one editor per column.
You have to extend the JTable class to support an additional selection for rows.
This article explains it very well:
http://www.javaworld.com/javaworld/javatips/jw-javatip102.html
In addition to cellEditor it is necessary to do the cellRenderer to paint the combobox in the cell, look at this:
public void example(){
TableColumn tmpColum =table.getColumnModel().getColumn(1);
String[] DATA = { "Data 1", "Data 2", "Data 3", "Data 4" };
JComboBox comboBox = new JComboBox(DATA);
DefaultCellEditor defaultCellEditor=new DefaultCellEditor(comboBox);
tmpColum.setCellEditor(defaultCellEditor);
tmpColum.setCellRenderer(new CheckBoxCellRenderer(comboBox));
table.repaint();
}
/**
Custom class for adding elements in the JComboBox.
*/
class CheckBoxCellRenderer implements TableCellRenderer {
JComboBox combo;
public CheckBoxCellRenderer(JComboBox comboBox) {
this.combo = new JComboBox();
for (int i=0; i<comboBox.getItemCount(); i++){
combo.addItem(comboBox.getItemAt(i));
}
}
public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
combo.setSelectedItem(value);
return combo;
}
}
#Override
public TableCellEditor getCellEditor(int row, int column) {
Object value = super.getValueAt(row, column);
if(value != null) {
if(value instanceof JComboBox) {
return new DefaultCellEditor((JComboBox)value);
}
return getDefaultEditor(value.getClass());
}
return super.getCellEditor(row, column);
}
And then, override the toString method from JComboBox.
This page might help you, although it seems you are restricted to having the same combobox in all the cells in a column.
You need to create a subclass of JTable to override the method TableCellEditor getCellEditor(int row, int column).
This enables you to set arbitrary cell editors for any row and column combination. The default way is to set the cell editor for an entire column.
(You can also set individual cell renderers by overriding getCellRenderer.)
The easiest way is to implement your own TableModel
public class MyModel extends AbstractTableModel {
List rows;
public int getRowCount() {
return rows.size();
}
public int getColumnCount() {
return 4;
}
public Object getValueAt(int row, int column) {
return rows.get(row).getCol(col); //assuming your row "Object" has a getCol()
}
public Class<?> getColumnClass(int col) {
return Boolean.class;
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
rows.get(rowIndex).getCol(columnIndex).setValue(aValue);
}
}
Load this into you JTable. If you haven't replaced the default cell renderer for Boolean's, all you cells will be rendered as check boxes thanks to you implementation of getColumnClass(). All user input to these check boxes is collected with our setValueAt().