GEF Programmer Guide 번역

Graphical Editing Framework Overview

 

GEF(Graphical Editing Framework)는 이클립스 플랫폼에서 제공하는 위젯만으로는 구현하기 어려운 사용자 인터페이스를 구현할 수 있는 토대를 제공한다. 

 

GEF 컴포넌트는 다음 3개의 플러그인으로 나뉘어진다. 

 

  • Draw2d(org.eclipse.draw2d) - SWT Canvas 상에서 페인팅과 레이아웃 작업을 위한 경량의 툴킷
  • GEF(org.eclipse.gef) - Draw2d 기반의 MVC Framework
  • Zest(org.eclipse.zest) - Draw2d 기반의 시각화 도구

Draw2d와 GEF 를 하나의 완벽한 GEF 로 언급하기도 하고 단순히 org.eclipse.gef 플러그인 자체를 GEF로 언급하기도 한다.

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

 

Zest Overview 
 
이클립스를 위한 시각화도구이다. 주요 목적은 그래프기반의 프로그래밍을 쉽게 하는 것이다. Zest를 사용하면 그래프는 표준 JFace 뷰어로 래핑한 SWT 컴포넌트로 다루어진다. 이런 연유로 개발자들은 Zest를 개발자들이 JFace의 Tables, Trees, Lists 등을 다루는 방식과 동일하게 다룰수 있게된다. 
 
Draw2d Overview
 
Draw2d는  figure 라는 그래픽 요소를 제공하는 경량의 툴킷이다. 여기서 경량이란 말을 주목해야하는데 이는  figure는 운영체제상의 어떤 그래픽적인 자원과도 상관없는 단순한 자바 객체를 의미한다.
figures는 부모자식관계로 복합체를 구성할 수 있다. 모든 figure는 사각형의 경계를 가진다.
layout manager 를 통해 figure의 자식들을 배치할 수 있다.  
 
 
 
org.draw2d.LightweightSystem 은 figure 와 SWT 사이의 링크이다. figure 는 LightweightSystem을 통해서 SWT Canvas에서 호스팅된다. LightweightSystem 은 대개의 SWT event를 가로채서 EventDispatcher에게 전달하고 전달된 이벤트는 figure 용 이벤트로 전환된다. 그러나 Paint event는 UpdateManager에게 전달되는데 UpdateManager가 painting과  배치를 관장하기 때문이다. 어떤 형태의 다이어그램, 도큐먼트 또는 그림일지라도 필요하다면 사용자 정의 figure 와 사용자 정의 layout 구현을 통해서라도 쉽고 효율적으로 그려질 수 있다.
 
Painting of Figures 
 
Figures는 org.eclipse.draw2d.Graphics 라는 추상 클래스를 통해서 paint작업을 수행한다.  이 Graphics 는 figure의 표면을 그릴 수 있는데, drawXxx()는 형태의 외관을 그리고 반면에 fillXxx()메소드는 내용을 채운다. 이 추상 클래스를 통해서 Draw2d는 SWT GC(Graphical Context)를 추상화하고 성능 최적화를 도모하고 있는 것이다. 예를 들면 Graphics는 현재 상태의 pushing과 popping을 지원하는데 figure의 paint는 아래와 같은 절차로 진행된다.
 
  • Figure#paint() - IFigure인터페이스에 정의되어 있는데 paint 프로세스의 시작을 알린다. 우선 자식 클래스에게 상속될 수 있는 Graphics 의 Font, background, foreground 같은 속성들을 설정하고 자식 클래스에서 이 속성들의 값을 활용해야 하는 경우를 위해서 이 상태를 push한다.
  • Figure#paintFigure() - 자기 자신을 paint한다.
  • Figure#paintClientArea() - 클라이언트 영역은 자식들이 나타나는 영역이다. 클라이언트 영역의 그래픽을 변경해야하는 상황이 발생한 경우 이 메소드를 통해서 반드시 해당 변경을 적용해야한다.
  • Figure#paintChildren() - 클라이언트 영역의 셋업이 끝났으면 자식을 그린다. 자식을 그린 후, Graphics  상태는 다시 처음의 상태로 복원되는데 부모로부터 상속된 Graphics 상태를 엎어쓰지 않기 위함이다.
  • Figure#paintBorder() - 마지막으로 Figure는 자식들에게 반드시 나타나야 하는 장식들을 그리는데 만일 Border가 Figure에게 설정되어 있다면 이 때 그리게 된다.
Layout 
 
drawing 내에서 특정 figure의 위치를 결정하는 프로세스를 의미한다.  이 프로세스는 layout(배치)이 필요한 figure를 invalid로 설정하는 단계와 그리고 invalid한 figure 의 branches를 validating 하는 2 단계를 포함한다.
자식 Figure의 배치는 자식 Figure 의 LayoutManager에게 위임한다.
 
