I've a JTable and a column contains Boolean object, so its view in the table is a JCheckBox. I would like to change the status of the JCheckBox in order to change the data in my model. I set
#Override
public boolean isCellEditable(int i, int y) {
return true;
}
but it doesn't work. Could anyone help me?
If you look at TableModel, you'll notice the method setValueAt(...). When you click the checkbox in the table, this is where this change will propogate.
Related
I am a beginner to Java Swing. I have a table with 3 columns. The first column has only check boxes. I wanted to get the index of all the selected items of the check box and store it in an ArrayList. How can I accomplish this?
have a look at this,
http://www.java2s.com/Code/Java/Swing-JFC/SwingCheckBoxDemo.htm
If you want to return all selected items, you can use List or Set for this.
Post the code what you have. I may assist...
As you use a JTable you are using a TableCellRenderer for the "checkbox column". As long you add check boxes to column 1 you "know" in which row the checkbox is created. As you know the row(=index) you can register an action to collect together the checked boxes index.
(from scratch)
public class MyRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, final int row, int column) {
if (column != 1) {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
JCheckBox cb = new JCheckBox();
cb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
list.add(row); // whatever list is ...
}
});
return cb;
}
}
I'm trying to implement a JTable which has to obey the following rules:
Only the 3'rd column's cells can be edited.
When double clicking any cell in row X, the 3'rd column of row X will start edit.
Whenever start editing a cell, the text inside of it will be selected.
I have a FileTable which extends JTable. In its constructor I have this lines:
getColumnModel().getColumn(2).setCellEditor(new FileTableCellEditor());
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2){
int row = rowAtPoint(e.getPoint());
editCellAt(row, 2);
}
}
} );
My FileTableCell editor is as follows:
public class FileTableCellEditor extends DefaultCellEditor {
public FileTableCellEditor() {
super(new JTextField());
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
final JTextField ec = (JTextField) editorComponent;
String textValue = (String)value;
ec.setText(textValue);
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
ec.selectAll();
}
});
return editorComponent;
}
}
My problem is when I double click on a cell which is not from the 3'rd column, The text edited on the 3'rd columns is not highlighted as selected text.
picture http://www.nispahit.com/stack/tableNotHighlight.png
This is very odd to me, because I know the text is selected. When I write something it removes the text that was in that cell before. It just doesn't what is selected.
Oddly, when I double click the 3'rd column cell itself, it does highlight the selection.
picture http://www.nispahit.com/stack/tableHighlight.png
Can someone pour some light?
Thanks!
You can try the Table Select All Editor approach. Don't forget to check out the Table Select All Renderer.
Your JTextField does not highlight the selection because it is not focused. Just add a ec.requestFocus(); right after ec.selectAll();. Then it works as expected.
Explanation: When you click on the editable column Swing will start cell editing (independently of your double-click listener) and forward the initiating event to the component. So the JTextField receives a click and will request focus. When you click on a different column, only your MouseListener initiates cell editing and the event will not get forwarded. (Forwarding the event would not help anyway as the click is outside the text field.) So you have to request the focus manually.
I set the renderer to the checkbox on jtable using following code
Object[] ColumnData = {"Sr No","Ward Name","Total voters","Action"};
Object[][] RawData=null;
// in loop
model.insertRow(x, new Object[]{ key,ward_name_var,total_vot_var,new Object[]{o}});
model.setValueAt(o,x,3);
tblWard.setModel(model);
Setchk(tblWard,3,checkbox); // by calling this method which contains following
private void Setchk(JTable jTable1, int i, JCheckBox checkbox)
{
jTable1.getColumnModel().getColumn(i).setCellRenderer((new CWCheckBoxRenderer()));
jTable1.getColumnModel().getColumn(i).setCellEditor(new CheckBoxCellEditor());
}
Blockquote
how can we try it for row to set the checkbox on jtable.
thanks in advance.
If your data is of type Boolean.class, the default render will display a checkbox. To change the checkbox in a particular row, you need a corresponding CellEditor. The default render/editor are used here; custom components are illustrated here.
You can simply override the getCellRenderer method of your JTable to return the desired renderer for a given row. Example:
JTable table = new JTable() {
TableCellRenderer getCellRenderer(int row, int column) {
if (row == checkBoxRow)
return myCheckBoxRenderer;
else
return super.getCellRenderer(row, column);
}
};
I am using a JComboBox as a cell editor for my JTable. When I select one of the values from the drop down list of the ComboBox, setValueAt is not getting called. I know this because I have overridden the function. Based on the value selected in this cell, the value in another cell of the same table is fixed. Also, I need to know which is the actionListener for this event, i.e when I change the value in the ComboBox.
The setValueAt does get called only when the focus is changed to another cell in the table, just clicking outside the table also does not help.
#Override
public void setValueAt(Object o,int row,int col)
{
super.setValueAt(o, row, col);
if(((String)o).matches("1"))
{
super.setValueAt(o, col-1, row+1);
return;
}
if(((String)o).contains("/"))
super.setValueAt(((String)o).substring(2), col-1, row+1);
else
super.setValueAt("1/"+(String)o, col-1, row+1);
}
I just found the way...
I need to add an actionListener to the JComboBox component that I created as a member of the CellEditor class and in the listener function, i need to call stopCellEditing so that the setValueAt gets called...
I creates a dataTable and cellEditor form one column. This column is simple jSpinner. I have the following problem. When I enter some value in the spinner and select the another row, the value in the previous row won't be changed. If I press , it'll done. If I select or button, it will done too. But if I enter value and change selection, it won't be done. Help, please. Here is the CellEditor code.
public class DurationTableCellEditor extends AbstractCellEditor implements TableCellEditor{
final JSpinner spinner = new JSpinner();
// Initializes the spinner.
public DurationTableCellEditor() {
spinner.setModel(new SpinnerNumberModel(1,1,50000,1));
}
// Prepares the spinner component and returns it.
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
spinner.setValue(new Integer(value.toString()).intValue());
spinner.setCursor(null);
return spinner;
}
// Enables the editor only for double-clicks.
#Override
public boolean isCellEditable(EventObject evt) {
if (evt instanceof MouseEvent) {
return ((MouseEvent)evt).getClickCount() >= 1;
}
return true;
}
// Returns the spinners current value.
public Object getCellEditorValue() {
return spinner.getValue();
}
}
It's not clear how you're updating your data model, but one approach would be to implement ChangeListener in your CellEditor, much as this example implements ItemListener. For reference, see How to Use Tables: Using Other Editors. In particular, look at fireEditingStopped(). Finally, you'll need a corresponding TableCellRenderer.
do commitEdit()
// Returns the spinners current value.
public Object getCellEditorValue() {
spinner.commitEdit();
return spinner.getValue();
}