I am adding Jbutton to a table by extendibg AbstractCellEditor class. But on click of button the text doesnt change from "Start" to "Stop" .here is the class i implemented
public class ButtonEditor1 extends AbstractCellEditor implements
TableCellEditor,ActionListener,TableCellRenderer{
JButton btnSTART = new JButton("START");
private JTable table ;
public ButtonEditor1(JTable table){
this.table = table;
btnSTART.addActionListener(this);
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
return btnSTART;
}
public Object getCellEditorValue() {
// TODO Auto-generated method stub
return btnSTART;
}
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
if(btnSTART.getText().equals("START")){
if(row != -1){
btnSTART.setText("STOP");
}
}else if(btnSTART.getText().equals("STOP")){
if(row != -1){
btnSTART.setText("START");
}
}
fireEditingStopped();
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return btnSTART;
}
}
what i am doing wrong .. I have a Model class which takes the column as JButton and have overriden the method setValueAt and getValueAt.
A JTable uses renderers to display data. Once you click on the cell using the button as an editor, the button editor is invoked for a split second, then the cell is placed back in rendering mode. So if you want to change the text you change the value in the model.
Related
I 'm a Java beginner.
I create an application with a JTable which is populated with a database.
In my database I have some 'news'. In my JTable I display titles of 'news' and when an user click on a row, it display a popup with the right contents of the news.
But I want to colorize the cell which are 'read' when the user clicked on it.
I use my own TableModel.
I hope I'm clear...
If I need to put some code, tell me what please...
public class JTableTest extends JFrame {
private JTable table;
private int col;
private int rowz;
/**
* Create the frame.
*/
public JTableTest() {
initComponents();
}
private void initComponents() {
/** any other components */
table = new JTable();//create the table
table.setDefaultRenderer(Object.class, new CustomModel());
table.addMouseListener(new CustomListener());
}
public class CustomListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent arg0) {
super.mouseClicked(arg0);
//get the clicked cell's row and column
rowz = table.getSelectedRow();
col = table.getSelectedColumn();
// Repaints JTable
table.repaint();
}
}
public class CustomModel extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Color c = Color.WHITE;//define the color you want
if (isSelected && row == rowz & column == col)
c = Color.GREEN;
label.setBackground(c);
return label;
}
}
}
Found this example of how to get the table cell on mouseClick: http://codeprogress.com/java/showSamples.php?index=52&key=JTableValueofSelectedCell
You can use this to get the selected row and column.
Then you need to create a custom TableCellRenderer, possibly as an inner class so that it can use the selected row and column data and set the background of the cell to your highlighted color
I have a table with a checkbox column, I am able to show the table like i want and I make editable just the column where the checkbox is placed. The problem is when I select the checkbox the render paint in the right way the checkbox but the value in the tablemodel isn't changed, this value just change until i give click in another checkbox, always the last checkbox that I choose doesn't reflects his value in the TableModel. The classes that I am using are:
Checkcell
class CheckCell extends DefaultCellEditor implements TableCellRenderer{
private JComponent component = new JCheckBox();
private boolean value = false;
public CheckCell() {
super(new JCheckBox());
}
#Override
public Object getCellEditorValue() {
return ((JCheckBox)component).isSelected();
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
( (JCheckBox) component).setBackground( new Color(200,200,0) );
boolean b = ((Boolean) value).booleanValue();
( (JCheckBox) component).setSelected( b );
( (JCheckBox) component).setHorizontalAlignment(SwingConstants.CENTER);
return ( (JCheckBox) component);
}
#Override
public boolean stopCellEditing() {
value = ((Boolean)getCellEditorValue()).booleanValue() ;
((JCheckBox)component).setSelected( value );
return super.stopCellEditing();
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value == null)
return null;
return ( (JCheckBox) component );
}
}
CheckRender
class CheckRender extends JCheckBox implements TableCellRenderer {
private JComponent component = new JCheckBox();
public CheckRender() {
setOpaque(true);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
((JCheckBox) component).setBackground( new Color(0,200,0));
boolean b = ((Boolean) value).booleanValue();
((JCheckBox) component).setSelected(b);
((JCheckBox) component).setHorizontalAlignment(SwingConstants.CENTER);
return ((JCheckBox) component);
}
}
My Model
class DynaTableModel extends DefaultTableModel {
public DynaTableModel() {
super();
}
public DynaTableModel(final DynaTableBean dynaBean) {
super(dynaBean.getContent(), dynaBean.getHeaders());
}
#Override
public boolean isCellEditable(int row, int col) {
if (col == 0)
{
return true;
} else {
return false;
}
}
#Override
public void setValueAt(Object value, int row, int column) {
super.setValueAt(value, row, column);
}
Could you help me with this? what is missing me to change the value in the jtable when this change in the checkbox.
I am new in java and I think that there are something that is missing me.
Thanks in advanced.
Being a little more explicity, when I ticked the checkbox and I tried to recover the value from the TableModel the value is wrong by example if I ticked the first checkbox and I tried to recover the value using:
valor = (Boolean) tablemodel.getValueAt(i, 0);
I am getting false when this should be true, but if I check the first checkbox and later the second one the value of the first checkbox now is fine(true) but the second is still false is a kind of bug but I don't find the way to avoid this.
Someone knows how to avoid this.
I have a table with a checkbox column, I am able to show the table
like i want and I make editable just the column where the checkbox is
placed. The problem is when I select the checkbox the render paint in
the right way the checkbox but the value in the tablemodel isn't
changed, this value just change until i give click in another
checkbox, always the last checkbox that I choose doesn't reflects his
value in the TableModel
JTable has built in support for JCheckBox as TableCellRenderer and Editor
Boolean value represens JCheckBox in XxxTableModel, you would need to put there true or false (1st column)
override public Class getColumnClass(int c) {,
I have a jTable that has a jComboBox column. However I had an issue where I couldn't get the jComboBox to show unless you first click on it. Other people have had the same problem, it seems.
So I then learned I needed to make a CellRenderer besides the CellEditor. And so I did...
public class MyCellRenderer extends JComboBox<CustomItem> implements TableCellRenderer{
#Override
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());
}
setSelectedItem(value);
return this;
}
}
By the way, I am also using a ComboBoxRenderer because I need it to display text while containing an item.
public class MyComboBoxRenderer extends BasicComboBoxRenderer{
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus){
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value != null){
CustomItem customItem = (CustomItem) value;
setText(customItem.getText());
}
if(index == -1){
CustomItem customItem = (CustomItem) value;
setText("" + customItem.getText());
}
return this;
}
}
And now it works! It does show the jComboBox in my jTable by default BUT now each jComboBox on each row has permanent focus! And only the first one I click on actually displays the menu. The rest are 'selected' but they do not respond.
Edit: Here is how I create the table.
private void initializeTable(){
JTable jTable1 = new javax.swing.JTable();
DefaultTableModel dtm = new DefaultTableModel();
dtm.addColumn("one");
dtm.addColumn("two");
dtm.addColumn("three");
jTable1.setModel(dtm);
JComboBox<CustomItem> items = new JComboBox<>();
items.setRenderer(new MyComboBoxRenderer());
items.add(new CustomItem(1, "soup", false);
items.add(new CustomItem(33, "sauce", false);
items.setSelectedIndex(0);
jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(items));
jTable1.getColumnModel().getColumn(2).setCellRenderer(new MyCellRenderer());
}
I am having a JTable with two columns. In the second column there are different editors (JTextField, JComboBox and CheckComboBox), in each row one. This works fine so far however I have implemented a reset option which changes the whole JTable back to the original state (resets all changes).
The problem I am facing now is that when I programmatical change the index of a ComboBox with setSelectedIndex I see no result in the GUI although the model fires its change with fireTableDataChanged and is also receivied by an TableModelListener of the Table. When I lookup the changed ComboBox I also get the correct index however it is not shown in the GUI. I also tried the methods revalidate, updateUI and repaint wihtout any change.
The problem might lay in the architecture of it (maybe the Renderer?). Here is my Editor/Renderer class.
class VEachRowEditor implements TableCellEditor, TableCellRenderer {
protected Hashtable<Integer, TableCellEditor> editors;
protected TableCellEditor editor, defaultEditor, renderer;
JTable table;
VEachRowEditorManager rowmanager;
public VEachRowEditor(JTable table, VEachRowEditorManager rowmanager) {
this.table = table;
editors = new Hashtable<Integer, TableCellEditor>();
defaultEditor = new DefaultCellEditor(new JTextField());
this.rowmanager = rowmanager;
}
public void setEditorAt(int row, TableCellEditor editor) {
if (editor instanceof DefaultCellEditor)
((DefaultCellEditor) editor).setClickCountToStart(1);
editors.put(new Integer(row), editor);
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
editor = (TableCellEditor) editors.get(new Integer(row));
if (editor == null) {
editor = defaultEditor;
}
return editor.getTableCellEditorComponent(table, value, isSelected,
row, column);
}
public Object getCellEditorValue() {
return editor.getCellEditorValue();
}
public final boolean stopCellEditing() {
return editor.stopCellEditing();
}
public void cancelCellEditing() {
editor.cancelCellEditing();
}
public boolean isCellEditable(EventObject anEvent) {
selectEditor((MouseEvent) anEvent);
return editor.isCellEditable(anEvent);
}
public void addCellEditorListener(CellEditorListener l) {
editor.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l) {
editor.removeCellEditorListener(l);
}
public boolean shouldSelectCell(EventObject anEvent) {
selectEditor((MouseEvent) anEvent);
return editor.shouldSelectCell(anEvent);
}
protected void selectEditor(MouseEvent e) {
int row;
if (e == null) {
row = table.getSelectionModel().getAnchorSelectionIndex();
} else {
row = table.rowAtPoint(e.getPoint());
}
editor = (TableCellEditor) editors.get(new Integer(row));
if (editor == null) {
System.out.println(editor);
editor = defaultEditor;
}
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
renderer = (TableCellEditor) editors.get(new Integer(row));
if (renderer == null) {
renderer = defaultEditor;
}
return renderer.getTableCellEditorComponent(table, value, isSelected,
row, column);
}
}
Is the getTableCellEditorComponent wrong?
The rowmanager holds all the JComboBoxes and CheckComboBoxes with all the models.
when I programmatical change the index of a ComboBox with setSelectedIndex I see no result in the GUI
Renderer and editers just display the data in the model. Don't reset the editor component.
Reset the data in the model. ie>
table.setValueAt(...); // or
table.getModel().setValueAt(...);
I need to display an image in one of jTable cells.
I wrote this:
class ImageRenderer extends DefaultTableCellRenderer {
JLabel lbl = new JLabel();
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
lbl.setText((String) value);
lbl.setIcon(new ImageIcon("/home/ariyan/Desktop/71290452.jpg"));
return lbl;
}
}
and then used it as this:
jTable1.getColumn(0).setCellRenderer(new ImageRenderer());
But this didn't work
How I can do that?
Thanks
JTable already provides a default renderer for images. You just need to tell the table what type of data is contained in each column and it will choose the best renderer:
a) override the getColumnClass() method of the JTable or the TableModel to return the class of data in the column. In this case you should return an Icon.class.
b) add an ImageIcon to the table model.
Now the JTable will use the default Icon renderer for that column.
Hmm: jTable1.getColumnModel().getColumn(0).setCellRenderer(new ImageRenderer()); perhaps?
Here's the relevant extract of some quick test code I put together to quickly verify my guess. It displays icons from a folder (it assumes all files in a folder are icons, so you should test it with something like an XDG icon theme sub directory). Install table model first then add the cell renderer on the columns:
class Renderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent (JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row, int column) {
if(isSelected) {
this.setBackground(table.getSelectionBackground());
this.setForeground(table.getSelectionForeground());
}
else {
this.setBackground(table.getBackground());
this.setForeground(table.getForeground());
}
if(column == 0) {
this.setText(list[row]);
}
else {
// edit as appropriate for your icon theme
this.setIcon(new ImageIcon("/usr/share/icons/default.kde4/16x16/apps/"+list[row]));
}
return this;
}
}
class Model extends DefaultTableModel {
#Override
public boolean isCellEditable (int row, int column) {
return false;
}
#Override
public Object getValueAt (int row, int column) {
return list[row];
}
#Override
public int getRowCount () {
return list.length;
}
#Override
public int getColumnCount () {
return 2;
}
#Override
public String getColumnName (int column) {
return column == 0? "Name" : "Preview";
}
#Override
public Class<?> getColumnClass (int columnIndex) {
return String.class;
}
}
// edit base directory as appropriate for your icon theme of choice
static String[] list=new File("/usr/share/icons/default.kde4/16x16/apps/").list();