validation 
 
validation 은  layout 과 매우 밀접한 관계가 있다. 배치가 필요한 figure는 일단 "invalid"로 마킹이 된다. 모든 Figure들은 처음 그려질 때 "invalid" 상태로 먼저 시작한다. 나중에 validate()메소드가 호출되고 난 후 스스로 validate 라고 마킹하고 layout을 수행한다. 배치(layout)이후, Figure  들은 자신들의 자식들을 validate 한다.
 
Hit Testing
 
마우스 위치 상의 특정 Figure를 찾아내야 하는 상황이 있을 수 있다. 예를 들어 특정 Figure 위에서 마우스 정지 버튼을 눌러졌을 때 어떤 풍선도움말인지를 결정해야한다던지 등등..
다른 예로는 인터렉티브한 그래픽 애플리케이션인데 하나의 figure가 다른 figure 위에 드래깅 되는 것을 판독해야 하는 것 등이다.  이런 경우에 사용할 수 있는 4 개의 메소드를 IFigure 인터페이스에서 정의해 놓았다. 실상은 1~3 번 메소드는 단지 4 번 메소드의 간편 버전일 뿐이다.
 
  1. findFigureAt(int x, int y)
  2. findFigureAt(Point p)
  3. findFigureAtExcluding(int x, int y, Collection exclude)
  4. findFigureAt(int x, int y, TreeSearch) - TreeSearch 는 탐색 될 필요가 없는 Figure 들은 제외하고 후보가 될 Figure 들만 취합하여 검색하는 helper 클래스이다.
 
Connectons and Routing
 
커넥션요소는 두 점 사이에 라인을 그리는데 사용된다. Connection 인터페이스는 IFigure 를 확장하고 있다. drwa2D 프레임워크에서는 PolylineConnection 이라는 구현 클래스를 제공하고 있는데 대부분의 경우에 사용될 수 있다. 커넥션에 의해 연결되는 소스, 타겟 양 끝단은 ConnectionAnchor를 사용해서 정의된다. 이 양끝단과 더불어 커넥션상의 모든 좌표(점, 포인트)들은 ConnectionRouter에 의해서 설정된다. 대개 한 화면상의 모든 커넥션들은 동일한 router 인스턴스를 공유한다.
또한 동일한 지점에 연결되는 커넥션들은 anchor 인스턴스를 공유한다.
 
Connecton Usage
 
커넥션은 다른 figure 처럼 생성되고 추가될 수 있다. 보통 다른 요소들 위해 나타나야 하기 때문에 Layer 를 사용해서 그려진다. 다른 Figure와는 다르게 커넥션에 대해서 bounds를 설정해서는 안되고, 소스, 타겟 엥커를 지정하고 커넥션이 그려질 포인트(점, 좌표)를 계산하는 Router를 지정해야 한다. 그러고 나면 커넥션은 자기 자신만의 bounding box를 결정할 수 있게 된다.
 
커넥션은 기본으로 간단한 라우터를 가지고 있지만 추가적으로 다른 라우터를 설정할 수 있다. 어떤 라우터들은 커넥션이 구부려져야하는 좌표 등 이른바 제약조건(Constraints)을 다룰수 있는 것들도 있다. 라우팅 제약조건을 설정할 때는 먼저 커넥션에 대해서 반드시 해당 라우터를 먼저 설정하고 난 이후에 설정된 라우터에 제약조건을 설정하면 된다.
 
모든 커넥션이 라우터를 공유하고 다른 모든 그래픽 요소들 위해 위치할 수 있게 하는 간편한 방법은 ConnectionLayer를 사용하는 것이다. 라우터 속성을 가지고 있어서 레이어에 추가되는 모든 커넥션들은 그것을 공유할 수 있다.
 
Routing and Anchors
 
커넥션은 항상 라우터를 가지고 있고 라우터는 적어도 소스, 타킷이라는 두개의 양단을 설정해야만 한다. 양 끝단은 앞서 설명한 바와 같이 Anchor 에 의해 정의되는데 이 앵커는 고정된 또는 계산되어질 수 있는 위치(location)인데, 통상 특정 Figure 와 연관되어 화면상에서 보여질 수 있다.
 
라우터는 양 끝단 및 양 끝단을 연결하는 커넥션의 모든 좌표를 계산한다. 그리고 나서 setPoints(PointList )메소드를 호출하여 해당 커넥션에 대해서 좌표들을 저장한다.
 
Ading Decorations and Children to Connections
 
 대개의 Figure 와 마찬가지로 PolylineConnection 도 자식을 추가할 수 있다. 그러나 자식은 반드시 화사표 촉 또는 커넥션을 장식하는 레이블이어야 한다. 각 장식의 위치는 움직일 수 있는데 이때 DelegatingLayOut이 사용된다.
 
