How to get a JTable cell to react on data changes on another column's cell?

Hi!

I would really appreciate urgent help on this matter:

I have a JTable that has two columns and two rows. The left column is a column for Integers and the right column is a column for Colors and that column's every cell's background is filled with some color.

When the user clicks a cell in the right column (the Color column), he gets a JColorChooser-dialog where he can pick the color he wants. After he has picked the color, that cell's background color changes to the color the user picked. This works fine.

But what I also would like, is that when the user changes the color in a cell,

the left column's (the Integer column) cell at the same row would as well change its background color to the same color the user picked. How should this be done? I've really tried everything, but I just can't get the Integer column's cells to change their background color based on which color I choose on the color column's cells.

Here's the code, though it's rather long. I assume that in the class OwnTableCellRenderer I should set the cell's background color to be the same as the user picked in the other cell from the JColorChooser. But how should this be done?

publicclass MyTableextends JPanelimplements TableModelListener{

public MyTable(){

super(new GridLayout(1,0));

JTable table =new JTable(new MyTableModel());

table.setPreferredScrollableViewportSize(new Dimension(500, 70));

JScrollPane scrollPane =new JScrollPane(table);

//Set up renderer and editor for the Color column and

//renderer for the Integer column:

table.setDefaultRenderer(Color.class,

new ColorRenderer(true));

table.setDefaultEditor(Color.class,

new ColorEditor());

table.setDefaultRenderer(Integer.class,new OwnTableCellRenderer());

table.getModel().addTableModelListener(this);

add(scrollPane);

}

publicvoid tableChanged(TableModelEvent e){

// Here I can detect if a cell from the Color column

// gets its background color changed and to what

// color. But how could I set that if the change is

// made, the Integer column's cell's background color

// is changed to the same color as well?

int row = e.getFirstRow();

int column = e.getColumn();

TableModel model = (TableModel)e.getSource();

String columnName = model.getColumnName(column);

Object data = model.getValueAt(row, column);

}

class MyTableModelextends AbstractTableModel{

private String[] columnNames ={"Integer",

"Color"};

private Object[][] data ={

{new Integer(5), Color.blue,

new Integer(2), Color.green}

};

publicint getColumnCount(){

return columnNames.length;

}

publicint getRowCount(){

return data.length;

}

public String getColumnName(int col){

return columnNames[col];

}

public Object getValueAt(int row,int col){

return data[row][col];

}

public Class getColumnClass(int c){

return getValueAt(0, c).getClass();

}

publicboolean isCellEditable(int row,int col){

returntrue;

}

}

privatestaticvoid createAndShowGUI(){

JFrame frame =new JFrame("MyTable");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JComponent newContentPane =new MyTable();

newContentPane.setOpaque(true);

frame.setContentPane(newContentPane);

frame.pack();

frame.setVisible(true);

}

publicstaticvoid main(String[] args){

javax.swing.SwingUtilities.invokeLater(new Runnable(){

publicvoid run(){

createAndShowGUI();

}

});

}

}

publicclass ColorEditorextends AbstractCellEditor

implements TableCellEditor,

ActionListener{

Color currentColor;

JButton button;

JColorChooser colorChooser;

JDialog dialog;

protectedstaticfinal String EDIT ="edit";

public ColorEditor(){

//Set up the editor (from the table's point of view),

//which is a button.

//This button brings up the color chooser dialog,

//which is the editor from the user's point of view.

button =new JButton();

button.setActionCommand(EDIT);

button.addActionListener(this);

button.setBorderPainted(false);

//Set up the dialog that the button brings up.

colorChooser =new JColorChooser();

dialog = JColorChooser.createDialog(button,

"Pick a color",

true,//modal

colorChooser,

this,//OK button handler

null);//no CANCEL button handler

}

/**

* Handles events from the editor button and from

* the dialog's OK button.

*/

publicvoid actionPerformed(ActionEvent e){

if (EDIT.equals(e.getActionCommand())){

//The user has clicked the cell, so

//bring up the dialog.

button.setBackground(currentColor);

colorChooser.setColor(currentColor);

dialog.setVisible(true);

//Make the renderer reappear.

fireEditingStopped();

}else{//User pressed dialog's "OK" button.

currentColor = colorChooser.getColor();

}

}

//Implement the one CellEditor method that AbstractCellEditor doesn't.

public Object getCellEditorValue(){

return currentColor;

}

//Implement the one method defined by TableCellEditor.

public Component getTableCellEditorComponent(JTable table,

Object value,

boolean isSelected,

int row,

int column){

currentColor = (Color)value;

return button;

}

}

