2011-03-21 6 views
1

개발중인 스윙 앱에서 계속 페인트 칠하는 데 이상한 문제가 있습니다. 나는 특정 구성 요소의 텍스트를 설정할 때 (화면의 맨 아래에있는 상태 표시 줄의 텍스트 레이블 일뿐) 화면의 매우 다른 영역에있는 전체 테이블을 다시 그리라고 말하고 있습니다. 기본적으로 전체 창에 상태 표시 줄 텍스트를 설정할 때마다 다시 그리기를 요청하는 것처럼 보이기 때문에 일부 성능 문제가 발생합니다.스윙 내에서 발생하는 불필요한 다시 그리기를 디버그하는 방법

무슨 일이 일어나고 있는지 RepaintManager 주위를 배회하고 있었고이 텍스트의 레이블을 설정하려고 할 때 내 전체 JPanel이 더티 컴포넌트로 표시된다는 것을 알았습니다. 그러나 에서 디버깅하는 데 문제가 있습니다. 어떤 점이 발생하고 있으며 정확히 인 이유는 무엇입니까? 전혀 발생하지 않습니다. 필자는 페인트 칠하는 시스템을 읽으려고했지만 다른 텍스트 레이블이 설정되어있을 때 중첩되지 않는 테이블을 다시 그리는 것이 왜 필요한지 알 수 없습니다.

스윙 탐색기를 사용하여 레이아웃 테두리를 시각적으로 보여 주면서 모든 것이 깔끔하게 겹치지 않고 모든 것이 잘되는 것처럼 보입니다.

JTable에 다시 그리기를 요청하는 호출 순서를 결정하는 방법을 찾고 있습니다. paintComponent()에 중단 점을 추가하고 스택을 따라 가면 RepaintManager의 paintDirtyRegions() 호출 내에서 끝나고, 전체 JPanel (창에있는 모든 내용 포함)은 tmpDirtyComponents 변수 안에 있습니다.

처음에는 단일 상태 텍스트 레이블을 설정할 때 내 JPanel이 더티로 표시되는 방법을 설명 할 수 있습니까? 그렇지 않은 경우 오류를 찾기 위해 어디서 연결해야하는지에 대한 지침을 제공 할 수 있습니까?

도움을 주셔서 감사합니다.

+2

아마도 JComponent.invalidate에 중단 점을 넣어 더티 영역 생성의 원인인지 확인해야합니다. 물론, 디버거가 응용 프로그램에 끼어 들자 더러운 영역이 생기므로 응용 프로그램을 디버거와 별도로 유지하십시오. – MeBigFatGuy

+0

네, 그 재밌는 일이 다시 칠판을 트리거 할 때 디버거에 초점을 맞추면 정말 재밌습니다. 다시 그리기 등을 유발하는 앱으로 돌아와야합니다. – krock

답변

1

어떻게 든 레이아웃 관리자를 변경하여이 문제를 해결할 수있었습니다. 내 메인 패널에서 GroupLayout을 사용하고있었습니다. 전반적인 GroupLayout이 매우 간단했기 때문에 BorderLayout을 대신 사용해 보았습니다. JPanel의 기본 윈도우 내용이 BorderLayout.CENTER에 추가되었고 BorderLayout.PAGE_END의 상태 표시 줄 레이블이 추가되었습니다. 그것은 상태 레이블 텍스트를 설정할 때 이상한 무효화와 전체 창 다시 그리기를 수정합니다! 모두에게 감사의 말씀을 전합니다!

1

Swing 구성 요소에서 속성을 변경할 때마다 구성 요소에서 revalidate() 및 repaint()가 호출됩니다. 텍스트를 설정하면 구성 요소의 기본 크기가 변경 될 수 있으므로 레이아웃 관리자를 호출하고 전체 패널을 다시 그려야합니다.

이 문제를 해결하는 방법을 모르겠습니다.

+0

텍스트 레이블 구성 요소의 기본 크기를 그대로 유지하면 다시 그리기가 중단됩니다. 나는 그 라인들을 따라 뭔가를 시도 할 것입니다 ... – aardvarkk

+0

그것이 효과가 있을지 확실하지 않습니다. revalidate() 메소드에 대한 API를 읽으십시오. 어쩌면 구성 요소의 isValidateRoot() 메서드를 재정의하거나 JPanel을 만들고이 메서드를 재정의 한 다음 레이블을 추가 할 수 있습니다. 전체 프레임의 유효성을 다시 검사하지 못할 수 있습니다. – camickr

1

camickr의 의견을 추가하기 만하면 문제가있는 구성 요소에 대한 isValidateRoot()를 재정의하는 것이이 문제의 올바른 해결책이며 일반적으로 불필요한 다시 그리기 문제를 해결하는 올바른 해결 방법입니다.

단점은 당신의 isValidateRoot 구성 요소 에 변화가 실제로 크기를 변경하는 구성 요소를 필요로 않는 경우, 당신은 (myValidateRoot.getParent은(). 무효()를 수행해야합니다) 수동으로 재 검증을 강제해야 할 것입니다.

관련 문제