GEF Overview
 
Draw2d는 figure 들의 효율적인 페인팅과 배치에 중점을 두고 있고 GEF plug-in 은 Draw2d 위에 편집기능을 더했다. 이 프레임워크의 목적은
 
1. draw2d figure 들을 사용하여 어떤 모델 객체일지라도 그래픽적으로 display 가능하게 한다..
2. 마우스, 키보드, 또는 워크벤치와의 상호작용을 지원한다.
3. 1, 2 번과 관련된 공통 컴포넌트들을 제공한다.
 
아래 복잡한 다이어그램을 통해서 GEF를 추상적으로 이해할 수 있을것이다. GEF는 모델과 뷰를 약하게 결합시키고 있는 중간 영역으로 정의될수가 있겠다. 이렇게 해서 애플리케이션의 모델과 뷰 사이의 링크를 제공하고 이벤트를 요청으로 변환시켜주는 도구나 액션과 같은 i nput handler를 제공하기도 한다. 그림에서 볼수 있는 것과 같이 요청(Request)과 명령(Command)는 모델과 모델에 적용되는 영향을 캡슐화시키는데 사용되고 있다.
 
 
 
 
MVC 구조에서 컨트롤러는 통상적으로 모델과 뷰사이의 유일한 링크이다. 하여서 컨트롤러는 뷰를 유지하고 UI 이벤트를 해석하여 이를 해당하는 오퍼레이션으로 변환하곤한다. 컨트롤러의 이런 역할들이 GEF에서도 적용되며 아래에 설명되어진 바와 같다.
 
Model
 
모델은 영속화되는 데이터를 의미한다. 어떤 모델이라도 GEF와 함께 사용될 수 있다.
모델은 반드시 어떤 종류의 통보 메커니즘을 가지고 있어야 한다. 기술적으로 모델은 아니지만 커멘드 객체가 아주 밀접한 관련이 있는데 커멘드 객체를 통해서 편집, 취소,재편집, 재취소가 작동할 수 있다. 일반적으로 커멘드는 모델 그 자체에 대해서만 작동해야 한다.
 
View(Figures/TreeItems)
 
뷰는 사용자에 보여지는 그 어떤 것이라도 될 수 있다.
Figure, TreeItem 모두 뷰의 요소로 사용될 수 있다.
 
Controler(EditPart)
 
통상 시각화될 모델객체 별로 하나의 컨트롤러 객체를 둔다. 컨트롤러를 EditPart라 한다.
EditParts는 모델과 뷰 사이의 링크로서 편집에 대해서 대응해야 한다. Editparts는 소위 EditPolicies라는 편집 작업의 상당부분을 처리하는 헬퍼클래스들을 가지고 있다.
 
Viewers
 
EditpartViewer는 editpart가 뷰를 시각화하는 곳이다. GEF에서 제공하는 뷰어는 2가지가 있다. 그래픽 뷰어는 figure들을 포함하고 트리뷰어는 네이티브 트리뷰아이템을 시각화한다.
 
GEF 뷰어들은 swt컨트롤들을 관리한다는 측면에서 JFace의 뷰어들과 비슷하다. 뷰어들은  selection provider이고 선택의 단위는 EditPart이다.(통상 모델 객체 하나당 EditPart 하나라는 점에서 볼 때 모델객체 하나 하나가 선택의 단위라는 뜻) 
 
언제 사용하는가?
 
Workbench 내에서 SWT 컨트롤이 사용될  수 있는 곳에서는 모두 GEF가 사용될 수 있다. 그 곳은 편집기(editor), 뷰, 위저드페이지, 기타 등등이 될 수 있겠고 가장 흔하게는 EditorPart내부에서 사용되고 종종 editor의 아웃라인페이지에서도 사용되기도 한다.
 
GEF는 Eclipse Rich Client Platform(RCP)과 속성시트를 제공하는 "views" 플러그인(org.eclipse.ui.views)을 필요로 한다.
 
An Introduction to EditParts
 
