【发布时间】:2010-12-02 07:25:15
【问题描述】:
我设计了一个 GUI,我在其中使用了一个 JTable,我必须从中使 2 列不可见。我该怎么做?
【问题讨论】:
标签: java swing jtable invisible
我设计了一个 GUI,我在其中使用了一个 JTable,我必须从中使 2 列不可见。我该怎么做?
【问题讨论】:
标签: java swing jtable invisible
将最小、最大和“正常”宽度设置为 0:
jTable.getColumn("ABC").setMinWidth(0); // Must be set before maxWidth!!
jTable.getColumn("ABC").setMaxWidth(0);
jTable.getColumn("ABC").setWidth(0);
注意:由于不能设置maxWidthminWidth,需要先更改minWidth,(javadoc)。 width 也是如此。
第二种方法是扩展 TableColumnModel 并覆盖所有方法以创建模型没有这两列的错觉(对于 JTable)。
所以当你隐藏一列时,当表格要求列数时,你必须返回一个,当它要求列X时,你可能要在列索引上加1(取决于它是否是隐藏列的左侧或右侧)等。
让您的新表模型将所有方法调用(使用更正的索引等)转发到实际的列模型,并在 JTable 中使用新表模型。
【讨论】:
如果您从JTable 中删除该列,则该列仍存在于TableModel 中。
例如删除第一个 ID 列:
TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn(tcm.getColumn(0));
如果你想访问被移除列的值,你必须通过TableModel的getValueAt函数来访问它,而不是JTable。但是你必须将模型中的rowIndex转换回rowIndex。
例如,如果您想访问所选行的第一列:
int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
int value = (Integer)table.getModel().getValueAt(modelRow,0);
【讨论】:
从TableColumnModel 中删除TableColumn。
TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn( tcm.getColumn(...) );
如果您需要访问数据,请使用table.getModel().getValueAt(...)。
对于允许用户根据需要隐藏/显示列的更复杂的解决方案,请查看Table Column Manager。
【讨论】:
view 和model 之间的区别。表方法总是引用视图。 JTable API 有一堆convertXXX 可以使用的方法。所以你可以使用convertColumnIndexToModel(...)
我遇到了同样的问题,因为我使用的是 TableColumnModel removColumn(); 对我没有帮助,所以我使用了这个
table.getColumnModel().getColumn(0).setWidth(0);
table.getColumnModel().getColumn(0).setMinWidth(0);
table.getColumnModel().getColumn(0).setMaxWidth(0);
对我来说工作得很好,它隐藏了第 0 列,我仍然可以从中获得价值
【讨论】:
首先从视图中移除列
table.removeColumn(table.getColumnModel().getColumn(4));
然后从模型中检索数据。
table.getModel().getValueAt(table.getSelectedRow(),4);
需要注意的是,在检索数据时,必须从模型中检索,而不是从表中检索。
【讨论】:
我都试过了:它们没有帮助。最好的方法是创建一个没有要删除的列的新表模型。这就是你的做法:
table = (DefaultTableModel) <table name>.getModel();
DefaultTableModel table1 = new DefaultTableModel();
Vector v = table.getDataVector();
Vector v1 = newvector(v,<column index you want to delete>);
Vector newvector(Vector v,int j){
Vector v1= new Vector();
try{
Vector v2;
Object[] o = v.toArray();
int i =0;
while(i<o.length){
v2 = (Vector) o[i];
v2.remove(j);
v1.add(v2);
i++;
}
}
catch(Exception e){
JOptionPane.showMessageDialog(null,"Error in newvector \n"+e);
}
return v1;
}
Vector getColumnIdentifiers(int i) {
Vector columnIdentifiers = new Vector();
int j=0;
while(j<i){
columnIdentifiers.add(("c"+(j+1)));
j++;
}
return columnIdentifiers;
}
table1.setDataVector(v1,getColumnIdentifiers((<column count>-1)));
<table name>.setModel(table1);
【讨论】:
我尝试了两种可行的解决方案,但第一种解决方案出现了一些问题。
table.removeColumn(table.getColumnModel().getColumn(4));
或
table.getColumnModel().getColumn(4).setMinWidth(0);
table.getColumnModel().getColumn(4).setMaxWidth(0);
table.getColumnModel().getColumn(4).setWidth(0);
在我最近的案例中,我更喜欢第二种解决方案,因为我添加了一个 TableRowSorter。
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
使用table.removeColumn(table.getColumnModel().getColumn(4)) 时,它会从视图/表中物理删除列,因此您不能使用table.getValueAt(row, 4) - 它返回ArrayIndexOutOfBounds。获取已删除列的值的唯一方法是调用table.getModel().getValueAt(table.getSelectedRow(),4)。由于 TableRowSorter 只对表中的内容进行排序,而不是对 DefaultTableModel 对象中的数据进行排序,因此问题是当您在对记录进行排序之后获得值 after - 它将从 DefaultModelObject 中检索数据,该数据未排序。
所以我使用了第二种解决方案,然后使用了table.getValueAt(table.getSelectedRow(),4);
@camickr 提到了我在第二种方法中看到的唯一问题:“当您将宽度设置为 0 时,请尝试使用制表符,当您点击隐藏列时焦点会消失,直到您再次制表符。这会让用户感到困惑。”
【讨论】:
您可以创建模型的子类,并按如下方式覆盖TableModel.getColumnCount:
int getColumnCount() {
return super.getColumnCount()-2;
}
最后两列将不会显示在JTable 中。
【讨论】: