【发布时间】:2017-03-22 04:00:07
【问题描述】:
我正在评估 Swingtools JTable,它是 JTable 和 JXTable 的开源且更强大的版本。正如维护者 Ivan Portyankin 在他的博客 ipsoftware blog 上解释的那样:
"有时看起来标准的 Swing JTable 或其关闭 SwingX JXTable 之类的伙伴太有限了。你也没有 许多有趣的方式来操纵它们——它们是严格的矩形 网格,每行占用固定数量的屏幕空间(以像素为单位) 和列取自一个且唯一的列模型。列不能 跨越或拆分,并始终在网格中采用单个单元格。"
现在我正在研究隐藏列的能力,这可以通过它的界面来完成: 但是我想默认隐藏一些列并在用户手动重新启用它们时存储首选项以便显示总是最后选择的偏好。
下面我尝试将所有列默认隐藏,但会出现ArrayIndexOutOfBoundsException 错误!!
public class AdvancedTableDemo extends JFrame
{
public AdvancedTableDemo()
{
super("Advanced Table Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(600, 300);
final BaseTable baseTable = new BaseTable();
baseTable.setFilterHeaderEnabled(true);
add(new JScrollPane(baseTable));
BeanPropertyTableModel<TableBean> model = new BeanPropertyTableModel<TableBean>(TableBean.class);
model.setOrderedProperties(Arrays.asList("name", "surname", "date"));
model.setData(TableBean.generateList(100));
baseTable.setModel(model);
int j = baseTable.getColumnCount(true);
for (int i = 0; i < j; i++)
{
TableColumnExt tableColumnExt = baseTable.getColumnExt(i);
tableColumnExt.setVisible(false);
}
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new AdvancedTableDemo();
}
});
}
}
错误是:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 >= 1
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at org.jdesktop.swingx.JXTable.getColumn(JXTable.java:2265)
at org.jdesktop.swingx.JXTable.getColumnExt(JXTable.java:2415)
at demo.table.AdvancedTableDemo.<init>(AdvancedTableDemo.java:46)
at demo.table.AdvancedTableDemo$1.run(AdvancedTableDemo.java:62)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
列数为 3,但任何大于列 1 的值都会产生刚才看到的错误!尝试使用 17 列,任何大于 10 的列都返回异常。
我在这里错过了什么吗??
【问题讨论】:
-
试试这个:用
final BaseTable baseTable = new BaseTable(model);代替baseTable.setModel(model);。根据需要重新排列行。那还有这个问题吗? -
没有以模型为参数的构造函数,只有BaseTable的不带参数的构造函数。见源代码:github.com/thirdy/swingtools/blob/master/src/main/java/com/…
-
我建议这样做的原因是,对于
JTable.setModel()文档,它声明:“将此表的数据模型设置为 newModel 并注册它以接收来自新数据模型的侦听器通知。 "。无需为您设置列模型(如在JTable( TableModel )的构造函数中)。 -
我隐藏列的地方实际上并不是处理模型,而是处理 TableColumnExt,这与我尚未弄清楚的模型有何关系。但我现在看不出按照你说的做。
-
我建议您更改
BaseTable类,添加一个构造函数,该构造函数采用TableModel来调用super(dm);(并在无参数构造函数中执行其他操作),然后使用该构造函数.根据约定,TableModel的JXTable和JTable构造函数应该为您创建ColumnModel。