org.eclipse.gef.EditPart 인터페이스의 내용을 보면 EditPart는 GEF Viewer의 Building Block이라고 기술되어 있으며 모델의 변경과 시각화를 책임지고 있다고 기술하고 있다. GEF Viewer는 아래 별도로 설명하고 있지만 org.eclipse.gef.EditPartView 인터페이스 타입으로서 EditPart를 관리하는 SWT Control 의 Adaptor이며 editparts 는 시각적 요소인 Figure, TreeItem 과 같은 시각적 요소를 가지는데 이런 시각적 요소는 Viewer 에 의해서 시각적으로 제공되기때문에 뷰어가 editparts의 생명주기를 관리해야하는 책임을 가지게 된다. GEF 뷰어에서 컨텐츠는 바로 model 이다. GEF 뷰어에 컨텐츠를 제공하는 것은 모델 객체를 뷰어에 전달하면 되는데 뷰어는 모델 객체를 직접 다룰 수 없다. 뷰어의 빌딩블록이 editpart 이므로 뷰어의 EditPartFactory를 통해서 특정 모델 객체와 연결된 edit part를 생성하여 뷰어를 구성하는 것이다. 
GEF 뷰어는 보통 root edit part(org.eclipse.gef.RootEditPart)를 가지고 있는데 이 root edit part 에 컨텐츠 edit part를 구성하게 된다. 컨텐츠 editpart 는 모델과 연결된 edit part이고 root edit part는 특정 모델과 상관이 없는 뷰어를 초기화하고 컨텐츠 edit part의 부모역할을 하는 edit part이다. 뷰어에 대한 자세한 설명은 뒤이어 나오는 Creating a Graphical View of Model 섹션을 참고한다.
 
Editparts 는 뷰와 모델을 연결시켜주는 것이 주요 목적이지만 또한 자체 구조를 구성하기도 한다. 즉 계층구조를 가질 수 있는데 보통 이 구조는 대응되는 모델의 구조와 상응하게 된다. 예를들어 모델이 노드들을 가지는 다이어그램으로 구성되어 있다면 여러개의 노드 editpart 자식들을 가지는 다이어그램 editpart가 있게되는 것이다.
 
 
GEF에서는 editpart의 2가지 구현물을 제공하고 있는데 Graphical editparts와 Tree editparts 가 그 것들이다. Graphical Editpart는 figure 를 뷰로 사용하고 Tree editparts는 SWT treeitems를 view 로 사용하고 있다.
 
이런 editpart의 책임은 다음을 포함하고 있다.
 
  • 뷰의 생성과 유지(figures or treeitems)
  • 하위 editpart의 생성과 유지
  • connection editpart의 생성과 유지
  • 모델의 편집지원

뷰와 하위 editpart 의 생성과 유지가 의미하는 것은 모델에서 발생하는 변경을 통보받을 수 있음을 의미한다. editpart는 통상 모델 객체에 직접적으로 리스너를 설정하여 통보를 받어서 해당 통보(변경)의 내용에 따라서 관련 뷰 나 구조를 갱신한다. 

 

 

 
Creating a Graphical View of Model
 
모델과 모델의 시각적 표현요소가 준비되었다면 이제는 그것들을 함께 유기적으로 연결시켜야 하는데 edit part 를  작성하여 모델과 시각적 요소가 유기적으로 결합될 수 있다. GEF에서 제공하는 EditPart인터페이스의 구현 클래스들이 있는데 애플리케이션 개발 시 적절한 클래스를 base 클래스로 삼아서 확장하여 개발해야 한다. 어차피 우리의 애플리케이션을 위한 데이터(모델)와 시각적 요소(Figure)는 프레임워크에서 제공해줄 수 없기때문에 이 두 요소(모델, 시각요소)를 프레임워크의 EditPart를 확장한 EditPart에서 유기적으로 결합해야한다.
 
 
GEF는 ScrollingGraphicalViewer라는 Draw2d FigureCanvas를 사용하는 클래스를 포함하고 있는데 스크롤바가 필요없는 상황이 아니라면 대개의 애플리케이션들은 이 클래스를 사용하게 된다
 
다음 단계는 사용할 Root Edit Part를 결정하는 것이다. GEF EditPartViewer는 소위 root 라고 불리우는 특별한 형태의 edit part를 필요로 하는데 뷰어의 컨텐츠인 모델과 연결되지 않고 실제 컨텐츠 edit part 에게 일관된 문맥을 제공하는 컨테이너 edit part역할을 수행한다고 보면 된다.
 
