首先请注意您的问题与 JXTable 无关,而是与渲染器/编辑器/模型有关。
正如@mKorbel 指出的那样,JCheckBox 是布尔值的默认渲染器/编辑器,一般来说,您不需要重新发明轮子:只需正确覆盖getColumnClass()即可在第 5 列和第 6 列上返回布尔值。
但是,由于这个要求:
如果未选中第一个复选框,则必须禁用并取消选中第二个复选框。
这不是默认渲染器的行为,因此您实际上需要自己的渲染器。但只有渲染器,您不需要编辑器:正如@mKorbel 指出的那样,您需要对表格模型进行一些工作。
渲染器
class CheckBoxCellRenderer implements TableCellRenderer {
private final JCheckBox renderer;
public CheckBoxCellRenderer() {
renderer = new JCheckBox();
renderer.setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Color bg = isSelected
? table.getSelectionBackground() : table.getBackground();
renderer.setBackground(bg);
renderer.setEnabled(table.isCellEditable(row, column));
renderer.setSelected(value != null && (Boolean)value);
return renderer;
}
}
模型
您需要同时使用isCellEditable()和setValueAt()方法才能根据第一个布尔值正确更新第二个布尔值列。例如考虑这个片段:
// A default model with 5 rows and 6 columns
DefaultTableModel model = new DefaultTableModel(5, 6) {
@Override
public Class<?> getColumnClass(int columnIndex) {
switch(columnIndex) {
case 4:
case 5: return Boolean.class; // Both 5th and 6th columns are booleans
}
return super.getColumnClass(columnIndex);
}
@Override
public boolean isCellEditable(int row, int column) {
/*
* In order to know if 6th column is editable, you have to check
* 5th column's value.
*/
if(column == 5) {
Object value = getValueAt(row, 4);
return value != null && (Boolean)value;
}
return super.isCellEditable(row, column);
}
@Override
public void setValueAt(Object aValue, int row, int column) {
/*
* If 5th column value is updated to FALSE, you need to
* set 6th column's value to FALSE as well
*/
if(column == 4) {
super.setValueAt(Boolean.FALSE, row, 5);
}
super.setValueAt(aValue, row, column);
}
};
测试一下
这是一个完整的测试用例。希望能帮助到你。
import java.awt.Color;
import java.awt.Component;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
* @author dic19
*/
public class Demo {
private void createAndShowGui() {
DefaultTableModel model = new DefaultTableModel(5, 6) {
@Override
public Class<?> getColumnClass(int columnIndex) {
switch(columnIndex) {
case 4:
case 5: return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
@Override
public boolean isCellEditable(int row, int column) {
if(column == 5) {
Object value = getValueAt(row, 4);
return value != null && (Boolean)value;
}
return super.isCellEditable(row, column);
}
@Override
public void setValueAt(Object aValue, int row, int column) {
if(column == 4) {
super.setValueAt(false, row, 5);
}
super.setValueAt(aValue, row, column);
}
};
JTable table = new JTable(model);
table.getDefaultRenderer(null);
table.getColumnModel().getColumn(5).setCellRenderer(new CheckBoxCellRenderer());
JScrollPane scrollPane = new JScrollPane(table);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
class CheckBoxCellRenderer implements TableCellRenderer {
private final JCheckBox renderer;
public CheckBoxCellRenderer() {
renderer = new JCheckBox();
renderer.setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Color bg = isSelected
? table.getSelectionBackground() : table.getBackground();
renderer.setBackground(bg);
renderer.setEnabled(table.isCellEditable(row, column));
renderer.setSelected(value != null && (Boolean)value);
return renderer;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGui();
}
});
}
}