eclipse 셀렉션 서비스 사용 주의사항
eclipse는 파트(뷰/에디터)간의 약한 결합을 위한 의사소통 수단으로 셀렉션 서비스를 이용합니다. 셀렉션 서비스에 대한 내용은 번역해둔 eclipse 기술문서를 참조하세요.
그런데 셀렉션 서비스를 이용하는데 모든 파트의 선택을 Listen하는지 아니면 특정 파트의 선택을 Listen하는지에 따른 큰 차이점이 있습니다.
예제는 두 개의 뷰를 가진 간단한 eclipse RCP 어플리케이션입니다.
그림1. 예제 어플리케이션
View1은 모든 eclipse 파트의 선택을 Listen하며 View2는 View1에서의 선택만을 Listen하고 있습니다. 예제는 View1 이외의 파트가 View2 뿐이므로 완전히 동일한 행동을 예상하게 됩니다. View1과 View2의 셀렉션 프로바이더 설정과 셀렉션 리스너를 등록하는 코드는 다음과 같습니다.
- // View1.java
- public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setInput(getViewSite()); - // TableViewer의 선택을 외부로 내보내도록 설정
getSite().setSelectionProvider(viewer); - // View1이 eclipse 모든 파트의 선택을 listen하도록 설정
getSite().getPage().addSelectionListener(this); - }
- // View2.java
- public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setInput(getViewSite()); - // TableViewer의 선택을 외부로 내보내도록 설정
getSite().setSelectionProvider(viewer); - // View2가 View1의 선택에 대해서만 listen하도록 설정
getSite().getPage().addSelectionListener(View1.ID, this);
}
자신이 Listen하고 있는 파트에서 발생한 셀렉션을 처리하기 위해 ISelectionListener를 구현한 코드는 View1과 View2 모두 동일합니다. 단순히 자신이 내보낸 셀렉션은 무시하고 셀렉션이 발생한 파트의 이름과 셀렉션 요소를 이름을 콘솔에 출력합니다.
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (part == this) { // 자신이 내보낸 셀렉션은 처리하지 않음
return;
}
IStructuredSelection iss = (IStructuredSelection) selection; - // 셀렉션이 발생한 파트의 이름과 셀렉션 요소를 콘솔에 출력
System.err.println(part.getTitle() + ": " + iss.getFirstElement()); - }
이런 경우 아마도 View1과 View2의 동일한 행동을 예상하겠지만 이에 따른 반응이 다릅니다. 우선 View1과 View2의 출력 결과를 비교하기 위해서 둘 다 Three 요소를 선택했습니다. 아무 요소도 선택하지 않은 경우에도 차이점을 비교할 수 있지만 이전 선택이 영향을 미치는 걸 보이기 위해서 선택했습니다.
그림2. View1과 View2의 초기 선택
여기서 두 뷰 모두 One이라는 요소를 선택해 보겠습니다. View1을 선택했을 때 이를 전달 받은 View2에서 출력하는 내용은 다음과 같습니다.
그림3. View1의 선택에 따른 결과 값
View2를 선택했을 때 이를 전달 받은 View1의 출력 결과는 다음과 같습니다.
그림4. View2의 선택에 따른 결과 값
무언가 차이점을 발견했는지요? View2는 View1만을 Listen하고 있기에 현재선택(One)만을 전달 받았지만 모든 파트의 셀렉션을 Listen하고 있는 View1의 경우 View2의 이전 선택(Three)과 현재 선택(One) 모두를 셀렉션으로 전달 받습니다. 대부분의 경우 셀렉션을 전달받은 파트가 빠르게 반응하기 때문에 이전 셀렉션이 전달된다는 사실을 알 수 없습니다. 하지만 셀렉션을 전달받아 수행하는 작업이 무거운 작업이라면 두 번의 셀렉션이 전달되는 건 얘기치 못한 성능상의 문제점을 야기할 수 있습니다. 저 역시 셀렉션이 전달되면 애니메이션 효과를 보여주는 동작을 취하다가 두 번 그려지는걸 보고서 발견했으니까 말이지요. 현재로서는 이런 경우에는 특정 파트를 Listen하게 하는게 해결책입니다.
eclipse가 내부적으로 전체 리스너의 목록과 각 파트별 리스너의 목록을 별도로 관리하면서 발생하는 상황으로 생각이 되지만 정확한 원인은 모르겠습니다. 예전에 eclipse 버그질라에 포스팅 했었지만 빈약한 영어 문장 때문인지 아무런 응답도 받지 못했습니다. 3.3.1 버전까지 버전업하면서도 아무런 수정이 없는게 의도된 행동일지 모르겠네요 ^^'. 전체 파트를 Listen하는 것과 특정 파트를 Listen하는 것의 차이점을 알고 주의해서 사용할 필요가 있습니다.
아무래도 외국 eclipse 커뮤니티 사이트에 질문을 올려보고 관련 소스코드를 열어봐야겠습니다. 결과가 돌아오면 다시 포스팅 하겠습니다. 예제 코드는 첨부합니다.
이 글은 스프링노트에서 작성되었습니다.
'개발 이야기' 카테고리의 다른 글
| 플러그인 스파이(Plug-in Spy) (0) | 2009/12/06 |
|---|---|
| Eclipse 애플리케이션에서 웹 브라우저 띄우기 (0) | 2009/12/06 |
| Snow Note (0) | 2009/12/06 |
| 사용자 인터페이스(UI) 가이드라인 (0) | 2009/12/06 |
| eclipse 셀렉션 서비스 사용 주의사항 (0) | 2009/12/06 |
| eclipse 워크벤치: 셀렉션 서비스 이용하기 (0) | 2009/12/06 |



