JButton inside JTable Cell

Hi guys, I really need some help......

I am working with JTable, and would like to show a JButton inside the last table column... This button will perform some actions when the user click on it.

But I don't know how to solve some problems. I already create the table model, renderer, cell editor, my fired event are almos right, but I really think that are a lot to do until finish it.

Right now, I am with the followign problems:

1) How can I do to the button (inside the table) fire an event every time the user click on it, instead to force the user to click on button and press the enter?!!?!?

2) I would like to made the button disappear after the user click on it (or force it do setEnabled(false) to prevent user repeat the same action. To solve it I set the CellEditor component to not visible when the stoppingEdit is finished, but whem the user click on another table row my old button becomes visible automaticaly. How can I fix this things?!!?

ps: I know that it is a very complicated thing, and propably will need a lot of source code, so if anyone knows a good tutorial it will be welcome too.

Thanks all

[1168 byte] By [giscard_aiobaa] at [2007-10-2 4:37:54]
# 1

Hi guys, I am here again!!!! I think a lot of about the problem commented before and fix somethings, but at each time I gotted some "bug problems"...

Just to comment, every time I press a addButton I add a row into my model

model.addRow(...)

and when I press the clearButton I remove all rows from my table. But some times neither all rows are removed and the rows are not add at a logical order, sometimes the rows jump from 0 to 3, and the clear just remove some rows.

I sure it is not a java languange bug, but I really are lost, because I don't find at any place how to understand how tables, models, renderer, editors, and anything else worlks....

Please help. Thanks

giscard_aiobaa at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 2

> But some times neither all rows are removed

Use DefaultTableModel.setRowCount(0);

> 2) I would like to made the button disappear after the user click on it (or

> force it do setEnabled(false) to prevent user repeat the same action.

From my example below you could set the value of the cell to "". Then you could override the isCellEditable() method to return false when the "button cell" contains "".

Here is some example code I've been playing with that may (or may not) give you some ideas:

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.table.*;

public class TableButton3 extends JFrame

{

public TableButton3()

{

String[] columnNames = {"Date", "String", "Integer", "Decimal", ""};

Object[][] data =

{

{new Date(), "A", new Integer(1), new Double(5.1), "Delete0"},

{new Date(), "B", new Integer(2), new Double(6.2), "Delete1"},

{new Date(), "C", new Integer(3), new Double(7.3), "Delete2"},

{new Date(), "D", new Integer(4), new Double(8.4), "Delete3"}

};

DefaultTableModel model = new DefaultTableModel(data, columnNames);

JTable table = new JTable( model )

{

// Returning the Class of each column will allow different

// renderers to be used based on Class

public Class getColumnClass(int column)

{

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

}

};

JScrollPane scrollPane = new JScrollPane( table );

getContentPane().add( scrollPane );

// Create button column

ButtonColumn buttonColumn = new ButtonColumn(table, 4);

}

public static void main(String[] args)

{

TableButton3 frame = new TableButton3();

frame.setDefaultCloseOperation( EXIT_ON_CLOSE );

frame.pack();

frame.setVisible(true);

}

class ButtonColumn extends AbstractCellEditor

implements TableCellRenderer, TableCellEditor, ActionListener

{

JTable table;

JButton renderButton;

JButton editButton;

String text;

public ButtonColumn(JTable table, int column)

{

super();

this.table = table;

renderButton = new JButton();

editButton = new JButton();

editButton.setFocusPainted( false );

editButton.addActionListener( this );

TableColumnModel columnModel = table.getColumnModel();

columnModel.getColumn(column).setCellRenderer( this );

columnModel.getColumn(column).setCellEditor( this );

}

public Component getTableCellRendererComponent(

JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

{

if (hasFocus)

{

renderButton.setForeground(table.getForeground());

renderButton.setBackground(UIManager.getColor("Button.background"));

}

else if (isSelected)

{

renderButton.setForeground(table.getSelectionForeground());

renderButton.setBackground(table.getSelectionBackground());

}

else

{

renderButton.setForeground(table.getForeground());

renderButton.setBackground(UIManager.getColor("Button.background"));

}

renderButton.setText( (value == null) ? "" : value.toString() );

return renderButton;

}

public Component getTableCellEditorComponent(

JTable table, Object value, boolean isSelected, int row, int column)

{

text = (value == null) ? "" : value.toString();

editButton.setText( text );

return editButton;

}

public Object getCellEditorValue()

{

return text;

}

public void actionPerformed(ActionEvent e)

{

fireEditingStopped();

System.out.println( e.getActionCommand() + " : " + table.getSelectedRow());

}

}

}

camickra at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 3
Very thanks, Just to report another interested users, my big mistake was only implements the interfaces editor and renderer and don't extends any abstract model......So without a default implementation I implement all method by myself and they had bugs.Thanks.
giscard_aiobaa at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 4
I want to hide the buttons, so I used setVisible(false);This doesn't worked out, could anyone help me?
RubenVerweija at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 5
did you try to refresh the JTable or to repaint the scrollpane (if you have any) ?Message was edited by: ProZ
ProZa at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 6
I refreshed my scrollpane and it works!Thanks a lot!
RubenVerweija at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 7

iam facing the same problem you faced regarding the Jbutton in Jtable.

I would like to made the button disappear after the user click on it (or force it do setEnabled(false)......

how did u fixed this ...will be more help full if you replied me .

thanks in advance.

sathish.

sathishsa at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 8

Just use:

button.setVisible(false);

to hide your button, then refresh your scroll pane and table and use:

this.repaint();

If it still doesn't work. If your problem is still unsolved, remove the scroll pane and JTable and make some new ones. (not a very good solution, this will slow down your program...)

I hope I helped you out a little bit!

RubenVerweija at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 9

thanks ,. i tried the option and it worked well.

I have some other problem also , for some time i am setting the "button.SetEnabled(false); ", but when the user click on another table row my old button becomes visible automatically. How can I fix this things?!!?. Until i click the another button in that column , the button should be in disable state..how to make this work. ?

and also the action performed is called only once and after that it is not getting called if i use the setEnable(false) for the button .

really i have tried several options ...nothing helped.

sathishsa at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 10

hi camickr,

First of all thanks! Your code helps me a lot! :) Clear and fast, as I love its!

Do know that it's an old topic, but I've got a simple question. I'm not a swing expert, so hope this question would not sound stupid...

I pay attention to your code, and here is what I've concluded: (do know that it was a simple example)

you are using two components, since the TableCellRenderer and TableCellEditor are implemented in the same class: an editButton and a renderButton (for each method)

If we're digging into a set of components, such as a JPanel in a cell that contains a lot of labels, buttons and so on, does it mean that we must have, actually, two instances of each component? (one by interface, since our class implements each of it)

If my preceding assertion is true, what do you think of this?

columnModel.getColumn(column).setCellRenderer( this );

columnModel.getColumn(column).setCellEditor( this );

// maybe this could do the trick (of course outside the ButtonColumn class

columnModel.getColumn(column).setCellRenderer( new ButtonColumn());

columnModel.getColumn(column).setCellEditor( new ButtonColumn() );

Have a good day!

Mathieu.

math_a at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 11

This solution works beautifully - I only have one question:

I've modified some of my cells to support multi-line editing (as seen here: http://www.javaspecialists.co.za/archive/newsletter.do?issue=106&locale=en_US)

This now causes my button cells to expand to the full height of the row. I've tried setting the maximum size on the buttons, but that has no effect - it seems what the JTable does is take a snapshot of the renderer and expand the image to fill the cell, so setting the button size has no effect.

Anyone have any thoughts on how I can restrict the button height? If I happen to have a row with several lines, I don't want the button being any bigger than it thinks it should be (e.g., the button should only be one line).

theblueeyza at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 12
All components use a renderers are set to the size of the cell. So you could try using a panel as the renderer. Then add your button to the panel. That was the panel gets resized to the size of the cell and the button should stay the correct size.
camickra at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...
# 13
Perfect! I wrapped both the renderButton and editButton in a JPanel and returned those for the render/edit components instead, and I get a button in the cell that's the size I want.Thanks again!!
theblueeyza at 2007-7-16 0:10:52 > top of Java-index,Desktop,Core GUI APIs...