【问题标题】:JTable.removeColumn() method throws exceptionJTable.removeColumn() 方法抛出异常
【发布时间】:2012-09-01 03:23:06
【问题描述】:

要仅从 JTable 的视图中隐藏一列,我使用removeColumn() 方法。但它会抛出异常

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 7 >= 7
at java.util.Vector.elementAt(Vector.java:470)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:648)

我认为,从视图中删除列后,如果我修改了模型,则会弹出此异常。是因为模型正在更新表时视图中没有列吗?

在 JTable 中隐藏列的最佳方法是什么?而不是将大小设置为 0

编辑: 异常不会定期发生。这是一个随机例外。无论如何这里是代码:

    @Override
        protected Object doInBackground() throws Exception {
        ........
        resultDTO=//get data from database
        tableModel.setDataVector(resultDTO.getAllRows(), tableModel.getColumnNames());    
        // hide column
        table.removeColumn(table.getColumnModel().getColumn(7));
            System.out.println("table column count : " + table.getColumnCount());
            System.out.println("model column count : " + tableModel.getColumnCount());
        ........
        .........       
        }



initial result (with out any data in table, at application startup): 
table column count : 7
model column count : 8

after populating data (first running of above method):
table column count : 7
model column count : 8

after few times executing : 
table column count : 7
model column count : 8
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 7 >= 7
    at java.util.Vector.elementAt(Vector.java:470)
    at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
    at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:648)
    at javax.swing.plaf.synth.SynthTableHeaderUI.paint(SynthTableHeaderUI.java:173)

有时在我第一次加载数据时会发生上述异常,有时则不会。

【问题讨论】:

  • 我看到模型在尝试绘制时抛出了异常。在您删除一列并将其减少到 7 之后,该模型是否仍有可能报告总共有 8 列?这里真的没有太多信息可供我们继续。
  • 看起来类似于Bug ID: 6586009
  • 您是否尝试从 EDT 外的模型中移除该列?

标签: java swing jtable swingworker event-dispatching


【解决方案1】:

您正在尝试更新 Event Dispatching Thread 之外的 UI 组件,这绝不是一个好主意

protected Object doInBackground() throws Exception {
    ........
    resultDTO=//get data from database
    // This shouldn't be done here
    tableModel.setDataVector(resultDTO.getAllRows(), tableModel.getColumnNames());  
    // and neither should this
    // hide column
    table.removeColumn(table.getColumnModel().getColumn(7));

尽管使用SwingWorker,但还是要竖起大拇指。问题是,Swing 组件不是线程安全的,您永远不应该尝试在 EDT 之外更新它们,因为它们会导致意外结果(就像您刚刚遇到的那样)。

与其直接设置行数据,我建议使用publish/process 方法。如果您无法决定何时删除该列,我会在工作人员执行之前或在工作人员done 方法中删除它

【讨论】:

  • 好的,我只想知道关于摇摆工人的一件事。如果doInBackground()执行过程中出现异常,会发生什么?
  • @sanjeev 这是一个很好的问题! doInBackground 是从 Callable 调用的,而 Callable 又是由 ExecutorService 启动的...通常,它们会被吸收...执行后无法获得对 Callable 的引用。但是,您可以在代码中添加一个 try/catch 块并捕获任何可能被抛出的执行,然后我将维护一个以后可以获得的引用,例如在 done 方法中
【解决方案2】:

阅读有关SwingWorker的教程并使用

  • process()

  • publish()

  • setProgress()

用于通知、添加、删除、修改 Swing JComponents from doInBackground()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    相关资源
    最近更新 更多