Hi Nguyen, Some comments about your code:
1. What is the purpose behind putting a radio button in a cell and expecting radio buttons in all the rows to behave as if they are in a button group? In my opinion a table is a presenter of data and not a container for widgets. 2. For the radio button behavior (only one selection) you need to put all the radio buttons in a button group and to do this for all the editors for all the rows is not practically possible. So you either need to have purely client side renderer and editor and/or you need to implement this behavior in the model i.e. when you select one button, deselect others. Thanks and regards, Janak ________________________________________ From: nguyen duyhai [mailto:[EMAIL PROTECTED] Sent: Tuesday, March 25, 2008 11:55 AM To: [EMAIL PROTECTED] Subject: [ULC-developer] - Use radio button as cell renderer/ editor. Hello Janak ! I am encountering a problem using radioButton as cell editor/renderer. Please could you help me to pass it. Here is my explain about code in snipped : - The code for customize ULCRadioButton as cell editor in class MyRadioButtonEditor and MyUIRadioButtonEditor. - The code for customize ULCRadioButton as cell renderer in class MyRadioButtonRenderer and MyUIRadioButtonRenderer. - I used "ClientContext.setModelUpdateMode(table.getModel(),UlcEventConstants.SYNCH RONOUS_MODE)" - In table MyTableModel, I set cell renderer (MyRadioButtonRenderer) and editor (MyRadioButtonEditor) in table . Expect : - The first column works like a radio button, where only one table entry may have that option checked. - When I select one table entry, not press tab, then method setValueAt in table is called. Result : - When I select one table entry, I press tab, then method setValueAt in table is called. - At the same time , I select two table entry (wrong radio button behaviour : only one table entry should be selectable). May be the attached snipped will help you to show the problem. You have to play with it and try to check and uncheck the radioButton of the first column. It seems, the 'fireTableDataChanged()' doesn't make its job because of a focus problem. I have posted question in ULC-developer Archives at 17.03.2008. Can you explain me about problem using radio button as cell editor/renderer in table? Is it a bug in canoo? Thanks you for your supports, Nguyen ////////////////////////////////////////////////////////////////////////// /// //// The snipped/////////////////////// //////////////////////////// package com.ulcjava.sample.teammember; import java.awt.Component; import java.util.Enumeration; import javax.swing.AbstractCellEditor; import javax.swing.ComboBoxEditor; import javax.swing.JRadioButton; import javax.swing.JTable; import javax.swing.ListCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.tree.TreeCellEditor; import javax.swing.tree.TreeCellRenderer; import com.ulcjava.base.application.AbstractApplication; import com.ulcjava.base.application.ApplicationContext; import com.ulcjava.base.application.ClientContext; import com.ulcjava.base.application.IEditorComponent; import com.ulcjava.base.application.IRendererComponent; import com.ulcjava.base.application.ULCAlert; import com.ulcjava.base.application.ULCDialog; import com.ulcjava.base.application.ULCFrame; import com.ulcjava.base.application.ULCListSelectionModel; import com.ulcjava.base.application.ULCMenuItem; import com.ulcjava.base.application.ULCPopupMenu; import com.ulcjava.base.application.ULCRadioButton; import com.ulcjava.base.application.ULCScrollPane; import com.ulcjava.base.application.ULCTable; import com.ulcjava.base.application.event.IListSelectionListener; import com.ulcjava.base.application.event.IWindowListener; import com.ulcjava.base.application.event.ListSelectionEvent; import com.ulcjava.base.application.event.WindowEvent; import com.ulcjava.base.application.table.AbstractTableModel; import com.ulcjava.base.application.table.ITableCellEditor; import com.ulcjava.base.application.table.ITableCellRenderer; import com.ulcjava.base.application.table.ULCTableColumn; import com.ulcjava.base.client.UIRadioButton; import com.ulcjava.base.client.tabletree.TableTreeCellEditor; import com.ulcjava.base.client.tabletree.TableTreeCellRenderer; import com.ulcjava.base.development.DevelopmentRunner; import com.ulcjava.base.server.ICellComponent; import com.ulcjava.base.shared.UlcEventConstants; public class ULCRadioButtonEditorSnipped extends AbstractApplication { private ULCFrame frame; public void start() { this.frame = new ULCFrame("ULCTable Radio Button CellEditor Sample"); frame.setSize(100, 250); // Declare table model ULCTable table = new ULCTable(); table.setModel( new MyTableModel()); // Set mode synchronous for table model ClientContext.setModelUpdateMode(table.getModel(), UlcEventConstants. SYNCHRONOUS_MODE); table.getSelectionModel().addListSelectionListener( new IListSelectionListener() { public void valueChanged(ListSelectionEvent event) { System. out.println("Selection changed - " + "Row: " + ((ULCListSelectionModel)event.getSource()).getMinSelectionIndex()); } }); // Set cell renderer and editor for MyULCTable for (Enumeration columns = table.getColumnModel().getColumns(); columns.hasMoreElements() ;) { final ULCTableColumn column = (ULCTableColumn) columns.nextElement(); column.setCellRenderer( new ITableCellRenderer() { public IRendererComponent getTableCellRendererComponent(ULCTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4) { return new MyULCRadioButtonRenderer(); } }); column.setCellEditor( new ITableCellEditor() { public IEditorComponent getTableCellEditorComponent(ULCTable arg0, Object arg1, int arg2) { return new MyULCRadioButtonEditor(); } }); } frame.add(new ULCScrollPane(table)); frame.setVisible(true); frame.setDefaultCloseOperation(ULCDialog.DISPOSE_ON_CLOSE); frame.addWindowListener(new IWindowListener() { public void windowClosing(WindowEvent arg0) { ApplicationContext.terminate(); } }); } public static void main(String[] args) { DevelopmentRunner.setApplicationClass(ULCRadioButtonEditorSnipped. class ); DevelopmentRunner.main(args); } /** * <p> * My table model. * </p> */ private class MyTableModel extends AbstractTableModel { private int currentRow = 0; public int getRowCount() { return 10; } public int getColumnCount() { return 1; } public Object getValueAt(int row, int column) { switch (column) { case 0: return (row == currentRow) ? Boolean.TRUE : Boolean.FALSE; default: return (Math.random() < 0.5) ? Boolean.TRUE : Boolean.FALSE; } } public boolean isCellEditable(int rowIndex, int columnIndex) { return true; } public void setValueAt(Object value, int row, int column) { if (column == 0) { if (row == currentRow) { final ULCAlert alert = new ULCAlert(frame, "Warning", "Not uncheck!", "OK"); alert.show(); fireTableCellUpdated(row, column); } else { this.currentRow = row; fireTableDataChanged(); } } } } ///////////////////////////////////////////////////// /// Customize ULCRadioButton as cell editor ///////////////////////////////////////////////////// public static class MyULCRadioButtonEditor extends ULCRadioButton implements com.ulcjava.base.application.IEditorComponent { public boolean areAttributesEqual(ICellComponent component) { if (!(component instanceof MyULCRadioButtonEditor)) { return false; } MyULCRadioButtonEditor other = (MyULCRadioButtonEditor)component; return equals(getBackground(), other.getBackground()) && equals(getFont(), other.getFont()) && equals(getForeground(), other.getForeground()) && (isSelected() == other.isSelected()) && equals(getToolTipText(), other.getToolTipText()) ; } public int attributesHashCode() { int result = 17; result = 37 * result + (getBackground() == null ? 0 : getBackground().hashCode()); result = 37 * result + (getFont() == null ? 0 : getFont().hashCode()); result = 37 * result + (getForeground() == null ? 0 : getForeground().hashCode()); result = 37 * result + (getToolTipText() == null ? 0 : getToolTipText().hashCode()); return result; } public void copyAttributes(ICellComponent source) { MyULCRadioButtonEditor sourceRadioButton = (MyULCRadioButtonEditor)source; setBackground(sourceRadioButton.getBackground()); setFont(sourceRadioButton.getFont()); setForeground(sourceRadioButton.getForeground()); } protected String typeString() { return UIRadioButtonEditor.class.getName(); } } ///////////////////////////////////////////////////////////////////// /// On the client side, we have extends UIRadioButton as cell editor. ///////////////////////////////////////////////////////////////////// public static class UIRadioButtonEditor extends UIRadioButton implements com.ulcjava.base.client.IEditorComponent { private TableCellEditor fTableCellEditor; protected void postInitializeState() { super.postInitializeState(); fTableCellEditor = new RadioButtonTableCellEditor(); } public ComboBoxEditor getComboBoxEditor() { throw new UnsupportedOperationException(); } public TableCellEditor getTableCellEditor() { return fTableCellEditor; } public TableTreeCellEditor getTableTreeCellEditor() { throw new UnsupportedOperationException(); } public TreeCellEditor getTreeCellEditor() { throw new UnsupportedOperationException(); } private class RadioButtonTableCellEditor extends AbstractCellEditor implements TableCellEditor { public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { getBasicRadioButton().setSelected(((Boolean)value).booleanValue()); return getBasicRadioButton(); } public Object getCellEditorValue() { return new Boolean(getBasicRadioButton().isSelected()); } } } ///////////////////////////////////////////////////// /// Customize ULCRadioButton as cell renderer ///////////////////////////////////////////////////// public static class MyULCRadioButtonRenderer extends ULCRadioButton implements com.ulcjava.base.application.IRendererComponent { public MyULCRadioButtonRenderer() { super(); } /* (non-Javadoc) * @see com.ulcjava.base.server.ICellComponent#areAttributesEqual( com.ulcjava.base.server.ICellComponent) */ public boolean areAttributesEqual(ICellComponent component) { if (!(component instanceof MyULCRadioButtonRenderer)) { return false; } MyULCRadioButtonRenderer other = (MyULCRadioButtonRenderer)component; return equals(getBackground(), other.getBackground()) && equals(getFont(), other.getFont())&& equals(getForeground(), other.getForeground()) && equals(getToolTipText(), other.getToolTipText())&& isSelected() == other.isSelected() && isEnabled() == other.isEnabled(); } /* (non-Javadoc) * @see com.ulcjava.base.server.ICellComponent#attributesHashCode() */ public int attributesHashCode() { int result = 17; result = 37 * result + (getBackground() == null ? 0 :getBackground().hashCode()); result = 37 * result + (getFont() == null ? 0 :getFont().hashCode()); result = 37 * result + (getForeground() == null ? 0 : getForeground().hashCode()); result = 37 * result + (getToolTipText() == null ? 0 :getToolTipText().hashCode()); result = 37 * result + (isSelected()? 1 : 0); result = 37 * result + (isEnabled()? 1 : 0); return result; } /* (non-Javadoc) * @see com.ulcjava.base.server.ICellComponent#copyAttributes( com.ulcjava.base.server.ICellComponent) */ public void copyAttributes(ICellComponent source) { MyULCRadioButtonRenderer sourceRadioButton = (MyULCRadioButtonRenderer)source; setBackground(sourceRadioButton.getBackground()); setFont(sourceRadioButton.getFont()); setForeground(sourceRadioButton.getForeground()); setToolTipText(sourceRadioButton.getToolTipText()); setSelected(sourceRadioButton.isSelected()); setEnabled(sourceRadioButton.isEnabled()); } protected String typeString() { return UIRadioButtonRenderer. class.getName(); } } ///////////////////////////////////////////////////////////// /// Customize we have extends UIRadioButton as cell renderer. ///////////////////////////////////////////////////////////// public static class UIRadioButtonRenderer extends UIRadioButton implements com.ulcjava.base.client.IRendererComponent { private TableCellRenderer fTableCellRenderer; /* (non-Javadoc) * @see com.ulcjava.base.client.UITextField#postInitializeState() */ protected void postInitializeState() { super.postInitializeState(); fTableCellRenderer = new RadioButtonTableCellRenderer(); } /* (non-Javadoc) * @see com.ulcjava.base.client.IRendererComponent#getTableCellRenderer() */ public TableCellRenderer getTableCellRenderer() { return fTableCellRenderer; } /* (non-Javadoc) * @see com.ulcjava.base.client.IRendererComponent#getTreeCellRenderer() */ public TreeCellRenderer getTreeCellRenderer() { throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see com.ulcjava.base.client.IRendererComponent#getListCellRenderer() */ public ListCellRenderer getListCellRenderer() { throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see com.ulcjava.base.client.IRendererComponent#getTableTreeCellRenderer() */ public TableTreeCellRenderer getTableTreeCellRenderer() { throw new UnsupportedOperationException(); } private class RadioButtonTableCellRenderer implements TableCellRenderer { /* (non-Javadoc) * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent( javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Boolean select = (value instanceof Boolean) ? (Boolean)value : null; JRadioButton result = (JRadioButton)getBasicComponent(); if (select!= null) { result.setSelected(select.booleanValue()); } return result; } } } }