publicclass ColorRendererextends JLabel

implements TableCellRenderer{

Border unselectedBorder =null;

Border selectedBorder =null;

boolean isBordered =true;

public ColorRenderer(boolean isBordered){

this.isBordered = isBordered;

setOpaque(true);//MUST do this for background to show up.

}

public Component getTableCellRendererComponent(

JTable table, Object color,

boolean isSelected,boolean hasFocus,

int row,int column){

Color newColor = (Color)color;

setBackground(newColor);

if (isBordered){

if (isSelected){

if (selectedBorder ==null){

selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,

table.getSelectionBackground());

}

setBorder(selectedBorder);

}

else{

if (unselectedBorder ==null){

unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,

table.getBackground());

}

setBorder(unselectedBorder);

}

}

returnthis;

}

}

publicclass OwnTableCellRendererextends DefaultTableCellRenderer{

public Component getTableCellRendererComponent

(JTable table, Object value,boolean isSelected,

boolean hasFocus,int row,int column)

{

Component cell = super.getTableCellRendererComponent

(table, value, isSelected, hasFocus, row, column);

if( valueinstanceof Integer )

{

Integer amount = (Integer) value;

if( amount.intValue() > 0 )

{

//cell.setBackground(SOMETHING); // This cell's bg-color should

// be the same as the user picked

// in the other cell from the

// JColorChooser. But how?

setOpaque(true);

}

}

return cell;

}

}

[14489 byte] By [Dasha] at [2007-11-26 16:25:19]
# 1

1) Don't extend AbstractTableModel. The DefaultTableModel will be able to store your data without customization.

2) The easiest way to set the background of a cell that is dependent on a value in another cell is to override the prepareRenderer(...) method. Here is a simple example:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=610474

In your case you would simply set the background to the value of the second column.

camickra at 2007-7-8 22:49:21 > top of Java-index,Desktop,Core GUI APIs...
# 2

> 2) The easiest way to set the background of a cell

> that is dependent on a value in another cell is to

> override the prepareRenderer(...) method. Here is a

> simple example:

>

> http://forum.java.sun.com/thread.jspa?forumID=57&threa

> dID=610474

>

> In your case you would simply set the background to

> the value of the second column.

Ok, I checked the example you gave, but I'm still not able to write that override for the prepareRenderer method and to get it work. Also I'm not quite sure how to set the background color of a cell to the value of another cell.

Would it be possible to show me how to include those things in my code so that it works and does what it should?

Dasha at 2007-7-8 22:49:21 > top of Java-index,Desktop,Core GUI APIs...
# 3

> Also I'm not quite sure how to set the background color of a cell to the value of another cell.

You don't. Each cell is not a real component, so it doesn't have a background color. The background of the renderer is set when the cell is painted, then the background of the renderer is reset when the next cell is painted.

You store the color as data in the second column. My example shows you how to get data from a column in the TableModel. So you simply get the data, cast it to a Color Object and use it as the background of the column you wish to customize.

Use my example as the starting point. Make the required changes. If you still have problems then post your code.

camickra at 2007-7-8 22:49:21 > top of Java-index,Desktop,Core GUI APIs...
# 4
Yep, got that working now. It really was an easy way to solve this problem after all. Big thanks!
Dasha at 2007-7-8 22:49:21 > top of Java-index,Desktop,Core GUI APIs...