我已经阅读了所有线程,看起来好像可以解决我的问题,我也已经阅读了这里的所有答案,但我仍然在我的智慧结束。我不确定为什么抛出异常,尽管我觉得这可能与threading
有关。如果确实如此,请告诉我包含new Runnable()
以及是invokeLater()
还是invokeAndWait()
的位置,因为我尝试过无效。
在我给你的代码导致异常+堆栈跟踪(下方)时,请耐心等待。
编辑:我在调用syso
之前的AnnoTable
部分中添加了一些tableChanged
个,但是他们没有出现在控制台,因此我认为问题必须在应用程序到达那一点之前发生,即从AAView
调用它或者实例化数据和表模型时......
编辑II :问题是被覆盖的tableChanged
方法。这显然会引发异常。我已经删除了tableChanged()
电话(这也没有什么区别)。现在我遇到了另一个问题:了解底层数据(AnnoData
)的更改如何自动更新表。虽然这可能是针对另一个查询(在扩展的Google搜索之后),但请随时在此主题中发布有用的评论,因为我将继续阅读它...感谢所有有用的评论和提示!
编辑III:* 我已经解决了这个问题。我需要从AnnoData
实例化另一个对象,将其传递给AnnoTableModel
的新实例,将此实例设置为我的表格,然后设置为fireTableDataChanged()
。
编辑IV:好的,所以fireTableDataChanged()
(在编辑III中使用)毕竟是不必要的。我仍然想要使用它而不是一直创建新对象。我想我应该问一个新问题......谢谢!
AAView
中的此方法应该创建一个扩展JTable
的对象,将其放入JScrollPane
等等(后者确实有效)。
private JPanel createAnnoTablePanel() {
annoTablePanel = new JPanel();
annoTable = new AnnoTable(aameth);
setAnnoTable(annoTable);
JScrollPane scrollPane = new JScrollPane(getAnnoTable());
annoTablePanel.add(scrollPane);
return annoTablePanel;
}
这是类AnnoTable
(aameth
是一个实例对象,包含访问数据模型的业务逻辑,工作正常)。
public class AnnoTable extends JTable implements TableModelListener
{
public AnnoTable(AAMethods aameth)
{
int tokenCount = aameth.getTokenCount();
AnnoData annoData = new AnnoData(aameth); // cf. below, AnnoData is a Vector(Vector<Object>,String[])
TableModel tableModel = new AnnoTableModel(annoData.getAnnoData(),
// AnnoTableModel extends AbstractTableModel(Vector, String[])
annoData.getColTitles());
setModel(tableModel);
getModel().addTableModelListener(this);
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setCellSelectionEnabled(true);
getColumnModel().getSelectionModel().addListSelectionListener(new AnnoTableSelectionListener(this));
setPreferredScrollableViewportSize(this.getPreferredSize());
}
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
AbstractTableModel model = (AbstractTableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column); // This is where the exception is thrown!
}
}
如果您需要AnnoTableModel()
的源代码(这是AbstractTableModel
的相当通用的扩展名)或AnnoData
(构建包含三个Vector
的{{1}} Vector<Object>
和列String[]
的列标题,请告诉我。
这是堆栈跟踪。
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
at package.AnnoTable.tableChanged(AnnoTable.java:52)
at javax.swing.JTable.setModel(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at package.AnnoTable.<init>(AnnoTable.java:25)
at package.AAView.createAnnoTablePanel(AAView.java:464)
at package.AAView.createNorthPanel(AAView.java:455)
at package.AAView.displayAndAnnotate(AAView.java:444)
at package.AAView.loadProject(AAView.java:333)
at package.AAView.actionPerformed(AAView.java:286)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(Unknown Source)
at javax.swing.SwingUtilities.notifyAction(Unknown Source)
at javax.swing.JComponent.processKeyBinding(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processKeyBinding(Unknown Source)
at javax.swing.KeyboardManager.fireBinding(Unknown Source)
at javax.swing.KeyboardManager.fireKeyboardAction(Unknown Source)
at javax.swing.JComponent.processKeyBindingsForAllComponents(Unknown Source)
at javax.swing.JComponent.processKeyBindings(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我可以在那里看到EDT
所以从我所知道的这可能是一个线程问题。但是,我不知道如何找到我应该在哪里开始新Thread
(或调用new Runnable()
。
在旁注中,当我将AnnoTable
更改为JTable
而不是JPanel
时,异常才会开始显示。最初我有AnnoTable
不仅构造表,而且还将其包装在滚动窗格中,并将其添加到新的JPanel
。但是因为我想从一个只知道fireTableDataChanged
的类AAView
(其中还有一个setAnnoTable()
方法),我想以正确的方式做到这一点,而在它工作之前就好了。墨菲定律?
答案 0 :(得分:5)
rowIndex为-1(== TableModelEvent.HEADER_ROW)表示模型的结构已完全更改。这样的事件由JTable在setModel上内部触发。阅读TableModelEvent的api文档,以完全理解在侦听器的tableChanged中期望的类型/值。
BTW,@ AKJ是对的 - 无需在表代码中触发任何TableModelEvents。使模型适当地触发事件
答案 1 :(得分:3)
这意味着您将-1
作为行或列传递。这是不允许的 - 确保传递正确的值。
答案 2 :(得分:3)
我觉得你的问题在这里:
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
->
int column = e.getColumn();
AbstractTableModel model = (AbstractTableModel)e.getSource();
String columnName = model.getColumnName(column);
由于您未指定row
或column
值,getColumn()
和getRow()
调用将返回-1,然后您将传递给{{1 }}。
尝试查看TableModelEvent的构造函数。它具有指定行/列值的选项。
答案 3 :(得分:3)
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);
我认为不需要这个电话。正如其他海报所指出的,这是导致问题的原因。
如果正确实现表模型,每当更新表模型时,jtable将自动获得通知,您也不需要编写tableChanged()方法。所以我很遗憾为什么你需要明确地调用tableChanged()。
每当您想要更新表时,只需更新模型即可。乍一看似乎没有涉及任何线程问题。
答案 4 :(得分:0)
你的AnnoTable构造函数正在泄漏对未完全构造的引用&#34; this&#34;宾语。此外,从构造函数注册监听器是不安全的。 enter link description here
在构造函数中尽可能少地构建对象,然后对完全构建的对象进行操作。添加监听器,调整模型,fireEvents等......