2012-04-07 2 views
1

프레임에 JFrameJTable이라는 간단한 문자가 있습니다. 사용자는 테이블의 행에 데이터를 제공 할 수 있습니다. 요구 사항 중 하나는 프레임을 닫은 후 새 데이터를 저장하거나 삭제할 수 있다는 것입니다. 프레임의DefaultTableModel의 dataVector 복제 문제

  1. 오버라이드 setVisible() 방법과 DefaultTableModel의 데이터 벡터를 복제 :이 동작을 수행하는 가장 쉬운 방법은 다음과 같은 것을 생각했다.

  2. 프레임에 WindowListener을 추가하고 WindowClosing 이벤트에 대해 반응합니다. 이렇게하면 창 수신기는 모델을 이전에 저장 한 모델로 다시 설정해야하는지 여부를 결정할 수 있습니다.

    @Override 
    public void setVisible(boolean b) { 
        //save the original models only if setVisible invoked with true (do not save the model when hiding the frame) 
        if (b) { 
        Vector cloned = (Vector) userTableModel.getDataVector().clone(); 
        Vector headerNames = new Vector(); 
        originalModel = new CustomTableModel(cloned, headerNames); 
        } 
        super.setVisible(b); 
    } 
    

    는 사실, 뭔가 이상한 일이 일어나고 :

여기에 관련 코드입니다. I는 데이터 벡터를 복제 한 후, 테이블은 렌더링이 다음 예외로 연결되지 않을 수

 
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0 
    at java.util.Vector.elementAt(Vector.java:470) 
    at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:650) 
    at asc.model.CustomTableModel.getValueAt(CustomTableModel.java:74) 
    at javax.swing.JTable.getValueAt(JTable.java:2720) 

테이블은 어떤 방식으로 관련 originalModel 아니다. 이론 상으로는 복제가 테이블의 모델에 영향을주지 않아야하기 때문에 놀랍습니다. originalModel의 의도는 새로 생성 된 테이블 모델의 복사본에 대한 참조를 유지하는 것입니다. originalModel의 생성을 주석 처리하고 나면 모든 것이 잘 동작합니다. 나는 headerNames 벡터에 빈 String을 추가 할 때 또 다른 흥미로운 점은

, 테이블 렌더러는 거의 같은 ArrayIndexOutOfBounds 예외가 발생하지만,이 엔딩 :이 경우

 
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1 

,의 첫 번째 열 첫 번째 행은 완벽하게 렌더링됩니다.

CustomTableModelDefaultTableModel에서 확장되었으며 특별한 방법은 사용하지 않습니다. 생성자는 단순히 데이터 벡터와 헤더 벡터를 수퍼 클래스에 전달합니다.

누군가가 문제를 해결하는 데 도움이되기를 바랍니다. 미리 감사드립니다. 당신이 경우에 Vector<Vector>을 기반으로 Vector하지만 JTable 일반 반환에 노력하기 때문에

+2

더 나은 도움을 받으려면 [SSCCE] (http://sscce.org/) – mKorbel

답변

1

나는, 당신이 Vector cloned에 실수가 있다고 생각 headerNames 벡터의 길이는 당신이했습니다 열 수와 일치하는

1

알았어. Vector가 CustomTableModel 클래스 안에있는 헤더 이름의 배열로 변환되기 때문에 혼란 스럽습니다. 이것이 AIOOBE로 나타나는 이유입니다.

따라서 첫 번째 열은 첫 번째 열 (인덱스 0의 열)에 대해 headerNames 벡터/배열을 찾고 오류가 발생하여 오류가 0> = 0 인 버전을 보냅니다. 일단 열 이름 문자열을 추가하면 (비어있을 수도 있지만 비어 있음) 첫 번째 열 전체를 성공적으로 렌더링 한 다음 두 번째 열 (색인 1의 열)을 찾습니다. headerNames 벡터에 두 번째 요소가 없으므로 오류가 발생하고 1> = 1 버전의 오류가 발생합니다.

headerNames 벡터에 올바른 수의 값 (데이터 벡터의 열 수와 일치)이 있는지 확인하고 잘 보내야합니다.

주 - clone() 메서드는 데이터의 SHALLOW 복사본을 만들고 있으므로 사용자가 셀의 데이터를 변경하면 여전히 원래 객체가 변경됩니다. 이 도움말은 다음과 같이 도움이 될 수 있습니다. http://javatechniques.com/blog/faster-deep-copies-of-java-objects/.

1

AbstractTableModel을 구현하면 데이터 구조를 직접 제어 할 수 있습니다. 이 exampleMap<String, String>을 나타내지 만 선택은 임의입니다.