SWT/JFace

이 글에서는 SWTJFace가 대략 무엇인지, 그리고 이클립스에서 차지하는 위상은 어떤 것인지에 대해서 개괄적으로 이야기하겠습니다. JFace는 일종의 프레임워크이다 보니 공부를 상당히해야 코딩이 가능하지만, SWT를 이용한 코딩은 AWT/Swing으로 UI를 작성해 보신 분이라면 쉽게 적응하실 수 있으리라 생각됩니다. 구조에 큰 차이가 없습니다.

SWT는 Standard Widget Toolkit의 약자로 이클립스에서 UI를 표현하는데 사용되는 API 입니다. SWT가 나오기전에는 AWT와 Swing을 사용했습니만, 써보신 분은 아시겠지만 UI가 어설프고 예쁘지가 않습니다. SWT의 특징은 현재 사용중인 OS에 어울리는 미려한 UI를 제공한다는 것입니다. JNI를 이용해 호스트 운영체제가 제공하는 사용자 인터페이스를 불러서 사용하기 때문이죠. 이클립스를 윈도우, 리눅스에서 각각 실행해보면 SWT와 Swing의 차이를 확인할 수 있습니다. Swing을 사용한 어플리케이션은 윈도우에서나 리눅스에서나 적당히 비슷하면서도 적당히 어설픈 UI를 보여줍니다.

