2010-06-16 2 views
3

2 테이블 (JTable) 그들의 DefaultTableModels 함께 사용하고 있습니다. 첫 번째 테이블이 이미 채워져 있습니다. 두 번째 테이블은 SQL 쿼리를 사용하여 첫 번째 테이블의 각 행에 채워집니다. 나의 목적은 첫 번째 테이블의 모든 라인을 Excel 파일의 두 번째 라인과 함께 내보내는 것입니다.JTable 및 모델 이상한 문제 (아마 스레드 문제)

for (첫 번째 테이블의 각 행에 대해) Excel 파일의 첫 번째 테이블의 행을 작성한 다음 두 번째 테이블 (이 첫 번째 테이블의 행)을 채 웁니다. 나는 테이블에서 모든 라인을 얻는다. (실제로는 Model이다.) 그리고 Excel 파일에 첫 번째 테이블의 현재 라인 아래에 놓는다. 즉, 첫 번째 테이블에 n 줄이 있으면 두 번째 테이블을 n 번 지우고 다시 채 웁니다.

이 코드는 모두 별도의 스레드에서 호출됩니다.

문제 : 모든 것이 완벽하게 작동하며 일부 예외가 발생합니다. 이상한 점은 나는 내 결과에서 어떤 것도 거짓말을하지 않는다는 것입니다. Excel 파일이 완벽합니다.

예외의 라인의 일부

은 다음과 같습니다 java.util.Vector.elementAt (벡터에서 0> = 0 : 스레드 "AWT-EventQueue의-0"java.lang.ArrayIndexOutOfBoundsException의

예외입니다. java : 427) 에서 javax.swing.table.DefaultTableModel.getValueAt (DefaultTableModel.java:632) 에서 javax.swing.JComponent.paint (JComponent.java:1017) 에서 javax.swing.RepaintManager.paint (RepaintManager. java : 1220) at javax.swing.RepaintManager.paintDirtyRegions (RepaintManager.java:803)

나는 두 번째 테이블에 데이터를 가져 오기 전에 채워지는 데 더 많은 시간이 필요하다는 사실에 문제가 있다고 가정합니다. 그래서 예외적으로 RepaintManager 및 paintDirtyRegions가 표시됩니다. 또 다른 것은 디버그 모드에서 프로그램을 실행했고 두 번째 테이블의 각 채우기 후에 중단 점을 넣었습니다. 그런 다음 두 번째 테이블의 각 모집단에 대해 F5 키를 눌러도 예외가 나타나지 않았습니다. 프로그램은 예외없이 끝났습니다. 이것은 또 다른 중요한 사실입니다.이 경우에는 테이블에 채워질 충분한 시간을 주었을 것입니다. 물론

당신이 저를 요구한다 : 당신의 프로그램이 잘 작동

  • 경우, 당신은 왜 예외에 대한 상관이야? 향후 문제를 피하고 Java 및 Java GUI 및 스레드에 대해 더 잘 이해하고 있습니다.

  • 정보를 얻기 위해 GUI 구성 요소 (및 모델)에 의존하는 이유와 SQL 쿼리를 사용하여 테이블을 채우고 결과 집합에서 정보를 가져 오는 결과 집합을 다시 만들지 않는 이유는 무엇입니까? 그것은 최선의 방법 일 것입니다. 사실 나는 테이블 코드 준비가되어 있고 그것들로부터 정보를 얻는 것이 더 쉬웠다. 그러나 올바른 방법은 데이터베이스에서 모든 것을 직접 가져 오는 것입니다. 어쨌든 내 질문을 꺼내서 대답하면 자바에 대한 더 많은 것들을 이해하는 데 도움이 될 것입니다. 그래서 나는 그것을 게시했다.

답변

2

스윙 API는 thread에 대해서 안전하지 않고, 몇 가지 방법은 호출을 제외 : 재 페인트, 를 재 검증하고, 을 무효로합니다. 특정 클래스에 대해 별도로 명시하지 않는 한 모든 기타 호출은 이벤트 발송 스레드에서 수행해야합니다. 스폰 배경/작업자 스레드에서 콜 이동 처리

SwingUtilities.invokeLater() 또는 SwingUtilities.invokeAndWait() 통해 수행 될 수있다.

JTable과 javax.swing package summary javadocs에 인스턴스에 연결된 TableModel에 관한 몇 가지 구체적인 설명이 있습니다. 어느 것도 스레드로부터 안전하지 않으므로 데이터를 액세스하는 모든 호출은 Event Dispatch Thread에서 수행되어야합니다.

발생하는 가장 일반적인 원인은 디버거에서 발생할 때와 다른 동작으로 경쟁 조건의 전형적인 징후입니다. 자신의 잠금 장치 등을 도입하여이 문제를 해킹 할 수있는 확실한 방법도 없습니다. 이러한 관행은 오랫동안 Swing이 진정으로 진정으로 문제였던 (장기간에 이벤트 발송 대기열 잠금 장치가있는 교착 상태와 같은) 문제를 야기했습니다. 스레드로부터 안전하도록 설계되지 않았습니다.

+0

감사합니다. 나는 스윙과 쓰레드에 관한 것들을 일반적으로 읽어야한다. –

1

테이블 모델 중 하나가 getValueAt (int row, int column) 호출에 대해 null을 반환하기 때문에 예외가 발생합니다.그 이유는 데이터 모델에 액세스하기 위해 보조 스레드를 사용하고 있기 때문에 스윙 또는 데이터 모델의 내부 문제 일 가능성이 높습니다. 스윙 API는 구체적으로 설명 된 방식으로 보조 스레드를 사용할 수 없다고 명시합니다.

다음 문서에서는 스윙의 단일 스레드 규칙에 대해 자세히 설명합니다.

http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html