【发布时间】:2017-04-01 08:07:50
【问题描述】:
为 JTable 添加“复选框编辑器”的最佳方法是什么?到目前为止,我有一个使用自定义 AbstractTableModel 的 JTable,它使用两个数据集合:一个是 HashMap,它为每一行添加带有“false”值的复选框。第二个集合框架是带有整数的简单 ArrayList。 AbstractTableModel 也有自定义方法从 ArrayList 和 AbstractTableModel 中删除选定的行。问题是,如果我在表中“检查”检查框,检查的值将保持在同一行。我认为问题在于覆盖 setValueAt。我的一段代码:
package checkboxeditor;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JButton;
public class CheckBoxEditor extends JPanel {
public CheckBoxEditor() {
super(new BorderLayout());
MyTableModel myTableModel = new MyTableModel();
JTable table = new JTable(myTableModel);
table.setFillsViewportHeight(true);
JButton deleteBtn = new JButton("Delete selected rows");
deleteBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
int rowCount = table.getRowCount();
for (int i = rowCount - 1; i >= 0; i--) {
boolean checked = (boolean) table.getValueAt(i, 0);
if (checked) {
myTableModel.removeRow((int) table.getValueAt(i, 1));
}
}
}
});
add(deleteBtn, BorderLayout.PAGE_START);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane, BorderLayout.CENTER);
}
class MyTableModel extends AbstractTableModel {
// column names
private String[] columnNames = {"#", "Number"};
// check boxes
HashMap<Integer, Boolean> checkBoxes = new HashMap();
// data
ArrayList<Integer> data = new ArrayList();
public MyTableModel() {
for (Integer i = 1; i < 6; i++) {
data.add(i);
}
}
public void removeRow(Integer numberToDelete) {
int index = data.indexOf(numberToDelete);
data.remove(numberToDelete);
fireTableRowsDeleted(index, index);
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.size();
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
switch (col) {
case 0:
Object value = checkBoxes.get(row);
return (value == null) ? false : value;
case 1:
return data.get(row);
default:
return "";
}
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int col) {
switch (col) {
case 0:
return Boolean.class;
default:
return Integer.class;
}
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
return (col == 0);
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
if (col == 0) {
checkBoxes.put(row, (boolean) value);
}
}
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
CheckBoxEditor newContentPane = new CheckBoxEditor();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
【问题讨论】:
-
Problem is that if I "check" chceckBox in table, the checked value stays in same row.你能进一步解释问题是什么吗?我在您的代码中没有看到任何会影响复选框值的明显内容,并且在运行您的代码时,我没有看到复选框中出现异常行为。 -
@copeg,问题是复选框的“已检查”值始终用于行的索引,而不是用于应该删除值的行。例如,如果表有 5 行,并且我想删除索引为 2 的数字 3,则该值保留在索引 2 上。现在在索引 2 上有下一个数字 - 数字 4。这个数字共享行。
标签: java swing checkbox jtable