我的 table 中扩展 AbstractTableModel 的 JCheckbox 出现问题
Problem with JCheckbox in my table that extends AbstractTableModel
FileSystemModel class 为我提供了系统文件列表。
我想使用复选框来下载 select 个文件,但我无法编辑此复选框。
我正在寻求关于我做错了什么的提示。
MyTableModel.java
public class MyTableModel extends AbstractTableModel{
private File dir;
private String[] filenames;
private static final long serialVersionUID = -2929662905556163705L;
public DownloadTableModel(File dir) {
this.dir = dir;
this.filenames = dir.list();
}
private ResourceBundle resourceBundle = ResourceBundle.getBundle("MessageBundle", Locale.forLanguageTag("pl"));
protected String[] columns = new String[] {"fileName","fileSize","checked","progress"};
@SuppressWarnings("rawtypes")
protected Class[] columnClasses = {FileSystemModel.class , Long.class, JCheckBox.class, JProgressBar.class};
The FileSystemModel class gives me a list of files from the system.
public int getColumnCount() {
return columns.length;
}
public int getRowCount() {
return filenames.length;
}
public String getColumnName(int col) {
return columns[col].toString();
}
public Class getColumnClass(int c) {
switch (c) {
case 0:
return String.class;
case 1:
return Long.class;
case 2:
return Boolean.class;
case 3:
return Float.class;
default:
return null;
}
}
public Object getValueAt(int row, int col) {
File f = new File(dir, filenames[row]);
switch (col) {
case 0:
return filenames[row];
case 1:
return new Long(f.length());
case 2:
return new Boolean(false);
case 3:
return new Float(50);
default:
return null;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 0:
return false;
case 1:
return false;
case 2:
return true;
case 3:
return false;
default:
return false;
}
}
public void setValueAt(String aValue, int row, int column) {
if ( column == 2) {
filenames[row] = aValue;
fireTableCellUpdated(row, column);
System.out.println(aValue + " " + row);
}
}
}
CheckBoxRenderer.java
public class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
private static final long serialVersionUID = -1892085041343659845L;
private static final Border NO_FOCUS = BorderFactory.createEmptyBorder(1, 1, 1, 1);
public CheckBoxRenderer() {
super();
setHorizontalAlignment(JCheckBox.CENTER);
setBorderPainted(true);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Color alternate = UIManager.getColor("Table.alternateRowColor");
Color normal = new Color(table.getBackground().getRGB());
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(alternate != null && row % 2 == 0 ? normal : alternate);
}
setEnabled(table.isCellEditable(row, column));
setSelected(value != null && (Boolean) value);
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
setBorder(NO_FOCUS);
}
return this;
}
}
MainGUI
在主界面我把它添加到面板
fileDir = new File(System.getProperty("user.dir"));
myTableModel = new MyTableModel(fileDir);
jTable = new JTable(downloadModel);
enter image description here
我没有看到您将数据存储在 TableModel 中的什么位置。您所拥有的只是一个文件名数组。您不存储每行的布尔值以了解它是否被选中。
File f = new File(dir, filenames[row]);
在您的 getValueAte(...)
方法中,您不断地创建一个新的 File 对象。这不是很有效,getValueAt(...) 方法不断地被 table 调用。例如,每次突出显示一行时,您需要将前一行重新绘制为未选中,然后将当前行重新绘制为选中。
所以getValueAt(...)
方法应该尽可能高效。
那么我会怎么做:
创建一个自定义 TableModel,其中包含您要在 table 中显示的所有值,以及复选框的布尔值。
暂时忘记自定义 renderer/editor。首先使用布尔列的默认值 renderer/editor 让逻辑工作。证明基本逻辑有效。然后,如果您认为需要使渲染更加精美,您可以创建自定义渲染器。然后,如果您遇到问题,您就会知道问题出在哪里。
您可以查看 Row Table Model 以了解基于自定义对象创建 TableModel 的分步示例。
FileSystemModel class 为我提供了系统文件列表。 我想使用复选框来下载 select 个文件,但我无法编辑此复选框。 我正在寻求关于我做错了什么的提示。
MyTableModel.java
public class MyTableModel extends AbstractTableModel{
private File dir;
private String[] filenames;
private static final long serialVersionUID = -2929662905556163705L;
public DownloadTableModel(File dir) {
this.dir = dir;
this.filenames = dir.list();
}
private ResourceBundle resourceBundle = ResourceBundle.getBundle("MessageBundle", Locale.forLanguageTag("pl"));
protected String[] columns = new String[] {"fileName","fileSize","checked","progress"};
@SuppressWarnings("rawtypes")
protected Class[] columnClasses = {FileSystemModel.class , Long.class, JCheckBox.class, JProgressBar.class};
The FileSystemModel class gives me a list of files from the system.
public int getColumnCount() {
return columns.length;
}
public int getRowCount() {
return filenames.length;
}
public String getColumnName(int col) {
return columns[col].toString();
}
public Class getColumnClass(int c) {
switch (c) {
case 0:
return String.class;
case 1:
return Long.class;
case 2:
return Boolean.class;
case 3:
return Float.class;
default:
return null;
}
}
public Object getValueAt(int row, int col) {
File f = new File(dir, filenames[row]);
switch (col) {
case 0:
return filenames[row];
case 1:
return new Long(f.length());
case 2:
return new Boolean(false);
case 3:
return new Float(50);
default:
return null;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 0:
return false;
case 1:
return false;
case 2:
return true;
case 3:
return false;
default:
return false;
}
}
public void setValueAt(String aValue, int row, int column) {
if ( column == 2) {
filenames[row] = aValue;
fireTableCellUpdated(row, column);
System.out.println(aValue + " " + row);
}
}
}
CheckBoxRenderer.java
public class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
private static final long serialVersionUID = -1892085041343659845L;
private static final Border NO_FOCUS = BorderFactory.createEmptyBorder(1, 1, 1, 1);
public CheckBoxRenderer() {
super();
setHorizontalAlignment(JCheckBox.CENTER);
setBorderPainted(true);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Color alternate = UIManager.getColor("Table.alternateRowColor");
Color normal = new Color(table.getBackground().getRGB());
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(alternate != null && row % 2 == 0 ? normal : alternate);
}
setEnabled(table.isCellEditable(row, column));
setSelected(value != null && (Boolean) value);
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
setBorder(NO_FOCUS);
}
return this;
}
}
MainGUI
在主界面我把它添加到面板
fileDir = new File(System.getProperty("user.dir"));
myTableModel = new MyTableModel(fileDir);
jTable = new JTable(downloadModel);
enter image description here
我没有看到您将数据存储在 TableModel 中的什么位置。您所拥有的只是一个文件名数组。您不存储每行的布尔值以了解它是否被选中。
File f = new File(dir, filenames[row]);
在您的 getValueAte(...)
方法中,您不断地创建一个新的 File 对象。这不是很有效,getValueAt(...) 方法不断地被 table 调用。例如,每次突出显示一行时,您需要将前一行重新绘制为未选中,然后将当前行重新绘制为选中。
所以getValueAt(...)
方法应该尽可能高效。
那么我会怎么做:
创建一个自定义 TableModel,其中包含您要在 table 中显示的所有值,以及复选框的布尔值。
暂时忘记自定义 renderer/editor。首先使用布尔列的默认值 renderer/editor 让逻辑工作。证明基本逻辑有效。然后,如果您认为需要使渲染更加精美,您可以创建自定义渲染器。然后,如果您遇到问题,您就会知道问题出在哪里。
您可以查看 Row Table Model 以了解基于自定义对象创建 TableModel 的分步示例。