2011-10-24 2 views
1

거기에 모든 문제를 해결할 수있는 것처럼 보이는 모든 스레드를 읽었으며 여기에 대한 모든 대답도 읽었지만 여전히 위트가 있습니다. 종료. 이 예외가 throw 된 이유는 확실하지 않지만, threading과 관련이 있다고 생각합니다. 그렇다면 new Runnable()을 어디에 넣어야하는지, invokeLater() 또는 invokeAndWait()이 될지 알려주십시오. 아무 소용이 없으므로 시도해보십시오.ArrayIndexOutOfBoundsException : -1 JTable 작성/tablechanged

예외와 스택 추적 (아래)으로 연결되는 코드를 제공하면서 나와 함께하시기 바랍니다.

편집가 : tableChanged를 호출하고 콘솔에 표시되지 않습니다 바로 전에 나는 AnnoTable 섹션에서 syso s의 수를 포함했다, 따라서 그 문제는 응용 프로그램이 해당에 도달하기도 전에 발생해야합니다 생각 점, 즉 하나 그것은 ... AAView하거나 데이터와 테이블 모델이 인스턴스화에서라고 할 때

편집 II : 문제는 덮어 tableChanged 방법이었다. 그것은 분명히 예외를 발생시킬 것입니다. 나는 tableChanged() 콜을 제거했는데 (차이는 없었을 것이다). 이제 또 다른 문제가 있습니다. 기본 데이터 (AnnoData)의 변경이 테이블을 자동으로 업데이트하는 방법을 이해합니다. 이것은 아마도 다른 검색어 (확장 된 Google 검색 후) 일지 모르지만이 글에 유용한 글을 게시 하시길 바랍니다. 글을 계속 읽으면서 ... 유용한 모든 의견과 팁을 제공해 주시면 감사하겠습니다.

EDIT III : * 문제점을 해결했습니다. AnnoData에서 다른 객체를 인스턴스화하고 AnnoTableModel이라는 새 인스턴스로 전달하고이 인스턴스를 내 테이블로 설정 한 다음 fireTableDataChanged()으로 설정해야합니다.

편집 IV : 그래, 결국 fireTableDataChanged() (EDIT 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! 
    } 
} 

당신이 (세 Vector<Object>과 열 제목의 String[]을 포함하는 Vector를 구성) 또는 AnnoData (매우 일반적인 AbstractTableModel의 확장) AnnoTableModel()에 대한 소스 코드가 필요하면 알려 주시기 바랍니다.

여기에 스택 추적이 있습니다. 이건 정말 스레딩 문제가 될 수도 있습니다 내가 배운 것과 있도록

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()을 호출하는 방법을 알지 못합니다.

AnnoTableJPanel이 아닌 JTable으로 변경했을 때 예외가 표시되기 시작했습니다. 원래 나는 AnnoTable을 가지고 있었을뿐만 아니라 테이블을 구성 할뿐만 아니라 스크롤 창에 포장하여 이것을 새로운 JPanel에 추가했습니다. 그러나 내가 AAView (setAnnoTable() 메서드가있는 기능)을 알고있는 클래스의 fireTableDataChanged을 원했기 때문에 올바른 방법으로 작업하기를 원했지만 이전에는 문제가 없었습니다. 머피의 법칙?

답변

4

-1의 rowIndex (== TableModelEvent.HEADER_ROW)는 모델의 구조가 완전히 변경된 것을 나타냅니다. 이러한 이벤트는 setModel의 JTable에 의해 내부적으로 시작됩니다. 청취자의 tableChanged에서 예상되는 유형/값을 완전히 이해하려면 TableModelEvent의 API 문서를 읽으십시오.

표제 코드에서 TableModelEvents를 실행할 필요가 없습니다. @AKJ가 맞습니다. 모델을으로 적절하게 처리하십시오.

+0

우수 캐치 +1 – mKorbel

+0

@kleopatra : 감사합니다. 물론 필자의 경우'setModel()'은받지 못한 매개 변수를 받기를 기대하면서 하드 코드 된'tableChanged()'(cf. EDIT II)를 호출 할 것입니다. 방법을 삭제했습니다. 이제 테이블이 올바르게 표시되지만, annoData'에서 모든 것이 설정되고 난 후'((AbstractTableModel) aaView.getAnnoTable(). getModel()). fireTableDataChanged()'메소드를 통해'), 테이블은 여전히 ​​업데이트되지 않습니다 ...아마도 새로운 쿼리에서 물어보아야 할 것입니다. 여기 누군가가 빠른 대답을하지 않는 한 :). 모두에게 감사드립니다! –

+1

_do not_ 모델 외부의 코드에서 모델의 모든 fireXX 메소드를 호출하지 않습니다. 대신 어떤 것이 변경되었을 때 _model_을 구현하십시오. – kleopatra

2

이것은 행 또는 열로 -1을 전달한다는 것을 의미합니다. 허용되지 않습니다. 정확한 값을 전달하십시오.

2

나는 당신의 문제가 여기에있다 느낌이 :

당신이 row 또는 column 값을 지정하지 않았기 때문에
TableModelEvent tme = new TableModelEvent(tableModel);  
this.tableChanged(tme); 
-> 
    int column = e.getColumn();  
    AbstractTableModel model = (AbstractTableModel)e.getSource();  
    String columnName = model.getColumnName(column); 

getColumn()getRow() 호출하면 다음 getValueAt()에 전달하는 -1을 반환합니다 .

TableModelEvent의 생성자를 살펴보십시오. 행/열 값을 지정하는 옵션이 있습니다.

+0

잘못된 - 상위 두 줄은 예외와 관련이 없습니다 (stacktrace :-) 참고 사항 외에도 분석은 정확합니다. 리스너 코드는 '특수 값 '(HEADER_ROW, ALL_COLUMNS) 행/열 색인 – kleopatra

2
TableModelEvent tme = new TableModelEvent(tableModel); 
this.tableChanged(tme); 

이 호출이 필요하지 않습니다. 다른 포스터가 지적한 것처럼 이것이 문제의 원인입니다.

테이블 모델을 올바르게 구현하는 경우 테이블 모델을 업데이트 할 때마다 jtable이 자동으로 알림을받으며 tableChanged() 메서드도 작성할 필요가 없습니다. 그래서 tableChanged()를 명시 적으로 호출해야하는 이유가 없어졌습니다.

테이블을 업데이트 할 때마다 모델을 업데이트하면됩니다. 또한 언뜻보기에는 관련 스레딩 문제가없는 것처럼 보입니다.

0

귀하의 AnnoTable 생성자가 불완전하게 구성된 "this"객체에 대한 참조를 누설하고 있습니다. 또한 리스너를 생성자에서 등록하는 것은 안전하지 않습니다. enter link description here

생성자에서 가능한 한 적은 양의 작업을 수행하여 개체를 만든 다음 완전히 빌드 된 개체를 조작하십시오. 청취자 추가, 모델 조정, fireEvents 등 ...

관련 문제