본문 바로가기

Lecture & Tip/eclipse_android

JTextArea.getText의 무서움.

로깅 뷰어가 필요해서 swing으로 하나를 만들었다.

근데 가로막힌 문제가 로그의 양이 매우 많고 빨리 찍히다보니

JTextArea에 그리는 것이 문제가 되었다.

실제 타겟의 동작은 종료되었는데 로그는 계속 찍고 있는 문제....동기가 안맞는 것이다;;; 한마디로 그리는게 느리다.

public void printMsg(String msg, Highlighter.HighlightPainter selectPainter) {

   _startPosition = _msgArea.getText().length();
  _endPosition = _startPosition + msg.length();
  _msgArea.append(msg + "\n");

//하이라이팅 
try {
   if (selectPainter != null) {
    _currentHighlighter.addHighlight(_startPosition, _endPosition,
      selectPainter);
   }
  } catch (BadLocationException e) {
   e.printStackTrace();
  }

//버퍼이상 라인 지우기
  if (_msgArea.getLineCount() > TEXTAREA_MAX_LENGTH) {
   try {
    _msgArea.replaceRange("", _msgArea.getLineStartOffset(0),_msgArea.getLineEndOffset(_msgArea.getLineCount()-TEXTAREA_MAX_LENGTH-1));
   } catch (BadLocationException e) {
    e.printStackTrace();
   }
  }
//스크롤 다운
  setScrollEnd();
 }

그래서 처음에는

스크롤 다운이 문제가 있는줄 알았다.

private void setScrollEnd() {
   if(_msgScrllBar.getValue()<_msgScrllBar.getMaximum()){
      _msgScrllBar.setValue(_msgScrllBar.getMaximum());
   }
 }
음 하지만 이것을 빼보아도 좋아지지 않았다.

아무래도 색을 칠하는 것이니 하이라이팅에 문제가 있는 거 같아서 하이라이팅 부분을 빼보았다.

역시 이것도 아니고.

String replace가 느린 것인가하고 라인지우기도 빼보았다...하지만..이것도 역시...

삽질에 삽질을 거듭하는 중.. 결국 알게된것은 충격적으로도...

_startPosition = _msgArea.getText().length();

이 놈이었다.;;;;;;

하이라이팅 시작 위치를 찾기위해 계산하는 코드에서 호출되는 getText()가 문제였던 것이다.
몇천,몇만 줄이나 되는 텍스트를 리턴하려고 하니 퍼포먼스에 지대한 문제를 주었던 것이다.

무심코 적은 한줄의 코드가 충격적인 결말을 가져왔다.

나의 삽질을 다른사람들은 피해주길 기대하며......

.
.
위의 코드는 아래와 같이 수정하여서 해결하였다.

try {
   _startPosition = _msgArea.getLineEndOffset(_msgArea.getLineCount()-1);
  } catch (BadLocationException e) {
   e.printStackTrace();
  }