2016-10-07 5 views
2

カスタムモデルを使用してJTableで2つの操作を適用します。JTableモデルのfireTableChangedイベントは、フィルタ処理後に例外をスローします。

は、まずフィルタリング操作:

// rf is a RowFilter object 
((DefaultRowSorter) table.getRowSorter()).setRowFilter(rf); 

その後、別のスレッドには、テーブルの列名を変更し、イベントを発生:

model.fireTableChanged(new TableModelEvent(model, TableModelEvent.HEADER_ROW)); 

しかし、ランタイム例外がスローされています。考えられる理由は何でしょうか?

トレースは以下のとおりです。ありがとう。

例外スレッドの "AWT-EventQueueの-0" java.lang.ArrayIndexOutOfBoundsException:-1 java.util.Vector.elementData(Vector.java:734)で でjava.util.Vector.elementAt com.jtattooでcom.jtattoo.plaf.BaseTableHeaderUI.getHeaderRenderer(BaseTableHeaderUI.java:189)で javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)で(Vector.java:477) .plaf.BaseTableHeaderUI.paintCell(BaseTableHeaderUI.java:358) at com.jtattoo.plaf.BaseTableHeaderUI.paint(BaseTableHeaderUI.java:3 2735) (javax.swing.plaf.ComponentUI.update(ComponentUI.java:161) (JComponent.java:889)を に設定します。 で、 でjavax.swing.JComponent.paintChildren(JComponent.java:889)で javax.swing.JComponent.paint(JComponent.java:1065)で javax.swing.JComponent.paintChildren(JComponent.java:889)でjavax.swing.JComponent.paint(JComponent.java:1065)at 01でのjavax.swing.JComponent.paintChildren(JComponent.java:889) のjavax.swing.JComponent.paint(JComponent.java:1065) のjavax.swing.JComponent.paintChildren(JComponent.java:889)javax.swing.JComponent.paint(JComponent.java:1065)at .swing.JComponent.paintChildren(JComponent.java:889)at にあるjavax.swing.Javaponent.paint(JComponent.java:1065) .JComponent.paintChildren(JComponent.java:889)at のjavax.swing.JComponent.paint(JComponent.java:1065) .paint(JComponent.java:1065)at javax.swing.JComponent.paintChildren(JComponent.java:889)at javax.swing.JComponent.paint(JComponent.java:1065)at javax.swing.JComponent.paintChildren(JComponent.java:889)at javax.swing.JComponent.paint(JComponent.java:1065)at .swing.JComponent.paintChildren(JComponent.java:889)at javax.swing.JComponent.paint(JComponent.java:1065)at にあるjavax.swing.JComponent.paintChildren(JComponent.java:889)javax.swing .JComponent.paint(JComponent.java:1065)at javax.swing.JComponent.paintChildren(JComponent.java:889)at のjavax.swing.JComponent.paint(JComponent.java:1065)。javax.swing.JComponent .paintChildren(JComponent。java:889) でのjavax.swing.JComponent.paint(JComponent.java:889) のjavax.swing.JComponent.paint(JComponent.java: (JComponent.java:889)、 で にある。 でjavax.swing.JComponent.paint(JComponent.java:1065)を返します。javax.swing.JComponent.paintChildren(JComponent.java:889) のjavax.swing.JComponent.paint(JComponent.java:1065) のjavax.swing.JComponent.paintToOffscreen(JComponent.java:5210)javax.swing.RepaintManager $ PaintManager.paintDoubleBuffered(RepaintManager.java:1579) at javax.swing.RepaintManager $ PaintManager.paint(RepaintManager.java:1502) でjavax.swing.JComponent.paintImmediately(JComponent.java:4969)で javax.swing.JComponent._paintImmediately(JComponent.java:5158)でjavax.swing.RepaintManager.paint(RepaintManager.java:1272)でjavax.swing.RepaintManager $ 4.run(RepaintManager.java:831)at javax.swing.RepaintManager $ 4.run(RepaintManager.java:814)at java.security.AccessController.doPrivileged(ネイティブメソッド) java.security javax.swing.RepaintManager.paintDirtyRegionsで.ProtectionDomain $ JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) でjavax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814) (RepaintManager.java:789)(RepaintManager.java:64): の場合、RepaintManager.java:738の場合は、 1732) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756) 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(ネイティブメソッド) at java.security.ProtectionDomain $ JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDあなたのスタックトレースを見てomain.java:76)

+0

メソッド '' com.jtattoo.plaf.BaseTableHeaderUI.getHeaderRenderer''は、動作しない '' DefaultTableColumnModel.getColumn(-1) ''を呼び出します。あなたのクラスでこのスタックトレースに関わっていますか? – f1sh

+0

"ソーターを使用する場合は、必ずセル座標を変換してください。" - [loc.cit。](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#sorting) – trashgod

+0

@ f1shいいえ、私は関与していません。しかし、私はEDTで 'fireTableChanged'を呼び出します。 –

答えて

0

私はjavax.swing.table.DefaultTableColumnModelへの呼び出しであるため、上記のBaseTableHeaderUI

com.jtattoo.plaf.BaseTableHeaderUI.getHeaderRenderer(BaseTableHeaderUI.java:189) 

のバグを推測:

/** 
* Returns the <code>TableColumn</code> object for the column 
* at <code>columnIndex</code>. 
* 
* @param columnIndex  the index of the column desired 
* @return the <code>TableColumn</code> object for the column 
*       at <code>columnIndex</code> 
*/ 
public TableColumn getColumn(int columnIndex) { 
    return tableColumns.elementAt(columnIndex); 
} 

BaseTableHeaderUIのように2つのスレッドに問題があります。 同じスレッド内のすべてのイベントを処理する必要がありますか?私の選択はEvent-Dipatch-Threadです。

+0

ありがとうございます。私はあなたが「2つの糸」を意味するものを得られなかった。モデル上の 'fireModelChanged'呼び出しは' SwingUtilities.invokeLater'の内部で呼び出されます。fireModelChangedはすべての変更(JTable、モデルへのリレーション、ColumnModel、Editor、Rendererなど)をデフォルト(新しいモデル定義からのもの)にリセットすることができるので、SelectionModelはそれを無視することができます。 –

+1

は、(AbstractTableModel) – mKorbel

+0

私は 'fireTableChanged'を呼び出すことを取り除きました。問題は、@trashgodが思い出すように、フィルタ操作を適用した後にテーブル行のインデックス値が変化することです。代わりに、インデックス値を表示してヘッダー値を設定するように変換して、列を繰り返し処理します。しかし、テーブルヘッダーで 'repaint'メソッドを呼び出さなければなりませんでした。 –

関連する問題