JTable.removeColumn()方法抛出异常

时间:2012-09-01 03:23:07

标签: java swing jtable swingworker event-dispatching

要仅从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)

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

2 个答案:

答案 0 :(得分: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方法中将其删除

答案 1 :(得分:1)

阅读有关SwingWorker的教程并使用

  • process()

  • publish()

  • setProgress()

Swing JComponents

通知,添加,删除,修改doInBackground()