아래 클래스 다이어그램을 보면 EditPart 인터페이스 하위에 RootEditPart인터페이스가 있고 이 RootEditPart 인터페이스를 구현하고 있는 클래스들이 SimpleRootEditPart ,GraphicalRootEditPart, ScalableRootEditPart 클래스 들이 있다. 클래스 다이어그램 상으로 보면 AbstractGraphicalEditPart 를 확장한 것이 SimpleRootEditPart 등 RootEditPart계열 클래스이다. 일반적인 컨텐츠 EditPart클래스들은 보통 AbstractGraphicalEditPart클래스를 상속받아서 개발하게되는데 그렇다면 루트에디터클래스는 컨텐츠 EditPart 클래스 역할도 할 수 있다는 것이 된다. 역은 안된다. 즉 일반적인 컨텐츠EditPart클래스는 루트에딧파트 클래스 역할을 할 수는 없다. (객체지향 개념적으로 그렇다는 애기지 API 등 어디에서도 이런 애기를 하고 있지는 않다) 또한 RootEditPart 계열의 클래스들은 LayerManager 인터페이스를 구현하고 있는데 LayerManager 는 GraphicalViewerImpl 클래스의 멤버변수로 포함관계를 이루고 있다. 즉 RootEditPart 는 자기자신을 뷰어의 LayerManager 로 등록하고 GEF Viewer 의 Layer의 배치를 관리하고 있는것이다. 
 
 
암튼 프레임웍에서 제공하고 있는 클래스 중 
 
  • ScalableRootEditPart - 일련의 표준화된 레이어들과 줌 기능을 제공하고 있다.
  • ScalableFreeformRootEditPart - ScalableRootEditPart와 동일하나 모든 Layer들이 freeform 인터페이스 타입이어서 다이어그램이 음의좌표계로까지 확장될 수 있다. 이 것이 가장 흔하게 사용되면서도 가장 유연한 루트에딧파트이다. 
위의 2개의 클래스를 고려할 수 있겠다. 
 
자, 뷰어와 루트에딧파트까지 되었다면 다음해야 할일은 실제적으로 컨텐츠를 뷰어에 제공하는 것이다. 콘텐츠는 모델 객체를 의미하는데 모델은 뷰어에 의해 표현될 그래픽 그림을 제공한다. 뷰어의 EditPartFactory가 컨텐츠(모델)를 가지고 컨텐츠 editpart를 만드는 책임을 가지게되는데 우선은 루트에딧파트에 추가될 컨텐츠 에딧파트를 생성하게 된다. 그리고 나서 만들어진 에딧파트(들)이 하위의 자식 에딧파트 및 커넥션에딧파트를 만들어야 하면 EditPartFactory 는 계속해서 에딧파트들을 만들고 부모 에딧 파트에 만들어진 하위 자식 컨텐츠 에딧타트들을 추가하는 것이다. 
 
아래그림에서 표현했듯이 뷰어의 팩토리가 모델을 가지고 EditPart를 생산하고 있는 것을 알수 있다.
 
 
 
Implementing the Contents EditParts
 
자 먼저 컨텐츠 EditPart를 만들어야한다. 또한 콘텐츠 모델 객체를 인식하고 이를 통해 editPart를 만들 팩토리도 구현해야한다. 이 에딧파트의 시각적요소는 다이어그램의 나머지들을 위한 배경 또는 백그라운드 역할을 제공하는 것이고 이때 대개는 페인트 작업이 필요하지 않지만, 그럼에도 불구하고 layout manager 와 루트에딧파트의 기본 Figure 요소의 타입을 선택해야 한다. 어떤 Figure 가 만들어져야는지 제어하기 위해서는 createFigure() 메소드를 재정의한다. freedom root를 사용할때는 컨텐츠 figure는 반드시 freeform API를 구현해야 하며 FreeformLayer 면 충분할 것이다. 레이아웃 매니저는 루트가 freeform 이냐 아니냐에 따라서 XYLayout 또는 FreeformLayout이 자주 사용된다. 
 
초기화 동안, 컨텐츠 에딧파트는 getModelChildren()메소드를 통해서 반환된 목록을 토대로 자식 editpart를 생성한다.EditPart 클래스들은 이 메소드(getModelChildren)를 재정의해서 모델에서 일련의 객체 목록이 반환되도록 구현해야 한다. 
 
Implementing the Children EditParts
 
다이어그램상의 자식들, 종종 노드라고 불리우는데, 통상 사용자에게 제공되는 정보가 이 것들이다. 뷰어에서 이런 정보가 보여질려면 각 EditPart는 자기 자신의 refreshVisuals()메소드를 호출하여 모델의 프로퍼티를 뷰에 반영해야 한다. EditPart는 이 메소드(refreshVisuals)를 해당 모델과 사용할 시각적요소에 기반하여 반드시 재정의해야 한다.복잡한 경우에서는 이메소드는 더 작은 몇개의 helper 메소드로 뽑혀질수도 있다. 나중에 모델의 변경을 리스닝할때 이 메소드 또는 헬퍼 메소드들이 재 호출될 수도 있다. 다이어그램의 자식이 또한 부모일 수 있는데 이 때 역시 자기 자신만의 자식을 가질 수 있으며, 역시 getModelChildren()메소드를 재정의해야 한다. 
 
Adding Connection EditParts
 
