java - 尽管实现了“getColumnClass”,但 JTable 显示 true/false 而不是 CheckBox
问题描述
我有一个 JTable,我想在其中以 CheckBoxes 的形式显示布尔值,它应该能够被编辑(选中/取消选中)。
为了实现这一点,我实现了 AbstractTableModel 的一个子类,其中包含所有需要的方法,实现了 getColumnClass 和 isCellEditable。
问题是,显示的是真/假而不是复选框。只有当我单击单元格时,才会调用 getColumnClass-Method 并且 CheckBox 会出现一小段时间。
我发现,JTable 在开始时从不调用“getColumnClass”,而只是在我想单击单元格时调用。
public class OrderTableModel extends AbstractTableModel {
private ArrayList<Orders> orders;
private final String[] HEADER = {"Date", "isParty", "isHost"};
public OrderTableModel(ArrayList<Orders> orders)
{
this.orders = orders;
}
public OrderTableModel(){
orders = new ArrayList<>();
}
@Override
public String getColumnName(int column) {
return HEADER[column];
}
@Override
public int getRowCount() {
return orders.size() > 20 ? orders.size() : 20;
}
@Override
public int getColumnCount() {
return HEADER.length;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
System.out.println("in getColumnClass");
switch(columnIndex)
{
case 1: return Boolean.class;
case 2: return Boolean.class;
default: return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
...
}
解决方案
对于它的价值,我使用您的代码创建了自己的MRE,但对其进行了充实,以便它可以编译和运行,并且代码按预期工作:在您希望看到它们的地方看到 JCheckBoxes。请自行测试以查看:
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
@SuppressWarnings("serial")
public class OrderTableFun extends JPanel {
private OrderTableModel model = new OrderTableModel();
private JTable table = new JTable(model);
public OrderTableFun() {
Random random = new Random();
for (int i = 0; i < 20; i++) {
String name = "name " + i;
boolean party = random.nextBoolean();
boolean host = random.nextBoolean();
Orders order = new Orders(name, party, host);
model.addOrders(order);
}
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
private static void createAndShowGui() {
OrderTableFun mainPanel = new OrderTableFun();
JFrame frame = new JFrame("OrderTableFun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class OrderTableModel extends AbstractTableModel {
private ArrayList<Orders> orders;
private final String[] HEADER = { "Date", "isParty", "isHost" };
public OrderTableModel(ArrayList<Orders> orders) {
this.orders = orders;
}
public OrderTableModel() {
orders = new ArrayList<>();
}
@Override
public String getColumnName(int column) {
return HEADER[column];
}
@Override
public int getRowCount() {
// !! return orders.size() > 20 ? orders.size() : 20;
return orders.size(); // !!
}
@Override
public int getColumnCount() {
return HEADER.length;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
System.out.println("in getColumnClass");
switch (columnIndex) {
case 1:
return Boolean.class;
case 2:
return Boolean.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Orders order = (Orders) orders.get(rowIndex);
switch (columnIndex) {
case 0:
String name = (String) aValue;
order.setName(name);
break;
case 1:
Boolean party = (Boolean) aValue;
order.setParty(party);
case 2:
Boolean host = (Boolean) aValue;
order.setHost(host);
}
fireTableRowsUpdated(rowIndex, rowIndex);
}
public void addOrders(Orders order) {
orders.add(order);
fireTableRowsInserted(getRowCount() - 1, getRowCount());
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Orders order = (Orders) orders.get(rowIndex);
switch (columnIndex) {
case 0:
return order.getName();
case 1:
return order.isParty();
case 2:
return order.isHost();
default:
return null;
}
}
}
class Orders {
String name;
boolean party;
boolean host;
public Orders(String name, boolean party, boolean host) {
this.name = name;
this.party = party;
this.host = host;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isParty() {
return party;
}
public void setParty(boolean party) {
this.party = party;
}
public boolean isHost() {
return host;
}
public void setHost(boolean host) {
this.host = host;
}
}
我已更改 getRowCount 以反映可用的 Orders 对象的实际数量。
推荐阅读
- java - rJava 无法在服务器上安装
- ios - 从 WKWebView 操作导航 SwiftUI 页面
- shell - 我正在尝试在电子邮件中的 shell 脚本中写入日志文件的内容,而不是转到日志文件并打开它以查看结果
- java - 尝试在 Spring + Thymeleaf 中创建复合 jpa 对象
- angular - 在 ssr 构建中使用 ngOnInit 中的拦截器 - Angular 8
- php - Laravel - 似乎无法使用种子用户登录
- python - Pytorch 在训练时变慢
- ruby-on-rails - 如何使用 Ruby on rails 表单“获取”
- javascript - Javascript mathjs-模块,增量矩阵
- google-apps-script - 根据同一行的另一个单元格中的日期,自动在 Google 电子表格的单元格中插入特定文本的脚本