Change background color of one cell in JTable
You'll need a custom renderer to display the green color when a cell is marked modified in your model.
You'll also need a custom editor to set the model's modified state in your implementation of stopCellEditing()
, mentioned here.
A related example of a custom renderer and editor is shown here.
Addendum: Here's an example of the approach described.
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
/**
* @see https://stackoverflow.com/a/12352838/230513
*/
public class ModifiedCells extends JPanel {
public ModifiedCells() {
final MyModel model = new MyModel();
JTable table = new JTable(model);
table.setDefaultRenderer(String.class, new MyRenderer());
table.setDefaultEditor(String.class, new MyEditor(table));
this.add(table);
}
private static class MyRenderer extends DefaultTableCellRenderer {
Color backgroundColor = getBackground();
@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);
MyModel model = (MyModel) table.getModel();
if (model.getState(row)) {
c.setBackground(Color.green.darker());
} else if (!isSelected) {
c.setBackground(backgroundColor);
}
return c;
}
}
private static class MyEditor extends DefaultCellEditor {
private JTable table;
private MyModel model;
public MyEditor(JTable table) {
super(new JTextField());
this.table = table;
this.model = (MyModel) table.getModel();
}
@Override
public boolean stopCellEditing() {
model.setState(table.getEditingRow(), true);
return super.stopCellEditing();
}
}
private static class MyModel extends AbstractTableModel {
private final List<Row> list = new ArrayList<Row>();
public MyModel() {
list.add(new Row("One", true));
list.add(new Row("Two", false));
list.add(new Row("Three", false));
}
public boolean getState(int row) {
return list.get(row).state.booleanValue();
}
public void setState(int row, boolean state) {
list.get(row).state = state;
}
@Override
public int getRowCount() {
return list.size();
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int row, int col) {
return list.get(row).name;
}
@Override
public void setValueAt(Object aValue, int row, int col) {
list.get(row).name = (String) aValue;
fireTableCellUpdated(row, col);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
private static class Row {
private String name;
private Boolean state;
public Row(String name, Boolean state) {
this.name = name;
this.state = state;
}
}
}
private void display() {
JFrame f = new JFrame("ModifiedCells");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ModifiedCells().display();
}
});
}
}
Matteo Codogno
I'm Technical Leader at WellD, a software house delivering innovative solutions in the domains of Energy, Industry automation and Health. I love to experiment with new technologies, open source projects and design Software architectures (I am a kid in a candy store!).
Updated on December 08, 2020Comments
-
Matteo Codogno over 3 years
Possible Duplicate:
Changing Swing JTable Cell ColorsI have developed a swing application which shows a JTable. I want that when the user modify a cell value, the cell modified change color.
This is the code that I run when the user modify a cell:
this.myTable.getColumnModel().getColumn(column).setCellRenderer(new StatusColumnCellRenderer());
And this is the code of my cell Render class:
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. TableModelLotti tableModel = (TableModelLotti) table.getModel(); if(isSelected) l.setBackground(Color.GREEN); //Return the JLabel which renders the cell. return l; } }
-
trashgod almost 12 yearswhen the user modifies a cell value: You'll have to maintain this state in your (unseen)
TableModel
. -
Matteo Codogno almost 12 years@trashgod Color cell is not related to table model but is related to cellRender.
-
trashgod almost 12 yearsThe cell's state goes in the
TableModel
; it's resulting color is applied in the renderer. -
Matteo Codogno almost 12 years@Vinesh - I have just look this answer, but not solve my problem! I want that cell color change after the user modify cell value, and the cell must maintain this color!
-
Matteo Codogno almost 12 years@trashgod - can you show me how to do?
-
kleopatra almost 12 yearsare you sure that you really want to track direct user changes (via editing) to the data? Typically in a load/save data context it doesn't really matter were the change originated (direct edit, progammatic change, indirect user action, wheather change ... :-), as long as the changed data is saved.
-
-
kleopatra almost 12 yearshmm .. a bit on the borderline: a) typically a cellEditor must not change the model (alleviated here because the state is not really a model-property, which is another borderline story :-) b) should call super before changing the state (because it shouldn't if super returned false
-
trashgod almost 12 years@kleopatra: I was hoping for your insight; thank you. a) I agree about the
CellEditor
; it should be aRow.class
editor, notString.class
; it'll experiment. b)super
invokesdelegate.stopCellEditing()
, which unconditionally returnstrue
afterfireEditingStopped()
, which invalidatestable.getEditingRow()
. -
kleopatra almost 12 yearsahh (or better beeee :-).. good point! But then, super class behaviour is an implementation detail not to be relied on. A way out (to prevent setting the state in case super refused to stop), grab the editingRow before, message super, and set the state (or not) after.