我有一个 JTable,我想在其中以复选框的形式显示 boolean 值,它应该能够被编辑(选中/取消选中)。
为了实现这一目标,我实现了 AbstractTableModel 的子类,其中包含所有需要的方法、getColumnClass 和 isCellEditable 实现。
问题是,显示的是 true/false,而不是 CheckBox。仅当我单击单元格时,才会调用 getColumnClass-Method 并且复选框会出现一小段时间。
我发现,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 以反射(reflect)可用 Orders 对象的实际数量。
关于java - 尽管实现了 "getColumnClass",但 JTable 显示 true/false 而不是 CheckBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56327653/