커넥션은 두 editpart를 연결하는 특별한 종류의 EditPart이다. 커넥션의 소스, 타겟이 될 수 있는 EditPart를 node라고 하는데 커넥션은 소스 또는 타깃 양 끝단에서 공통된 방식으로 생성되거나 다루어질 수 있다. 노드는 커넥션 자체를 의미하는 모델객체를 반환하는 getModelSourceConnections()와 getModelTargetConnections()메소드를 반드시 재정의해야 하고 GFE 는 커넥션 EditPart가 다른 끝 단에의해서 이미 생성되어 있는지 체크하고 만일 아직 생성되어 있지 않다면 팩토리객체를 통해서 커넥션 EditPart를 생성한다. 커넥션 Figure 즉 시각적 요소를 화면에 표현하는 것은 소스 노드 측에서 수행한다.
 
커넥션 에딧파트의 Figure는 반드시 Draw2d  Connection 형식이어야 한다. 커넥션 에딧파트는 자신의 Figure의 Anchors를 소스와 타겟 노드로 설정한다.(이해가 안되면 앞서의 Draw2d의 소스,타깃,앵커를 참고한다)
 
여러가지면에서 커넥션은  다른 에딧파트와 크게 다를바가 없다. 실제 눈으로 보여져야할 모델을 가지고 있으며 심지어 자식객체를 가질 수 있고 다른 커넥션의 노드가 될 수도 있기도 하다.
 
Summary
 
지금까지 모델을 시각적으로 나타내는 것을 집중적으로 살펴보았는데 AbstractGraphicalEditPart를 확장하고 각 에딧파트의 모델에 따라서 적절하게 행위들 즉 메소드들을 재정의하는 것이 요점이 되겠다. 아래는 요점이 되는 메소드 목록이 되겠다.
 
  • createFigure() - editpart의 뷰 또는 Figrue를 생성한다. 이 메소드는 모델의 상태를 반영하지는 않는다. 그 것은 refreshVisuals()의 책임이다.
  • refreshVisuals() - 모델의 속성을 뷰에 반영한다. 복잡한 EditPart의 경우는 이 메소드를 분해하여 몇개의 helper메소드로 나눠야 할 것이다.
  • getModelChildren() - 이 메소드는 자식 editpart가 생성되어야 할 모델 요소가 있는지 판단하기위해서 호출된다.
  • getModelSource/TargetConnections() - children 과 비슷하지만 이 메소드에서 리턴하는 모델 요소들은 소스, 타깃 에디파트에 대한 커넥션 에딧파트를 의미한다.
 
Editing and EditPolicies
 
editPart들이 디스플레이되었다면 이제는 편집(editing)을 시작해야할 때이다. 편집은  editpart가 수행하는 가장 복잡한 작업이다. 편집은 모델에 변경을 일으키는 것 뿐 아니라 상호작용 동안의 발생하는 피드백을 보여주는 것 까지 포함하기 때문에 복잡한데.. 이런 상호작용을 추상화시키기 위해서 GEF 는 request를 사용한다. 사용자 UI 인터프리터나 도구등이 request를 생성하고 EditPart 인터페이스가 정의한 다양한 API를 상호작용 중에 호출한다. EditPart API 의 일부가 아래 그림에서 보여지고 있다.
                                   
 
 
1. 편집의 첫단계는 어떤 EditPart가 편집되는 것인지를 확인하는 것이다. 보통 현재 뷰어에서 선택된 selection 과 마우스의 위치를 통해서 계산된 editpart 의 어떤 조합이 될텐데, selection은 request 의 이해여부를 질의하여 확인할 수 있을 것이고, 마우스 아래 있는 영역, 소위 타겟이라고 하는 부분은 뷰어의도움과 getTargetEditPart(Request) 메소드를 통해서 확인될 수 있다. 모든 상호작용이 타겟을 가지는 것은 아니다.
 
2. 상호작용이 일어나는 동안- 특히 마우스 상호작용과 드래깅, 에딧파트는 상호작용에 있어서 자신의 역할에 기반하여 피드백을 보여줘야 하는데, 만일 상호작용을 수행하고 있는 부분이라면 소스 에딧파트이고 마우스 아래에 있는 부분이라면 타겟에딧파트이다. 예를들어 노드를 다이어그램 주위로 드래깅할때, 노드는 소스이고 다이어그램은 타겟이 되는 것이다. 노드는 사각형 또는 노드의 다른 표현이 될 수 있는 소스피드백을 보여줘야 할 것이고 다이어그램은 타겟피드백을 보여주도록 요청받을 것이다. 커넥션의 끝을 다시 연결할때 노드는 대신 타겟피드백을 보여줄 것이다. 어떤 상호작용은단지 소스에 대해서만 작동하기도 한다.
 
