Java: 单击另一个复选框时自动更新 JTable 中的复选框
Java: Automatically Update a Checkbox in JTable when Another Checkbox is Clicked
我希望在单击 EventYearMatchingWindow 中 JTable 中的复选框时自动选中 EventYearMatchingUnitPanel class 中 JTable 中的每个复选框。
单击第一张图片中的 "unit 9" 复选框 (https://ibb.co/fsqtrQ) should automatically select all 5 checkboxes in the second picture (https://ibb.co/f8ja5k)
我使用 TabelModelListener 中的 tableChanged() 方法来检测复选框是否被单击。当我单击复选框时,它会更改其他复选框的值(从 Boolean.FALSE 到 Boolean.TRUE),但复选框不会更新(不会实际显示复选标记)。
//for the first JTable
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
for(int i = 0; i < unitPanels[row].getNumRows(); i++){
unitPanels[row].setToSelectedState(i);
}
}
//for the second JTable
public void setToSelectedState(int row){
data[row][0] = Boolean.TRUE;
model.fireTableCellUpdated(row, 0);
}
这是代码的大图:
public class EventYearMatchingWindow extends JFrame implements
TableModelListener
{
private boolean columnHeaderClicked;
private ArrayList<Category> categories;
private JPanel mainPanel, listPanel, buttonPanel;
private ArrayList<Item> selectedItems;
private EventYearMatchingItemChoosing[] unitPanels;
Object data[][];
public EventYearMatchingWindow(ArrayList<Category> c){
...
String[] columnNames = {"Include?", ""};
data = new Object[6][2];
for(int i = 0; i < 6; i++){
data[i][0] = Boolean.FALSE;
data[i][1] = "Unit " + (i+8);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int columnIndex) {
if (columnIndex == 0){
return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
};
JTable table = new JTable(model);
table.getModel().addTableModelListener(this);
table.addMouseListener(new java.awt.event.MouseAdapter() {
....
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
if (row == -1 && col >= 0){
columnHeaderClicked = true;
}
if (row >= 0 && col == 1 && !columnHeaderClicked) {
mainPanel.removeAll();
System.out.println(unitPanels[row].getData()[0][0]);
unitPanels[row].revalidate();
unitPanels[row].repaint();
mainPanel.add(unitPanels[row]);
JPanel nButtonPanel = new JPanel();
Button back = new Button("Back");
nButtonPanel.add(back);
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
mainPanel.removeAll();
mainPanel.add(listPanel);
mainPanel.add(buttonPanel);
mainPanel.revalidate();
repaint();
}
});
mainPanel.add(nButtonPanel);
mainPanel.revalidate();
repaint();
}
}
});
}
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
for(int i = 0; i < unitPanels[row].getNumRows(); i++){
unitPanels[row].setToSelectedState(i);
}
}
}
并且:
public class EventYearMatchingItemChoosing extends JPanel implements TableModelListener
{
Category category;
private boolean columnHeaderClicked;
private int size;
private ArrayList<Item> items;
private Object[][] data;
DefaultTableModel model;
public EventYearMatchingItemChoosing(String s, ArrayList<Category> c){
...
String[] columnNames = {"Include?", "Event", "Year"};
data = new Object[size][3]
for(int i = 0; i < category.getItems().size(); i++){
if(!category.getItems().get(i).getEvent().equals("") && !category.getItems().get(i).getYear().equals("")){
data[i][0] = Boolean.FALSE;
data[i][1] = category.getItems().get(i).getEvent();
data[i][2] = category.getItems().get(i).getYear();
}
}
model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int columnIndex) {
if (columnIndex == 0){
return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
};
JTable table = new JTable(model);
table.getModel().addTableModelListener(this);
...
}
...
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
}
public void setToSelectedState(int row){
data[row][0] = Boolean.TRUE;
model.fireTableCellUpdated(row, 0);
}
}
but the checkboxes don't update (don't physically show the checkmarks).
data[row][0] = Boolean.TRUE;
永远不要访问数据数组。数据 Array 用于创建 DefaultTableModel,然后将数据从 Array 复制到 DefaultTableModel 使用的数据结构(恰好是 Vector of Vectors)。
最终结果是 TableModel 中的数据永远不会改变。
代码应该是:
model.setValueAt(Boolean.TRUE, row, 0);
我希望在单击 EventYearMatchingWindow 中 JTable 中的复选框时自动选中 EventYearMatchingUnitPanel class 中 JTable 中的每个复选框。
单击第一张图片中的 "unit 9" 复选框 (https://ibb.co/fsqtrQ) should automatically select all 5 checkboxes in the second picture (https://ibb.co/f8ja5k)
我使用 TabelModelListener 中的 tableChanged() 方法来检测复选框是否被单击。当我单击复选框时,它会更改其他复选框的值(从 Boolean.FALSE 到 Boolean.TRUE),但复选框不会更新(不会实际显示复选标记)。
//for the first JTable
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
for(int i = 0; i < unitPanels[row].getNumRows(); i++){
unitPanels[row].setToSelectedState(i);
}
}
//for the second JTable
public void setToSelectedState(int row){
data[row][0] = Boolean.TRUE;
model.fireTableCellUpdated(row, 0);
}
这是代码的大图:
public class EventYearMatchingWindow extends JFrame implements
TableModelListener
{
private boolean columnHeaderClicked;
private ArrayList<Category> categories;
private JPanel mainPanel, listPanel, buttonPanel;
private ArrayList<Item> selectedItems;
private EventYearMatchingItemChoosing[] unitPanels;
Object data[][];
public EventYearMatchingWindow(ArrayList<Category> c){
...
String[] columnNames = {"Include?", ""};
data = new Object[6][2];
for(int i = 0; i < 6; i++){
data[i][0] = Boolean.FALSE;
data[i][1] = "Unit " + (i+8);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int columnIndex) {
if (columnIndex == 0){
return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
};
JTable table = new JTable(model);
table.getModel().addTableModelListener(this);
table.addMouseListener(new java.awt.event.MouseAdapter() {
....
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
if (row == -1 && col >= 0){
columnHeaderClicked = true;
}
if (row >= 0 && col == 1 && !columnHeaderClicked) {
mainPanel.removeAll();
System.out.println(unitPanels[row].getData()[0][0]);
unitPanels[row].revalidate();
unitPanels[row].repaint();
mainPanel.add(unitPanels[row]);
JPanel nButtonPanel = new JPanel();
Button back = new Button("Back");
nButtonPanel.add(back);
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
mainPanel.removeAll();
mainPanel.add(listPanel);
mainPanel.add(buttonPanel);
mainPanel.revalidate();
repaint();
}
});
mainPanel.add(nButtonPanel);
mainPanel.revalidate();
repaint();
}
}
});
}
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
for(int i = 0; i < unitPanels[row].getNumRows(); i++){
unitPanels[row].setToSelectedState(i);
}
}
}
并且:
public class EventYearMatchingItemChoosing extends JPanel implements TableModelListener
{
Category category;
private boolean columnHeaderClicked;
private int size;
private ArrayList<Item> items;
private Object[][] data;
DefaultTableModel model;
public EventYearMatchingItemChoosing(String s, ArrayList<Category> c){
...
String[] columnNames = {"Include?", "Event", "Year"};
data = new Object[size][3]
for(int i = 0; i < category.getItems().size(); i++){
if(!category.getItems().get(i).getEvent().equals("") && !category.getItems().get(i).getYear().equals("")){
data[i][0] = Boolean.FALSE;
data[i][1] = category.getItems().get(i).getEvent();
data[i][2] = category.getItems().get(i).getYear();
}
}
model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int columnIndex) {
if (columnIndex == 0){
return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
};
JTable table = new JTable(model);
table.getModel().addTableModelListener(this);
...
}
...
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object thatValue = model.getValueAt(row, column);
data[row][column] = thatValue;
}
public void setToSelectedState(int row){
data[row][0] = Boolean.TRUE;
model.fireTableCellUpdated(row, 0);
}
}
but the checkboxes don't update (don't physically show the checkmarks).
data[row][0] = Boolean.TRUE;
永远不要访问数据数组。数据 Array 用于创建 DefaultTableModel,然后将数据从 Array 复制到 DefaultTableModel 使用的数据结构(恰好是 Vector of Vectors)。
最终结果是 TableModel 中的数据永远不会改变。
代码应该是:
model.setValueAt(Boolean.TRUE, row, 0);