Adding jRadioButton into jTable
- If you want to edit the value of a table cell, you must set a
TableCellEditor
. - You should create a single
JRadioButton
in your renderer and reuse it everywhere, that is the purpose of TableCellRenderer. - If you are not calling
super.getTableCellRendererComponent
, it is not need to extendDefaultTableCellRenderer
, simply implementTableCellRenderer
.
Consider reading the JTable tutorial to understand better the concepts of renderers and editors.
EDIT:
Here is an example on how you can make this work. Of course, you'll have to adapt to your model but you should get the gist:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class TestTable {
public class RadioButtonCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener {
private JRadioButton radioButton;
public RadioButtonCellEditorRenderer() {
this.radioButton = new JRadioButton();
radioButton.addActionListener(this);
radioButton.setOpaque(false);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
radioButton.setSelected(Boolean.TRUE.equals(value));
return radioButton;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
radioButton.setSelected(Boolean.TRUE.equals(value));
return radioButton;
}
@Override
public void actionPerformed(ActionEvent e) {
stopCellEditing();
}
@Override
public Object getCellEditorValue() {
return radioButton.isSelected();
}
}
private JFrame f;
private JTable table;
private class MyObjectManager {
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private List<MyObject> objects = new ArrayList<TestTable.MyObject>();
public void addObject(MyObject object) {
objects.add(object);
object.setManager(this);
propertyChangeSupport.firePropertyChange("objects", null, object);
}
public List<MyObject> getObjects() {
return objects;
}
public void setAsSelected(MyObject myObject) {
for (MyObject o : objects) {
o.setSelected(myObject == o);
}
}
}
private class MyObject {
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private MyObjectManager manager;
private String value;
private boolean selected;
public MyObject(String value) {
this.value = value;
}
public PropertyChangeSupport getPropertyChangeSupport() {
return propertyChangeSupport;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
propertyChangeSupport.firePropertyChange("value", null, value);
}
public MyObjectManager getManager() {
return manager;
}
public void setManager(MyObjectManager manager) {
this.manager = manager;
propertyChangeSupport.firePropertyChange("manager", null, manager);
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
if (this.selected != selected) {
this.selected = selected;
if (selected) {
manager.setAsSelected(this);
}
propertyChangeSupport.firePropertyChange("selected", !selected, selected);
}
}
}
protected void initUI() {
MyObjectManager manager = new MyObjectManager();
for (int i = 0; i < 200; i++) {
MyObject object = new MyObject("Row " + (i + 1));
manager.addObject(object);
}
table = new JTable(new MyTableModel(manager));
table.setRowHeight(20);
TableColumn column = table.getColumnModel().getColumn(1);
column.setCellEditor(new RadioButtonCellEditorRenderer());
column.setCellRenderer(new RadioButtonCellEditorRenderer());
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JScrollPane(table), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
public class MyTableModel extends AbstractTableModel implements PropertyChangeListener {
private final MyObjectManager manager;
public MyTableModel(MyObjectManager manager) {
super();
this.manager = manager;
manager.propertyChangeSupport.addPropertyChangeListener(this);
for (MyObject object : manager.getObjects()) {
object.getPropertyChangeSupport().addPropertyChangeListener(this);
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getSource() == manager) {
// OK, not the cleanest thing, just to get the gist of it.
if (evt.getPropertyName().equals("objects")) {
((MyObject) evt.getNewValue()).getPropertyChangeSupport().addPropertyChangeListener(this);
}
fireTableDataChanged();
} else if (evt.getSource() instanceof MyObject) {
int index = manager.getObjects().indexOf(evt.getSource());
fireTableRowsUpdated(index, index);
}
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public int getRowCount() {
return manager.getObjects().size();
}
public MyObject getValueAt(int row) {
return manager.getObjects().get(row);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return getValueAt(rowIndex).getValue();
case 1:
return getValueAt(rowIndex).isSelected();
}
return null;
}
@Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
if (columnIndex == 1) {
getValueAt(rowIndex).setSelected(Boolean.TRUE.equals(value));
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 1;
}
@Override
public Class<?> getColumnClass(int column) {
switch (column) {
case 0:
return String.class;
case 1:
return Boolean.class;
}
return Object.class;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Value";
case 1:
return "Selected";
}
return null;
}
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTable().initUI();
}
});
}
}
Can I add JRadioButton into JTable
It's not clear how you want to use JRadioButton
in a JTable
; consider these alternatives:
Use
SINGLE_SELECTION
mode to select individual rows.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
Use a column of type
Boolean.class
, which will be rendered using aJCheckBox
. This example limits selections to a single row.Use a
JComboBox
as an editor for mutually exclusive choices within a row.Addendum: If
JRadioButton
is required, they can be added to aJPanel
, as shown in this example due to @mKorbel.Addendum: If each
JRadioButton
has its own column, you can't use aButtonGroup
because a single button is used for all cells having the same renderer. You can update other button(s) in the same row from yourTableModel
, which should overridesetValueAt()
to enforce the single-selection rule that is usually managed by theButtonGroup
. There's an example here.Addendum: This example due to @Guillaume Polet illustrates a way to manage one radio button per row.
jRadioButton value in jTable
bgButtonGroup.getSelection()
this is returning the model of the selected radio button, not the text of it. If you set action command to your radio buttons you can get the text by bgButtonGroup.getSelection().getActionCommand()
. For example after create your yesRadioButton
set "yes" as action command for it with yesRadioButton.setActionCommand("Yes")
.
private void bAdd11ActionPerformed(java.awt.event.ActionEvent evt) {
ErrorMessage.setText("");
DefaultTableModel model3;
model3 = (DefaultTableModel) tblProduct11.getModel();
if(!tfChassi.getText().trim().equals("")){
model3.addRow(new Object[]{
tf1.getText(),
tf2.getText(),
tf3.getText(),
cb1.getSelectedItem().toString(),
cb2.getSelectedItem().toString(),
cb3.getSelectedItem().toString(),
cb4.getSelectedItem().toString(),
tf4.getText(),
tf5.getText(),
bgButtonGroup.getSelection().getActionCommand()
}
);
Adding JRadioButton to Group
Hmm, I solve it like this:
void modelsRadio () throws SQLException {
JPanel modelsRadioPanel = new JPanel();
Statement statement = db.setConnection();
ResultSet rs = statement.executeQuery("SELECT * FROM МОДЕЛИ");
ButtonGroup modelRadioGroup = new ButtonGroup();
while (rs.next()) {
JRadioButton jr = new JRadioButton(rs.getString("НАЗВАНИЕ"));
//modelRadioGroup.add(new JRadioButton(rs.getString("НАЗВАНИЕ")));
modelRadioGroup.add(jr);
modelsRadioPanel.add(jr);
}
frame.add(modelsRadioPanel);
}
Radio button in JTable not working properly
From your illustration, it appears that you want to enforce mutual exclusion among the rows of a JTable
, where each row has a single JRadioButton
. As a ButtonGroup
is unsuitable, this example due to @Guillaume Polet uses a custom manager.
setting a default enabled radiobutton in a JTable
Not sure that I am interpreting the question correctly. You can use JRadioButton
constructor to set selection, for example the snippet (based on OP code sample) will set selected button "B":
dm.setDataVector(new Object[][] { { "Group 1", new JRadioButton("A") },
{ "Group 1", new JRadioButton("B", true) },
{ "Group 1", new JRadioButton("C") },
{ "Group 2", new JRadioButton("a") },
{ "Group 2", new JRadioButton("b") } }, new Object[] {
"String", "JRadioButton" });
You can also change selection like this:
((JRadioButton) dm.getValueAt(0, 1)).setSelected(true);
You can also use ButtonGroup.setSelected()
method.
EDIT: eliminate components from model
The model should contain data rather than components. Storing components in the model defeats the idea of renderers and editors. For more details see Editors and Renderers and Swing Models and Renderers. Check out the following example the mimics button group behavior in the model:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.table.*;
public class ButtonGroupMockupTest {
private static void createAndShowGUI() {
DefaultTableModel model = new DefaultTableModel(new Object[][] {
{ "Group 1", Boolean.FALSE }, { "Group 2", Boolean.FALSE },
{ "Group 3", Boolean.FALSE } },
new Object[] { "Name", "State" }) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int col) {
if (col == 1)
return Boolean.class;
return super.getColumnClass(col);
}
@Override
public void setValueAt(Object value, int row, int col) {
super.setValueAt(value, row, col);
if (col == 1 && value.equals(Boolean.TRUE))
deselectValues(row, col);
}
private void deselectValues(int selectedRow, int col) {
for (int row = 0; row < getRowCount(); row++) {
if (getValueAt(row, col).equals(Boolean.TRUE)
&& row != selectedRow) {
setValueAt(Boolean.FALSE, row, col);
fireTableCellUpdated(row, col);
}
}
}
};
JTable table = new JTable(model);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setDefaultRenderer(Boolean.class, new BooleanRadionRenderer());
table.setDefaultEditor(Boolean.class, new BooleanRadioEditor());
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JScrollPane(table));
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
static class BooleanRadionRenderer implements TableCellRenderer, UIResource {
JRadioButton radioButton;
Border emptyBorder;
public BooleanRadionRenderer() {
radioButton = new JRadioButton();
radioButton.setHorizontalAlignment(JRadioButton.CENTER);
radioButton.setBorderPainted(true);
emptyBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col) {
if (isSelected) {
radioButton.setBackground(table.getSelectionBackground());
radioButton.setForeground(table.getSelectionForeground());
} else {
radioButton.setBackground(table.getBackground());
radioButton.setForeground(table.getForeground());
}
if (hasFocus)
radioButton.setBorder(UIManager
.getBorder("Table.focusCellHighlightBorder"));
else
radioButton.setBorder(emptyBorder);
radioButton.setSelected(((Boolean) value).booleanValue());
return radioButton;
}
}
static class BooleanRadioEditor extends AbstractCellEditor
implements TableCellEditor {
private static final long serialVersionUID = 1L;
private JRadioButton radioButton;
public BooleanRadioEditor() {
radioButton = new JRadioButton();
radioButton.setHorizontalAlignment(JRadioButton.CENTER);
radioButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// prevent deselection to mimic button group
if (!radioButton.isSelected())
cancelCellEditing();
stopCellEditing();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int col) {
radioButton.setSelected(((Boolean) value).booleanValue());
return radioButton;
}
@Override
public Object getCellEditorValue() {
return Boolean.valueOf(radioButton.isSelected());
}
}
}
Related Topics
Filter Invoke Twice When Register as Spring Bean
Why Stringbuilder When There Is String
What Are Classes, References, and Objects
Cannot Parse String in Iso 8601 Format, Lacking Colon in Offset, to Java 8 Date
Returning Null as an Int Permitted with Ternary Operator But Not If Statement
Get Width and Height of JPAnel Outside of the Class
Org.Apache.Tomcat.Util.Bcel.Classfile.Classformatexception: Invalid Byte Tag in Constant Pool: 15
Differencebetween Set and List
Does the Jvm Prevent Tail Call Optimizations
Resume Http File Download in Java
How to Fix Role in Spring Security
How to Get Screen Resolution in Java
Java Byte Array to String to Byte Array
Java Thread.Sleep Puts Swing UI to Sleep Too