displaying icon in JButton table cell

hi,

I have a JTable with JButtons in first column, the second with

check boxes. The table should work in such a way that when a row is selected,

the icon is displayed (same as you have in MS Access when you design table data).

Now, when I click on the button, it displays the desired behavior, but when I

select the next column, the icon is not displayed. Why is this behavior seen?

Can anyone give me suggestions to get the desired behavior?

Thanks in advance.

The sample code is as given below:

import java.awt.Component;

import java.awt.Dimension;

import javax.swing.DefaultCellEditor;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JCheckBox;

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.TableCellRenderer;

import com.uisupport.GIFConstants;

/**

* This class creates a condition table

*

* @author

*

*/

publicclass SelCriteriaConditionTableextends JScrollPane{

private JTable tblSelection =null;

private DefaultTableModel tblSelectionModel =null;

private String[] values ={"And","Or"};

private String[] colNames =new String[]{"","And/Or","Conditions"};// null;

private Object lblData[][] ={{new JButton(),"And",""},

{new JButton(),"Or",""}};// null;

/**

* Constructor

*/

public SelCriteriaConditionTable(DefaultTableModel tblSelectionModel){

this.tblSelectionModel = tblSelectionModel;

init();

}

void init(){

tblSelectionModel =new DefaultTableModel();

tblSelectionModel.setDataVector(lblData, colNames);

tblSelection =new JTable(tblSelectionModel);

tblSelection.getColumnModel().getColumn(0).setCellRenderer(

new CWTableButtonRenderer());

tblSelection.getColumnModel().getColumn(0).setCellEditor(

new ButtonEditor(new JCheckBox()));

tblSelection.getColumnModel().getColumn(1).setCellRenderer(

new CWComboBoxRenderer(values));

tblSelection.getColumnModel().getColumn(1).setCellEditor(

new CWComboBoxEditor(values));

tblSelection.setShowGrid(false);

this.getViewport().add(tblSelection);

}

class ButtonEditorextends DefaultCellEditor{

protected JButton button;

ImageIcon leftButtonIcon =new ImageIcon(GIFConstants.getArrowIcon()

.getImage());

public ButtonEditor(JCheckBox checkBox){

super(checkBox);

button =new JButton("", leftButtonIcon);

button.setOpaque(true);

}

public Component getTableCellEditorComponent(JTable table,

Object value,boolean isSelected,int row,int column){

button.setIcon(leftButtonIcon);

return button;

}

}

/**

* TableCellRenderer for the JComboBox

*

* @author

*

*/

publicclass CWComboBoxRendererextends JComboBoximplements

TableCellRenderer{

/**

* Constructor

*

* @param items -

*The combo box items

*/

public CWComboBoxRenderer(String[] items){

super(items);

}

/**

* Returns the component used for drawing the cell

*/

public Component getTableCellRendererComponent(JTable table,

Object value,boolean isSelected,boolean hasFocus,int row,

int column){

if (isSelected){

setForeground(table.getSelectionForeground());

super.setBackground(table.getSelectionBackground());

}else{

setForeground(table.getForeground());

setBackground(table.getBackground());

}

// Select the current value

setSelectedItem(value);

returnthis;

}

}

/**

* Combo box editor for the table cell

*

* @author

*/

class CWComboBoxEditorextends DefaultCellEditor{

/**

* Constructor

*

* @param items -

*The items in the combo box

*/

public CWComboBoxEditor(String[] items){

super(new JComboBox(items));

}

}

/**

* Button renderer for the table cell

*

* @author

*

*/

publicclass CWTableButtonRendererextends JButtonimplements

TableCellRenderer{

/**

* Constructor

*

*/

public CWTableButtonRenderer(){

}

/**

* Returns the component used for drawing the cell

*/

public Component getTableCellRendererComponent(JTable table,

Object value,boolean isSelected,boolean hasFocus,int row,

int column){

returnthis;

}

}

staticvoid createAndShowGUI(){

// Make sure we have nice window decorations.

// JFrame.setDefaultLookAndFeelDecorated(true);

// Create and set up the window.

JFrame frame =new JFrame("display ");

System.out.println(frame.getSize());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

DefaultTableModel tblSelModel =new DefaultTableModel();

SelCriteriaConditionTable dt =new SelCriteriaConditionTable(

tblSelModel);

frame.getContentPane().add(dt);

// Display the window.

frame.pack();

frame.setSize(new Dimension(400, 200));

frame.setVisible(true);

System.out.println(frame.getSize());

}

/**

* @param args

*/

publicstaticvoid main(String[] args){

// TODO Auto-generated method stub

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

publicvoid run(){

createAndShowGUI();

}

});

}

}

[11096 byte] By [seemap123a] at [2007-10-3 3:03:22]
# 1
You need code in the renderer, not the editor:setIcon( isSelected ? leftButtonIcon : null );
camickra at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 2

camickr, Thanks a lot. It worked !

I had another question. I would like a different icon(an asterisks just like in MSaccess while designing the table) displayed in the last row JButton of the table. This would indicate that the row can be populated with values. If that row is selected the icon has to change to the first icon and the next row must have the asterisks. How do I go about. Any help or suggestions please ?

Thanks in advance.

seemap123a at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 3

Its just another test in the renderer:

if (lastRow)

setIcon( toTheLastRowIcon)

setIcon( isSelected ? leftButtonIcon : null );

The you override the isCellEditable(..) method to only return true when the cell is on the last row.