3. command는 결국 모델을 변경하는 것이다. 에딧파트는 요청(Request)에 대한 커멘드를 수행하도록 요청받는다. 커멘드는 또한  상호작용이 가능한지 결정하는데 도움이 될 수도 있다. 만일 커멘드가 없거나 실행될 수 없는 상황이라면 UI는 상호작용이 허락되지 않음을 나타낼 것이다.
 
4. 무엇인가를 하기위해 에딧파트와 소통할 수 있는 일반적인 API 가 있는데, 이 것들은 보통 즉각적인 모델 변경으로 이어지지는 않는다. 예를들어 대화창을 오픈한다고 해서 우리의 모델이 변경할 것 같지는 않다. 그렇지 않은가?
 
EditPolicies
 
EditPart가 편집 작업을 직접처리하는 것은 아니고 EditPolicies(편집정책) 를 사용한다. 각 편집정책은 하나의 편집 작업 또는 연관된 열련의 편집작업들에 주력한다. 이 것은 또한 편집 행위가 서로 다른 에딧파트 구현에 있어서 선택적으로 재사용 가능하게 해줄수 있다. 행위는 동적으로 변경될 수 있는데 레이아웃 또는 라우팅 메소드가 변경되는 것 처럼 말이다.
 
위에서 언급한 편집 메소드가 호출될때(performRequest()는 제외하고), 에딧파트는 그것을 편집정책에게 위임한다. 메소드에 따라서 요청을 처리하는 첫번째 정책에서 멈출수도 있고 또는 각 정책에게 Contribute 할 기회를 부여할 수도 있다. 자세한 것은 각 메소드 별로 API문서를 참고하자.
 
에딧파트의 생성 동안, createEditPolicies()메소드가 호출되고 에딧파트는 적절한 정책을 설치해야한다. 편집정책을 roles 를 사용하여 설치되는데 롤이란 것은 키 역할을 하는 식별자일 뿐이다.
GEF는 공통으로 사용되는 roles를 위한 몇개의 식별자를 제공하고 있다. GEF는 또한 이런 롤들과 함께 사용될 수 있는 정책들도 같이 제공하고 있다. 이 정책들중 많은 것들이 애플리케이션의 모델과 같이 작동하기 위해서는 확장되어서 사용되어져야할 필요가 있다.
 
Commands
 
commands 편집 과정 전반에 걸쳐 전달될 수 있는데 애플리케이션 모델에 발생하는 변경을 캡슐화하고  결합하는데 사용될 수 있겠다. 애플리케이션은 하나의 커멘드 stack을 가지고 있는데 커멘드들이 직접적으로 호출되는 것이 아니라 반드시 이 스택을 통해서 실행되어져야 한다.
 
The EditPart Lifecycle
 
 
 생명주기 관련해서 에딧파트 구현체들은 에딧파트가 모델에 대한 리스너를 추가하고 삭제할 때 활성화, 비활성화하는 것을 확장하는 것만 주의하기만 하면 되지만 에디파트의 전체 생명주기를 이해하고 있다는 것은 매우 중요한 것이다.
 
1) Creation
   시작은 생성부터이다. 모든 대개의 editpart들은 뷰어의 팩토리로부터 생성되어서 뷰어에 의해
   호출되거나 부모에딧파트에 의해 호출되고나서 다음 일련의 메소드들이 호출되는 그런 식이다. 
 
2) Getting Added to the Diagram
   setParent(...) - 부분(part)에게 부모가 누구인지 애기해주는 첫번째 스텝이다. 
   createFigure() - protected 접근자인데 호출되는 시점이 다소 흥미롭다. figure가 생성될 필요가 
   있는 시점에 부모와 모델은 이미 알려져있다.
   addNotify() - 자식요소가 완성되었다는 신호가 부모에게 전달된다.이 시점에서 자식은 다음과 같]
   은 것들을 한다.
 
          ① 뷰와 모델을 사용하여 뷰어에 자기자신을 등록한다. 
          ② 필요한 편집정책(editPolicies)를 생성한다.
          ③ 자신의 뷰를 처음으로 갱신하기 위해 refresh하고, 그리고나서 자식 및 커넥션과 같은 
             구조적인 것들을 조립(구축)한다. 
          
   activate() - editpart가 편집될 수 있도록 활성(active)화 되어야 함을 말한다. 부모는 단지 자기
   자식파트만을 활성화시킬 수 있다. 만일 뷰어가 자기의 컨트롤을 생성하였다면 유일하게 활성화
   되는 것은 root editpart 이다. editpart는 다음과 같은 활성화 작업을 해야 한다. 
          
          ① 모델 리스닝을 시작한다. 확장클래스는 반드시 이 메소드를 재정의하여 필요한 리스너
              를 추가해야한다.  
          ② 모든 편집정책(editpolicies)을 활성화시킨다.
          ③ 모든 자식들과 나가는 커넥션 에딧파트들을 활성화시킨다  