이클립스 플러그인을 제작할 때, SWT는 빈번히 사용됩니다. 마법사의 각 페이지나 Preference 페이지를 작성할 때 등등 세부 사용자 인터페이스를 정의할 때 SWT 코딩을 해야 합니다. 이클립스에서 UI를 제공하는 클래스는 다음과 같이 createContents() 메서드를 오버라이딩 함으로써 유저 인터페이스를 정의합니다. 이때 사용되는 것이 SWT 입니다.

 protected Control createContents(Composite parent) {
  // TODO Auto-generated method stub
  initializeDialogUnits(parent);
  // Get composite and set layout manager
  Composite composite = new Composite(parent, SWT.NONE);
  GridLayout layout = new GridLayout();
  layout.marginHeight = convertVerticalDLUsToPixels
    (IDialogConstants.VERTICAL_MARGIN);
  layout.marginWidth = 0;
  layout.verticalSpacing = convertVerticalDLUsToPixels(10);
  layout.horizontalSpacing = convertHorizontalDLUsToPixels
    (IDialogConstants.HORIZONTAL_SPACING);
  composite.setLayout(layout);

AWT/Swing과 다른 몇가지 SWT의 특징을 언급하고 JFace로 넘어가겠습니다. 우선 Widget간의 부모/자식 관계를 맺는 방법에서 차이가 있습니다. AWT/Swing에서는 다음과 같은 방법으로 부모 인스턴스에 자식 인스턴스를 추가합니다. 패널에 버튼을 추가하는 것을 예로 들 수 있겠습니다.

부모_인스턴스.add(자식_인스턴스);

반면에 SWT에서는 자식 인스턴스를 생성할 때 부모의 인스턴스를 첫번째 인자로 넘겨줍니다. 예제코드에서 Composite을 추가하는 부분을 참조하세요. 그리고 두번째 인자로 스타일 비츠(style bits)라는 것을 정의합니다. SWT.NONE, SWT.PUSH, SWT.CHECK 등이 스타일 비츠에 해당합니다. 이 상수들을 |로 묶어 Widget의 속성을 결정합니다. 물론 각 Widget마다 유효한 스타일 비츠가 정해져 있습니다. 마지막으로 언급할 것은 SWT가 실제 운영체제의 리소스를 사용하기 때문에 더 이상 쓰지 않을 때 해제해야 한다는 점 입니다. 대부분의 SWT Widget은 앞서 살펴본 것 처럼 생성자에서 부모를 지정하기 때문에, 부모를 폐기하면 자식도 폐기된다는 규칙에 의해서 문제가 되지 않습니다. 하지만 부모의 Widget 없이 생성된 SWT 오브젝트인 Font, Image, Color 등등은 사용하지 않을 때 직접 폐기해야 합니다.

JFace는 SWT를 보완하기 위해, 모델 기반 접근 방법(model-based approach)을 기반으로 더 적은 시간에, 더 이해하기 쉬운, 재사용 가능한 코드를 작성할 수 있도록 설계되었습니다. JFace는 UI를 효과적으로 작성하기 위한 일종의 프레임워크라고 할 수 있습니다. JFace 뷰어를 예로 들자면, JFace 뷰어가 제공하는 클래스를 상속해 정해진 절차를 따라서(!) ‘뚝딱뚝딱’ UI를 코딩하면 ‘짠!’ 하고 그럴듯한 하이퀄리티(?)의 UI를 화면에서 확인할 수 있는 것 입니다. JFace는 모델-뷰 구조로 구성되어있기 때문에, 이미 어플리케이션에서 사용하던 모델을 자연스럽게 사용할 수 있습니다. 물론 모델과 뷰사이의 연결을 담당하는 코드를 작성해야 하겠지만요. (e.g. ContentProvider , LabelProvider) JFace는 UI의 얼개에 해당하므로 SWT 역시 함께 사용해야 합니다. 

Wizard

아주 오랜만에 이클립스 플러그인에 관한 글을 다시 적게 되었습니다. 연구실에 남아있을 마지막 2주일 동안 그 동안 못다뤘던 부분들을 정리하려 합니다. 오늘은 마법사에 대해서 다루겠습니다. 마법사(Wizard)가 무엇인지는 각종 개발툴을 써보셨다면 이미 잘 알고계실 것 같습니다.  VICODE 사용자 메뉴얼을 존대말로 쓰다보니 탄력받아(?) 존대말로 쓰게 되었네요.

마법사는 여러 페이지로 구성되어 있습니다. 각 페이지는 프로젝트를 생성하는 등의 작업을 위한 일련의 단계를 표현합니다. 그리고 각 페이지는 자신에게 필요한 정보가 입력되었는지를 판단하여 마법사에게 알립니다. 마법사는 페이지의 상태에 따라 다음 페이지로의 이동가능 여부를 판단하여 UI에 반영하는 것이죠. 모든 페이지가 완료 상태에 도달하면 Finish 버튼이 활성화 되어 마법사를 종료할 수 있습니다. Finish 버튼이 클릭되면 마법사는 각 페이지에서 받은 정보를 바탕으로 원하는 작업을 수행하게 됩니다.

코드레벨에서 살펴보면 마법사는 마법사 클래스각 페이지에 해당하는 클래스의 집합으로 구성됩니다. 마법사 클래스는 페이지 클래스를 참조하고 있고  addpages() 함수에서 페이지 클래스를 마법사에 등록합니다.

지금부터는 코드를 가지고 상세구현 과정을 살펴보도록 하겠습니다. 이클립스 플러그인의 시작은 확장점입니다. 마법사를 추가할 수 있는 확장점은 총 3가지가 있는데, 이 글에서는 프로젝트 생성 마법사를 추가하는데 사용되는 org.eclipse.ui.newWizards를 사용하겠습니다. 다음코드는 확장을 정의한 plugin.xml 코드의 일부분입니다.

   <!– new project wizard –>
   <extension
         point=”org.eclipse.ui.newWizards“>
      <category
            id=”kr.ac.kaist.vicode”
            name=”VICODE”/>

      <wizard
            canFinishEarly=”false”
            category=”kr.ac.kaist.vicode”
            class=”kr.ac.kaist.vicode.wizard.NewProjectWizard
            finalPerspective=”kr.ac.kaist.vicode.perspective”
            hasPages=”true”
            icon=”icons/esterel_image.gif”
            id=”kr.ac.kaist.vicode.newprojectwizard”
            name=”VICODE Project”
            preferredPerspectives=”kr.ac.kaist.vicode.perspective”
            project=”true”/>
   </extension>

마법사 확장점에는 여러가지 속성이 있습니다. Perspective 관련 속성에는 VICODE perspective의 id를 정의하였습니다. canFinishEarly는 모든 페이지를 다 거치지 않아도 완료할 수 있는 마법사인지를 정의합니다. hasPages는 여러 페이지를 가진 마법사인지를 정의합니다. 예제로 보여드릴 VICODE 프로젝트 생성 마법사는 2페이지로 구성되어 있고 모든 페이지를 거쳐야 하므로 위의 코드와 같이 정의하였습니다.

먼저 마법사 클래스(NewProjectWizard)를 살펴보도록 하겠습니다.

public class NewProjectWizard extends Wizard implements INewWizard
{
 private WizardNewProjectCreationPage mainPage;
 private WizardInitialPage initialPage;

 private IProject newProject;

 public boolean performFinish()
 {
  createNewProject();
  initialPage.finish(newProject);
  return true;
 }

 public void addPages()
 {
  mainPage = new WizardNewProjectCreationPage(“New VICODE Project (1/2)”);
  mainPage.setDescription(“Create a new VICODE project in the workspace”);
  mainPage.setTitle(“Create VICODE Project”);
  initialPage = new WizardInitialPage(“New VICODE Project (2/2)”);
  initialPage.setDescription(“You can specify top module name and communication event.”);
  initialPage.setTitle(“Module declaration for hardware and Communication Event”);
  addPage(mainPage);
  addPage(initialPage);

 }

프로젝트 마법사 클래스는 Wizard 클래스와 INewWizard 인터페이스를 상속합니다. 예제 마법사의 목표는 두 페이지에 걸쳐 정보를 받아 들인 후 프로젝트를 생성하는 것 입니다. 총 2페이지로 구성되어 있는데, 첫번째 페이지는 구현하지 않고 이미 작성된 프로젝트 생성 페이지를 가져다가 사용하였습니다. 이 페이지는 단순히 프로젝트 이름과 저장위치를 지정할 수 있도록 구성되어 있습니다. 두 번째 페이지는 VICODE 프로젝트를 생성하는데 있어 필요한 정보를 입력받기 위해 직접 구현한 페이지입니다.

addPages() 메서드에서는 각 페이지의 인스턴스를 생성하고 초기화한 후에 addPage() 메서드를 호출하여 마법사에 각 페이지를 등록합니다. Finish 버튼이 클릭되면 호출되는 performFinish() 메서드에서 마법사 완료시에 필요한 일들을 기술합니다. 실제 프로젝트가 생성되는 코드는 첨부파일을 참조하시기 바랍니다.


지금부터는 두번째 페이지에 해당하는 코드를 살펴 보겠습니다.

public class WizardInitialPage extends WizardPage
{
 public void createControl(Composite parent)
 {
  Composite composite = new Composite(parent, SWT.NONE);
  GridLayout gridLayout = new GridLayout();
  gridLayout.numColumns = 1;
  composite.setLayout(gridLayout);
  createModuleNameGroup(composite);
  createCommunicationGroup(composite);
  setControl(composite);

  updatePageComplete();
  setMessage(null);
  setErrorMessage(null);

 }
 private void updatePageComplete()
 {
  setPageComplete(false);
  // 페이지의 완결성 체크
  if (moduleNameText.getText().equals(“”))
   return;
  // 페이지의 완결성 체크를 건너 뛰었다면 페이지를 완료상태로 변경
  setPageComplete(true);
  setMessage(null);
  setErrorMessage(null);

 }

마법사의 모든 페이지 클래스는 WizardPage 클래스를 상속합니다. UI를 정의하는 다른 클래스와 마찬가지로 createControll() 메서드에서 SWT로 사용자 인터페이스를 작성합니다. 마지막에 호출되는 메서드인 updatePageComplete()는 페이지에 필요한 정보가 입력되어 있는지를 판단하기 위해 제가 작성한 메서드 입니다. 이 메서드는 각 컨트롤에서 값이 변경될때마다 호출되어 페이지가 완료상태인지를 setPageComplete() 메서드를 호출하여 마법사에 알립니다.

이상으로 이클립스 플랫폼에서 마법사를 구현하는 방법에 대해서 말씀드렸습니다. 아래 첨부한 소스코드를 참조하시면 이해하시는데 도움이 될 것 같습니다.

bk20.java

블로그 분석결과: Daum WebInSide

사용자 삽입 이미지
블로그 스피어에서 우연히 발견한 다음 웹인사이드를 사용한지 일주일이 지났다. 어느정도 데이터가 성숙되었다고 판단하고 reshout.com의 분석결과를 살펴보았다. 재밌는건 대부분의 방문이 검색엔진으로부터 발생하고 있으며, 그 검색엔진에 입력된 검색어 중에 단연 “적천사주”가 절대적인 위치를 차지하고 있다는 점이다.

나는 reshout.com이 많은 사람들의 RSS 리더에 등록되어 고정적인 독자가 방문하는 블로그가 되었으면 한다. 특히 내가 읽은 책과 공부한 전산지식을 소개하는 공간으로서 의미를 가졌으면 좋겠다. 그런 측면에서 이번 분석 결과는 다소 실망스럽군.

그러나 그나마 고무적인 사실은 reshout.com의 RSS가 한RSS에서 15명에게 등록되어 있다는 사실. 아주 오랫동안 5명이였는데 최근에 급상승한 것 같다. 그다지 재미있는 주제를 다루고 있는 블로그는 아니지만, 책에 대한 데이터가 쌓이면서 조금씩 알려지고 있는 것 같다.

Microsoft Office 2007 사용기

우연히(?) 한글 오피스 2007의 RTM 버전을 P2P에서 발견하고는 호기심을 참지 못해 다운받아 설치하고 말았다. 그 당시 디펜스 슬라이드를 만들고 있었을 때니 업그레이드 밖에 안된다면 모험이 될 수도 있었는데, 기존의 버전을 유지하는 옵션을 제공하고 있었다. (오피스 사용기라고 하기는 조금 뻘쭘한 것이 내가 몇일 동안 제대로 사용해본 것은 파워포인트와 아웃룩 뿐이다.)

사용자 삽입 이미지
Microsoft PowerPoint 2007

처음 사용해 본 것은 PowerPoint. 디펜스 슬라이드의 대부분이 완성된 상태에서 2007 버전으로 갈아탔기 때문에 편집과정을 많이 경험해보지는 못했다. 일단 눈에 띄는 것은 메뉴의 구성. 개인적으로는 새롭게 바뀐 UI가 상당히 마음에 든다. 직관적이라고나 할까? 편집에 필요한 모든 것들이 상단에 일관적으로 배치되어 있고, 텍스트를 편집할 때 마우스 오른버튼을 누르면 그 자리에서 속성을 결정할 수 있어 매우 편리하다. 대부분의 메뉴가 아이콘으로 제공되어 원하는 기능을 찾기가 수월하다. 개인적으로는 오피스 2007 설치 후 추가되는 몇가지 폰트 중에 Corbel 폰트가 마음에 들어 디펜스 슬라이드의 폰트를 교체했다.

사용자 삽입 이미지
Microsoft Outlook 2007

연구실에 처음 들어왔을 때 한동안 Outlook을 메일 클라이언트로 사용하다가 그만둔 이유는 메일을 읽어오는게 느렸기 때문이다. 문제는 수 없이 쏟아지는 스팸메일을 읽는데 시간을 소비한다는 것. 그래서 이번에는 Gmail의 POP를 사용해서 계정을 설정하고 Outlook을 사용해봤다. Outlook을 쓸때의 단점은 Outlook에서 보낸 메일이 웹메일에서 보이지 않는다는 것이였는데, Gmail을 Outlook에 사용한 경우 Outlook에서 보낸 메일도 Gmail의 보낸편지함에 저장되어 둘을 동시에 사용하는데 문제가 없었다.

범주라는 개념이 추가되어 Gmail의 레이블처럼 메일을 분류하는데 유용하다. 색깔 별로 메일과 작업을 분류할 수 있는데 나는 연구실 관련일을 빨간색, 문화 생활 관련일은 노란색으로 표시하여 사용하고 있다.

Outlook에서 지원하는 메일, 작업, 일정이 유기적으로 통합되어 오른쪽에 할 일 모음 윈도우에 보기 좋게 정리해서 출력해준다. 덕분에 당장 신경써야 할 일들을 한눈에 확인할 수 있다. 전에도 있었던 기능인지는 모르겠지만 이메일에도 어떤 날에 관련있는 것인지를 표시하여 할 일 항목으로 활용할 수 있다. 항상 시간관리를 어떻게 해야하는 것이 가장 효율적인가에 대해 고민하고 여러가지를 시도해보았지만 앞으로는 Outlook 2007을 이용할 계획이다.

전체적인 느낌은 UI가 예쁘고 편리하다는 점. 특히 윈도우 비스타 RC2에서 어설퍼 보이던 맑은 고딕 폰트가 오피스 2007에서 깔끔하게 보여서 매우 마음에 든다. 내년 2월 회사에 가면 오피스 2007을 쓸 수 있었으면 좋겠다.

사용자 삽입 이미지

한가지 현재 아쉬운 것은 RTM 버전이라 그런지 잊을 만 하면 한번씩 오류메시지가 뜬다는 점.

세벌식으로


논문을 완성한 지금 오래전 부터 꿈뀌오던 세벌식으로 바꾸기 프로젝트를 시작했다. 이 글도 삼천빡을 하는 심정으로 힘들게 쓰고 있다. 이제 삼일차. 차라리 이제는 완전히 두벌식을 잊고 싶다. 평생 키보드를 두드려야 하는 운명, 입사하기 전 지금이 마지막 기회다. 미련해 보이더라도 노력하면 된다는 걸 스스로 증명해 보자!

세벌식 쓰시는 분들 정말 좋은가요?