camickra at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 4

camickr, Thanks again for the help. It worked.

The altered part of the code after making changes is as below:

void init() {

tblSelection = new JTable();

tblSelectionModel = new DefaultTableModel(){

public boolean isCellEditable(int row,

int column){

if(column == 0){

if(row == tblSelection.getRowCount()-1){

return true;

}

return false;

}else{

return true;

}

}

};

tblSelectionModel.setDataVector(lblData, colNames);

tblSelection.setModel(tblSelectionModel);

tblSelection.getColumnModel().getColumn(0).setCellRenderer(

new CWTableButtonRenderer());

tblSelection.getColumnModel().getColumn(1).setCellRenderer(

new CWComboBoxRenderer(values));

tblSelection.getColumnModel().getColumn(1).setCellEditor(

new CWComboBoxEditor(values));

tblSelection.setShowGrid(false);

this.getViewport().add(tblSelection);

}

/**

* Button renderer for the table cell

*

* @author

*

*/

class CWTableButtonRenderer extends JButton implements

TableCellRenderer {

ImageIcon leftButtonIcon = new ImageIcon("arrow.gif");

ImageIcon lastRowButtonIcon = new ImageIcon("asterisks.gif");

/**

* Constructor

*

*/

public CWTableButtonRenderer() {

}

/**

* Returns the component used for drawing the cell

*/

public Component getTableCellRendererComponent(JTable table,

Object value, boolean isSelected, boolean hasFocus, int row,

int column) {

if(row == table.getRowCount()-1){

setIcon(lastRowButtonIcon);

}

else

{

setIcon(isSelected ? leftButtonIcon : null);

}

return this;

}

}

Now, if I do not have any data in the table, then I want just one row in the table to be empty with only the first column having the button with the asterisks icon and no combo box in the second column. This row should not be editable

If the table gets populated with the data(i.e rows get populated), then the second column has to display the combo box, the selected row should have the button with the arrow icon. And now an empty row without data and combo box must be displayed(i.e filled rows +1) having the asterisks icon on the button indicating that the row is the next available row to be populated and this row should not be editable.

Can you please help? Thanks again.

seemap123a at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 5

Override the getCellRenderer(..) and / or getCellEditor(...) methods.

if the row is the last row you return the string renderer otherwise you return the comboBox renderer

if (lastRow and column2)

return getDefaultRenderer(Object.class);

else

return super.getCellRenderer(...);

camickra at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 6

camickr, , I tired . But, could not get it to work. I want to know what is wrong.

The code is as below.

class CWComboBoxRenderer1 extends CWComboBoxRenderer{

public CWComboBoxRenderer1(String[] items) {

super(items);

}

public Component getTableCellRendererComponent(JTable table,

Object value, boolean isSelected, boolean hasFocus, int row,

int column) {

if(row == table.getRowCount()-1 && column == 1){

return getDefaultRenderer(Object.class);

} else {

return super.getCellRenderer(table, value, isSelected, hasFocus, row, column);

}

//return this;

}

}

seemap123a at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 7
Override the getCellRenderer(...) method of JTable.
camickra at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 8

thanks again. I tried this, but does not work. Am I wrong somewhere ?

The code is:

void init() {

tblSelection = new JMyTable();

tblSelectionModel = new DefaultTableModel(){

public boolean isCellEditable(int row,

int column){

if(column == 0){

if(row == tblSelection.getRowCount()-1){

return true;

}

return false;

}else{

return true;

}

}

};

tblSelectionModel.setDataVector(lblData, colNames);

tblSelection.setModel(tblSelectionModel);

tblSelection.getColumnModel().getColumn(0).setCellRenderer(new CWTableButtonRenderer());

tblSelection.getColumnModel().getColumn(1).setCellRenderer(

new CWComboBoxRenderer(values));

tblSelection.getColumnModel().getColumn(1).setCellEditor(

new CWComboBoxEditor(values));

tblSelection.setShowGrid(false);

this.getViewport().add(tblSelection);

}

class JMyTable extends JTable{

public TableCellRenderer getCellRenderer(int row, int column) {

if (row == this.getRowCount()-1 && column == 1) {

return getDefaultRenderer(String.class);

}

return super.getCellRenderer(row,column);

}

};

/**

* TableCellRenderer for the JComboBox

*

* @author

*

*/

class CWComboBoxRenderer extends JComboBox implements

TableCellRenderer {

/**

* Constructor

*

* @param items -

*The combo box items

*/

public CWComboBoxRenderer(String[] items) {

super(items);

}

/**

* Returns the component used for drawing the cell

*/

public Component getTableCellRendererComponent(JTable table,

Object value, boolean isSelected, boolean hasFocus, int row,

int column) {

if (isSelected) {

setForeground(table.getSelectionForeground());

super.setBackground(table.getSelectionBackground());

} else {

setForeground(table.getForeground());

setBackground(table.getBackground());

}

// Select the current value

setSelectedItem(value);

return this;

}

}

Message was edited by:

seemap123

seemap123a at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 9
> I tried this, but does not work. Am I wrong somewhere ?Well, I guess I don't understand the question. I tried to give you some ideas on how you can change the renderer or editor that is used for a given row and column. I can't help you with the exact logic.
camickra at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...
# 10
thanksMessage was edited by: seemap123
seemap123a at 2007-7-14 20:53:16 > top of Java-index,Desktop,Core GUI APIs...