3) Normal Use
   이 시점에서 에딧파트는 일반적인 편집상태에 놓여있게 된다. 에딧파트는, 선택되고, 피드백을 보      여주고, 커멘드를 반환하고, 기타 등등.. 그 것이 더 이상 필요가 없어질때까지이런식인데.. 이것
   이 의미하는 것은 다이어그램에서 그 것이 제거되거나 또는 뷰어가 제거될때까지라는 뜻이다. 
 
4) Becoming Garbage 
    deactivate() - activate()의반대 메소드인데.. 확장 클래스는 반드시 이 메소드를 재정의하여
    활성화 동안에 추가된 리스너를 반드시 제거해야 한다. 
 
    ※ 남아있는 단계는 에딧파트가 제거될때에만 발생한다.즉 모델이 다이어그램에서 제거되는 경우
       를 의미한다. 만일 뷰어자체가 제거되는 거라면 deactivation()만이 해야할 유일한 단계이다. 이
       런 연유로 해서 남아있는 단계들은 무시될지라도 활성, 비활성은 공통적으로 확장되어야하는 
       메소드들이다.
 
    removeNotify() - 에딧파트가 이제 막 삭제될거라는 신호. 
 
          ① 에딧파트가 더이상 선택가능하지도 포커스를 가지지도 못한다.  
          ② 자식의 removeNofity를 호출한다.
          ③ 뷰어의 레지스트리로부터 에딧파트를 제거한다.
          ④ 커넥션 파트에 source, target 으로 등록되어 있다면 해당 등록을 삭제한다.
 
    setParent(null) - 제거 작업의 마지막 단계이다. 이 시점에서 부모와 뷰어는 더 이상 접근 가능하
    지않다. 
    
    ※ 에딧파트가 무덤에서 되돌아오는 경우는 없다. 모델에 가해진 변경을 되돌린다고 해서 즉 do          했던 것을 undo한다해서 제거된 에딧파트가 되돌아오는 것은 아니고 새로운 에딧파트가 생성
       되는 것이다. 이런 이유로 해서 커멘드는 에딧파트를 참조하고 있으면 안되고 에딧파트는 중요
       한 상태와 같은 정보를 가지고 있으면 안된다. 
 
Tools and the Palette
 
툴은 뷰어로부터의 대개의 이벤트를 처리한다. 
 
---이 후의 번역은 나중에 하기로 한다. --
 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
35 [EMF] EMF Tutorial EMF 튜터리얼 file 졸리운_곰 2023.08.23 21
34 Eclipse RAP Tutorial for Beginners - Workbench Application (OLD) file 졸리운_곰 2021.01.30 66
33 Learn Eclipse GMF in 15 minutes file 졸리운_곰 2019.11.27 42
32 [Eclipse] GEF entry series (10, an implementation of the form) file 졸리운_곰 2019.11.25 45
» GEF Programmer Guide 번역 졸리운_곰 2019.11.25 53
30 Learn Eclipse GMF in 15 minutes file 졸리운_곰 2019.11.20 41
29 RCP 에디터 정리 졸리운_곰 2019.11.20 122
28 다른 그림과 관련하여 GEF 편집기 레이아웃에서 그림의 위치 제한 조건을 동적으로 계산 Dynamically calculating the position constraints for a figure in a GEF editor layout in relation to another figure file 졸리운_곰 2019.11.20 90
27 RCP 등에서 .mf 파일로 다른 프로젝트 익스포트 포함시 라이브러리(메소드)를 찾지 못할 때, Eclipse RCP - cant resolve importing libraries in final build file 졸리운_곰 2019.10.15 181
26 ESE2006-EclipseModelingSymposium15_GMF.pdf file 졸리운_곰 2019.09.21 64
25 GMF_Creation_Review.pdf file 졸리운_곰 2019.09.21 74
24 Eclipse EMF and GMF Tutorial file 졸리운_곰 2019.09.21 46
23 GMF Tutorial/ko file 졸리운_곰 2019.09.20 162
22 Model Driven Architecture approach to domain of graphical editors file 졸리운_곰 2019.09.20 44
21 Single_Sourcing_RAP_RCP_en.pdf file 졸리운_곰 2019.05.15 27
20 Rich client platform 설명 및 배우기 참고 졸리운_곰 2019.05.15 89
19 Rich Ajax Platform, Part 1: 소개 file 졸리운_곰 2019.05.15 127
18 또 하나의 크로스 플랫폼: Eclipse RAP file 졸리운_곰 2019.05.15 143
17 Eclipse 4 RCP 튜토리얼(완료) file 졸리운_곰 2019.05.14 682
16 Updating UI in Eclipse RCP 졸리운_곰 2015.11.07 183
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED