2010년 2월 26일 금요일

JDT 타입 선택 다이얼로그

JDT로 메서드를 추가하는 다이얼로그 개발 중 메서드의 리턴 타입이나, 파라미터 타입이 클래스 일 경우에 프로젝트에서 접근 가능한 클래스목록 중에서 선택해야 하는 요구사항이 있었다.
해결 방법부터 간단히 이야기 하면 JavaUI.createTypeDialog() 메서드를 이용하면 된다.

createTypeDialog(Shell parent, IRunnableContext context, IJavaSearchScope scope, int style,
boolean multipleSelection, String filter, TypeSelectionExtension extension)


parent: shell 이다. 별로 신경 쓸게 없다. PDEPlugin.getActiveWorkbenchShell()
context: 이건 뭔지 잘 모르겠다. PlatformUI.getWorkbench().getProgressService()
scope: 이건 검색 범위라고 보면 된다. 특정 프로젝트내에서 검색하고 싶으면 SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }) 이런 식으로 지정해 주면 된다. javaProject는 JDT로 현재 작업하고 있는 Java 프로젝트를 의미하는 것으로 일반 프로젝트 정보를 알고 있을 때 JavaCore.create(project) 라고 해주면 생성할 수 있다.
style: 선택할 타입의 유형을 결정할 수 있다. 클래스, 인터페이스, enum, annotation 들 중에서 선택할 수 있으며, 이 모든 것들을 선택할 수도 있다.

  • IJavaElementSearchConstants.CONSIDER_CLASSES,

  • IJavaElementSearchConstants.CONSIDER_INTERFACES,

  • IJavaElementSearchConstants.CONSIDER_ANNOTATION_TYPES,

  • IJavaElementSearchConstants.CONSIDER_ENUMS,

  • IJavaElementSearchConstants.CONSIDER_ALL_TYPES,

  • IJavaElementSearchConstants.CONSIDER_CLASSES_AND_INTERFACES,

  • IJavaElementSearchConstants.CONSIDER_CLASSES_AND_ENUMS


중에서 선택하여 쓸 수 있다.
multipleSelection: true이면 두 개 이상 타입을 선택할 수 있다. false이면 하나만 지정할 수 있다. true로 선택해야 할 경우가 거의 없다.
filter: 텍스트 입력 컴포넌트와 찾기 버튼 형태의 조합으로 UI가 구성될 경우에 유용하다. 만약 텍스트 필드에 "java.io.IO"라고 입력되어 있으며 filter가 그 값으로 지정되어 있으면, 다이얼로그는 java.io.IO로 시작하는 타입만 목록에 보여주게 된다. 지정할 필요가 없는 경우에는 ""으로 설정한다.
extension: extension은 다이얼로그를 세세하게 제어할 때 필요하다. 필요없는 경우에는 지정하지 않으면 된다. 예를 들면 출력되는 타입 목록 중에서 java.lang.Throwable을 상속한 인터페이스와 구현한 클래스들만 선택가능하게 할 경우에 extension의 validator를 이용하면 처리할 수 있다.



다음은 사용 예다.


int scopeType = IJavaElementSearchConstants.CONSIDER_ALL_TYPES;
String filter = "";
TypeSelectionExtension ext = null;

SelectionDialog dialog =
JavaUI.createTypeDialog(PDEPlugin.getActiveWorkbenchShell(),
PlatformUI.getWorkbench().getProgressService(),
SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }),
scopeType,
false,
filter,
ext);
dialog.setTitle(PDEUIMessages.GeneralInfoSection_selectionTitle);

if (dialog.open() == Window.OK) {
IType type = (IType) dialog.getResult()[0];

throwsTableViewer.add(type.getFullyQualifiedName('$'));
}




일반적인 경우에 TypeSelectionExtension 를 자주 사용하지 않기 때문에 위의 예제에서는 null로 설정하였지만, 실제 코드에서는 ext를 아래와 같이 구현하였다. Throwable 인터페이스의 하위 인터페이스와 구현 클래스만 지정 가능하도록 구현된 예제다.


TypeSelectionExtension ext = new TypeSelectionExtension() {
@Override
public ISelectionStatusValidator getSelectionValidator() {
ISelectionStatusValidator validator =
new ISelectionStatusValidator() {
@Override
public IStatus validate(Object[] selection) {
if(selection != null && selection.length == 1 &&
selection[0] instanceof BinaryType) {

BinaryType binaryType = (BinaryType) selection[0];
Class selectedClass =
ProjectHelper.loadClass(javaProject, binaryType.getFullyQualifiedName('$'));

if(java.lang.Throwable.class.isAssignableFrom(selectedClass)) {
return Status.OK_STATUS;
}
}

String message = "Only Throwable classes are available";
return new Status(IStatus.ERROR, IRuntimeConstants.PI_RUNTIME, IStatus.OK, message, null);
}
};
return validator;
}
};

댓글 없음:

댓글 쓰기