Java &引用;复选框编辑器“;对于JTable
为JTable添加“复选框编辑器”的最佳方法是什么?到目前为止,我有一个使用自定义AbstractTableModel的JTable,它使用两个数据集合:一个是HashMap,它为每行添加带有“false”值的复选框。第二个集合框架是带有整数的简单ArrayList。AbstractTableModel还有一个自定义方法,可以从ArrayList和AbstractTableModel中删除选定的行。问题是,若我在表中“check”chceckBox,则选中的值保持在同一行中。我认为问题在于覆盖setValueAt。我的代码:Java &引用;复选框编辑器“;对于JTable,java,swing,checkbox,jtable,Java,Swing,Checkbox,Jtable,为JTable添加“复选框编辑器”的最佳方法是什么?到目前为止,我有一个使用自定义AbstractTableModel的JTable,它使用两个数据集合:一个是HashMap,它为每行添加带有“false”值的复选框。第二个集合框架是带有整数的简单ArrayList。AbstractTableModel还有一个自定义方法,可以从ArrayList和AbstractTableModel中删除选定的行。问题是,若我在表中“check”chceckBox,则选中的值保持在同一行中。我认为问题在于覆盖s
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();
}
});
}
}
packagecheckboxeditor;
导入java.awt.BorderLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.AbstractTableModel;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.HashMap;
导入javax.swing.JButton;
公共类CheckBoxEditor扩展了JPanel{
公共CheckBoxEditor(){
超级(新边框布局());
MyTableModel MyTableModel=新的MyTableModel();
JTable table=新的JTable(myTableModel);
表.setFillsViewPerthweight(真);
JButton deleteBtn=新JButton(“删除选定行”);
deleteBtn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
int rowCount=table.getRowCount();
对于(int i=rowCount-1;i>=0;i--){
布尔选中=(布尔)表.getValueAt(i,0);
如果(选中){
myTableModel.removeRow((int)table.getValueAt(i,1));
}
}
}
});
添加(删除BTN,边框布局。页面\开始);
//创建滚动窗格并将表添加到其中。
JScrollPane scrollPane=新的JScrollPane(表);
//将滚动窗格添加到此面板。
添加(滚动窗格,BorderLayout.CENTER);
}
类MyTableModel扩展了AbstractTableModel{
//列名
私有字符串[]columnNames={“#”,“Number”};
//复选框
HashMap复选框=新建HashMap();
//资料
ArrayList数据=新的ArrayList();
公共MyTableModel(){
对于(整数i=1;i<6;i++){
数据.添加(i);
}
}
public void remoterow(整数删除){
int index=data.indexOf(numberToDelete);
数据删除(numberToDelete);
fireTableRowsDeleted(索引,索引);
}
public int getColumnCount(){
返回columnNames.length;
}
public int getRowCount(){
返回data.size();
}
公共字符串getColumnName(int-col){
返回列名[col];
}
公共对象getValueAt(整数行,整数列){
开关(col){
案例0:
对象值=复选框。获取(行);
返回值(value==null)?false:值;
案例1:
返回数据.get(行);
违约:
返回“”;
}
}
/*
*JTable使用此方法确定默认渲染器/
*每个单元格的编辑器。如果我们没有实现此方法,
*最后一列将包含文本(“真”/“假”),
*而不是复选框。
*/
公共类getColumnClass(int-col){
开关(col){
案例0:
返回Boolean.class;
违约:
返回Integer.class;
}
}
/*
*不需要实现此方法,除非您的表
*可编辑。
*/
公共布尔值可编辑(int行,int列){
//请注意,数据/单元地址是恒定的,
//无论单元格出现在屏幕上的何处。
返回值(col==0);
}
/*
*不需要实现此方法,除非您的表
*数据可以改变。
*/
public void setValueAt(对象值、整行、整列){
如果(列==0){
复选框。输入(行,(布尔)值);
}
}
}
/**
*创建GUI并显示它。为了线程安全,应该
*从事件调度线程调用。
*/
私有静态void createAndShowGUI(){
//创建并设置窗口。
JFrame=新JFrame(“TableDemo”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建并设置内容窗格。
CheckBoxEditor newContentPane=新的CheckBoxEditor();
newContentPane.setOkable(true);//内容窗格必须是不透明的
frame.setContentPane(newContentPane);
//显示窗口。
frame.pack();
frame.setVisible(true);
}
公共静态void main(字符串[]args){
//为事件调度线程计划作业:
//创建并显示此应用程序的GUI。
javax.swing.SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGUI();
}
});
}
}
一种是HashMap,它为每行添加带有“false”值的复选框。第二个集合框架是带有整数的简单ArrayList
不需要两个数据结构或创建自定义TableModel
您可以使用DefaultTableModel
。DefaultTableModel
允许您在每行中存储任何类型的对象。您所需要做的就是重写模型的getColumnClass(…)
方法以返回正确的类,表将为列选择适当的呈现器/编辑器。比如:
String[] columnNames = {"#", "Number"};
DefaultTableModel model = new DefaultTableModel(columnNames, 0)
{
// Returning the Class of each column will allow different
// renderers and editors to be used based on Class
public Class getColumnClass(int column)
{
return column == 0 ? Boolean.class : Integer.class;
}
};
JTable table = new JTable(model);
for (Integer i = 1; i < 6; i++)
{
Object[] row = {Boolean.FALSE, i};
model.addRow( row);
}
然后,您可以通过执行以下操作将数据添加到表中: