목공책 하나 들이셔요~

2014년 3월 12일 수요일

[JavaFX] 아키텍쳐

이글은 Oracle의 JavaFX Architecture에 대한 글을 기반으로 작성되었습니다.

http://docs.oracle.com/javafx/2/architecture/jfxpub-architecture.htm


아래의 그림이 JavaFX 플랫폼 전체 컴포넌트들에 대한 구조를 표현하고 있습니다. 그리고 그림 아래에 각 컴포넌트들에 대한 설명과 이들이 어떻게 연관되는지를 짧게 설명을 추가햇습니다. JavaFX API 아래에는 JavaFX를 돌리기 위한 각종 엔진들이 위치하고 있습니다. 이 엔진들은 JavaFX의 고성능 그래픽 엔진인 Prism과 작고 효율적인 윈도우 시스템인 Glass, 그리고 미디어 엔진과 웹 엔진 등으로 구성되어 있습니다. 비록 이 엔진들은 노출되어 있지 않아 직접 사용하지는 않지만 대략의 역할과 기능을 숙지하는 것이 JavaFX를 이해하는데 큰 도움이 됩니다.



Scene Graph

Scene Graph는 JavaFX 어플리케이션의 구성하는 시작점이자 JavaFX 아키텍쳐의 최상위 레이어에 위치합니다. Scene Graph는 어플리케이션의 유저인터페이스를 구성하는 위젯들의 계층적 트리를 의미합니다. 그리고 Scene Graph는 입력을 처리하고 자신을 렌더링합니다.

Scene Graph의 한 요소를 노드(Node)라고 합니다. 각 노드는 ID, 스타일 클래스 그리고 영역(bounding volume)을 가지고 있습니다. 최상위의 루트 노드를 제외하고 Scene Graph의 모든 노드는 하나의 부모 노드와 자식이 없거나 여러개의 자식을 가질 수 있습니다. 그리고 노드들은 다음의 것들을 가집니다.

  • 블러(blur)나 그림자(shadow) 등의 효과(effects)
  • 투명도 (opacity)
  • 트랜스폼 (transforms)
  • 이벤트 핸들러 (마우스나 키보드 등의 입력을 처리)
  • 어플리케이션 고유의 상태들

Swing이나 AWT(Abstract Window Toolkit)과 달리 JavaFX Scene Graph는 그래픽 프리미티브(primitives)까지 포함하고 있습니다. 예를 들어 사각형, 텍스트 그리고 컨트롤, 레이아웃, 이미지, 미디어 등을 의미합니다.

Scene Graph는 일반적으로 UI를 쉽게 코딩할 수 있게 도와줍니다. 예를 들어 애니메이션은 javafx.animation API를 이용하거나 XML에 정의하는 것만으로도 쉽게 구현할 수 있습니다.

javafx.scene API는 다음과 같은 것들을 생성할 수 있게 해줍니다.

  • 노드(note) : 도형(2D, 3D), 이미지, 미디어, 임베디드 웹 브라우저, 텍스트, UI 컨트롤, 차트, 그룹 그리고 컨테이너들
  • 상태(state) : 트랜스폼 (노드의 위치와 방향), 시각 효과 기타 컨텐츠의 시각적인 상태
  • 효과(effect) : Scene Graph 노드들의 외관을 변경합니다. 예를 들어 블러(blur), 쉐도우(shadow) 그리고 색 보정 등이 있습니다.

더 자세한 내용은 여기를 참조하세요.

JavaFX를 위한 API

Scene Graph와 더불어 JavaFX의 최상위를 차지하는 것이 JavaFX API입니다. 이 API는 비교할 수 없는 자유도와 유연성을 가졌습니다. JavaFX를 위한 새로운 API는 다음과 같은 기능을 가졌습니다.

  • Generics, Annotations, Multithreading과 같은 강력한 Java의 기능을 사용할 수 있습니다.
  • JVM기반의 스크립트 언어인 Groovy나 JavaScript등을 지원하므로 웹 개발자들이 쉽게 접근할 수 있습니다.
  • 크고 복잡한 JavaFX 어플리케이션을 위해 Groovy와 같은 쉬운 시스템 언어를 사용할 수 있습니다.
  • 고성능의 Lazy binding, 바인딩 표현식(expression), 바인딩 시퀀스 표현식 그리고 부분적 바인드 재평가(reevaluation) 등의 다양한 바인딩 기능을 제공합니다. Groovy와 같은 언어들은 JavaFX Script와 유사한 문법으로 바인딩을 사용할 수 있습니다.
  • Java 컬렉션 라이브러리를 확장하여 관측 가능한 (observable) 리스트와 맵을 제공합니다. 이를 통해 데이타 모델과 유저 인터페이스 간에 긴밀한 관계를 표현할 수 있습니다. 즉 데이타 모델이 변경되면 그와 연결된 UI가 자동적으로 변경되는 식입니다.

JavaFX API와 프로그래밍 모델은 JavaFX 1.x 에서부터 이어져 왔던 것입니다. 대부분의 JavaFX API는 직관적으로 Java로 포팅되었습니다. 레이아웃과 미디어 등의 일부 API들은 JavaFX 1.x에서 부터 제기되었던 개발자들의 피드백을 고려하여 디테일이 대폭 향상되었고 단순화되었습니다. JavaFX는 스타일링을 위한 CSS와 접근성을 위한 ARIA 규격 등의 웹 표준을 대폭 채용했습니다. 더 많은 웹표준을 채용하기 위한 검토도 진행 중입니다.

그래픽 시스템

JavaFX의 그래픽 시스템은 JavaFX Scene Graph 아래에 구현됩니다. 그래픽 시스템은 2D와 3D 모두를 지원합니다. 그리고 가능하면 하드웨어 가속을 지원하며 지원되는 하드웨어가 아닌 경우에는 소프트웨어 렌더링을 지원합니다.
JavaFX에는 두개의 가속화된 파이프라인이 구현되었습니다.

Prism : Prism은 렌더링을 담당합니다. 하드웨어 혹은 소프트웨어 렌더러 모두에 동작하며, 3D를 포함합니다. Prism은 JavaFX Scene의 렌더링과 rasterization을 책임집니다. 다음의 여러 렌더링 경로가 보통 사용됩니다.

  • Windows XP / Windows Vista와 DirectX 9
  • Windows 7과 DirectX 11
  • Mac, Linux, Embedded에서 OpenGL
  • 지원되는 하드웨어가 아닌 경우 Java2D
    (되도록이면 하드웨어 가속을 사용합니다. Java2D 렌더러는 JRE와 더불어 이미 널리 배포되어 있으며 호환성이 높습니다. 하지만 하드웨어 가속에 비해서는 매우 느립니다)

Quantum 툴킷은 Prism과 Glass 윈도우 툴킷을 서로 연결합니다. 그리고 이벤트 핸들링과 렌더링과 관련된 쓰레딩 규칙들을 관리합니다.

Glass 윈도우 툴킷

Glass 윈도우 툴킷은 JavaFX 스택의 가장 아래에 위치합니다. Glass는 윈도우, 타이머, surface 등을 관리하는 역할을 합니다. Glass는 OS가 제공하는 윈도우 시스템과 연결하기 때문에 플랫폼마다 다르게 구현됩니다.

Glass 툴킷은 또한 이벤트 큐를 관리합니다. 자체적으로 이벤트 큐를 관리하는 AWT와 달리 Glass는 OS의 이벤트큐를 사용합니다. 또한 AWT와 달리 Glass는 JavaFX 어플리케이션과 같은 쓰레드에서 동작합니다. JavaFX 어플리케이션이 하나의 쓰레드에서 동작하게 됨으로서 많은 복잡한 이슈들이 해결되었습니다.

쓰레드들

시스템은 두개 혹은 세개의 쓰레드를 수행합니다.

  • JavaFX 어플리케이션 쓰레드 : JavaFX 어플리케이션 개발자가 주로 사용하는 쓰레드입니다. Scene Graph는 다른 쓰레드에서 만들어지고 조작될 수 있지만 루트 노드가 Scene의 라이브 오브젝트에 연결되면 JavaFX 어플리케이션 쓰레드에서 동작하게 됩니다. 이를 이용하여 개발자는 복잡한 Scene Graph를 백그라운드 쓰레드에서 만들면서 메인 쓰레드에서는 애니메이션을 수행할 수 있게 해줍니다. JafaFX 어플리케이션 쓰레드는 AWT나 Swing의 이벤트 디스패치 쓰레드(EDT, Event Dispatch Thread)와는 다릅니다. 그러므로 JavaFX 코드를 Swing 어플리케이션에 이식할 때는 이점에 유의해야 합니다.
  • Prism 렌더링 쓰레드 : 이 쓰레드는 이벤트 디스패쳐와는 별개로 렌더링만을 담당합니다. 즉 frame N+1이 준비되는 동안 frame N을 보여주는 역할입니다. 요즘 시스템들은 여러개의 CPU 코어를 가지고 있기 때문에 이런 동시 처리는 매우 잇점이 많습니다. Prism 쓰레드는 필요한 경우 여러개의 래스터라이제이션 쓰레드를 가지고 부하가 많은 렌더링을 수행할 수 있습니다.
  • 미디어 쓰레드 : 이 쓰레드는 백그라운드에서 프레임들을 동기화하는 역할을 합니다.

펄스(Pulse)

펄스는 심장박동과 같이 JavaFX Scene Graph의 요소들이 Prism과 동기화되는 이벤트를 의미합니다. 펄스는 최대 60 fps까지 올릴 수 있으며 애니메이션을 수행할 때마다 실행됩니다. 애니메이션이 실행되는 상황이 아니라도 Scene Graph가 변경될 때 자동으로 스케쥴링됩니다. 예를 들어 버튼의 위치가 변경되면 펄스가 스케쥴됩니다.

펄스가 발생하면 Scene Graph의 엘리먼트는 렌더링 레이어와 동기화됩니다. 펄스는 어플리케이션 개발자로 하여금 이벤트를 비동기적으로 처리할 수 있게 해줍니다. 이 중요한 기능은 시스템이 펄스에 따라 이벤트를 수행하고 배치를 실행할 수 있게 해줍니다.

레이아웃과 CSS 또한 펄스 이벤트와 연결될 수 있습니다. Scene Graph의 여러 변경들은 레이아웃이나 CSS의 성능을 떨어뜨리는 여러 변화를 초래할 수 있습니다. 시스템은 자동적으로 CSS와 레이아웃의 변화를 펄스 주기에 맞게 변경함으로서 성능의 저하를 막을 수 있습니다. 어플리케이션 개발자는 펄스를 무시하고 직접 레이아웃의 변화를 만들 수도 있습니다.

Glass 윈도우 툴킷은 펄스 이벤트를 실행할 책임을 갖습니다. 일르 위해서 고해상도의 네이티브 타이머를 사용합니다.

미디어와 이미지

JavaFX의 미디어는 javafx.scene.media API를 통해 제공됩니다. JavaFX는 비디오와 오디오를 모두 지원합니다. MP3, AIFF, WAV 오디오 파일과 FLV, H264 비디오 파일을 지원합니다. JavaFX 미디어 기능은 세개의 분리된 컴포넌트를 통해 제공되는데 미디어 오브젝트는 미디어 파일을 표현하고, 미디어 플레이어는 미디어 파일을 재생하며, 미디어 뷰는 미디를 노드에 보여주는 역할을 합니다.

미디어 엔진 컴포넌트는 성능과 안정성을 고려하여 설계되었으며 동시에 크로스 플랫폼을 지원합니다.

더 자세한 내용은 여기를 참조하세요.

웹 컴포넌트

웹 컴포넌트는 JavaFX에 새로 추가된 WebKit 기반의 UI 컨트롤입니다. 이 API를 이용하여 웹 뷰어와 웹 브라우징 기능을 제공합니다. WebKit은 오픈소스 웹 브라우저 엔진으로서 HTML5, CSS, JavaScript, DOM, SVG 등을 지원합니다. 그리고 Java 어플리케이션을 통해 다음의 기능들을 구현할 수 있습니다.

  • 로컬이나 원격 URL의 HTML을 읽어들여 렌더링합니다.
  • 브라우징 히스토리와 "앞으로", "뒤로" 등의 네이게이션을 지원합니다.
  • 컨텐츠를 리로딩할 수 있습니다.
  • 웸 컴포넌트에 효과(effect)를 추가할 수 있습니다.
  • HTML 컨텐츠를 편집할 수 있습니다.
  • JavaScript 커맨드를 실행할 수 있습니다.
  • 이벤트를 처리할 수 있습니다.

이 임베디드 브라우저 컴포넌트는 다음 클래스로 제공됩니다

  • WebEngine은 기본적은 페이지 브라우징 기능을 제공합니다.
  • WebView는 WebEngine을 감싸고 HTML 컨텐츠를 Scene에 보이게 합니다. 그리고 effect와 transformation을 지원합니다. 이것은 Node 클래스의 확장입니다.

추가적으로 Java와 JavaScript는 서로를 호출할 수 있습니다.

더 자세한 내용은 여기를 참조하세요.

CSS

JavaFX CSS(Cascading Style Sheet)는 JavaFX 어플리케이션의 소스 코드를 변경하지 않고 UI의 스타일을 커스터마이징할 수 있게 해 줍니다. CSS는 JavaFX의 어떤 노드에도 적용될 수 있으며 비동기적으로 적용될 수도 있습니다. 또한 JavaFX는 동적으로 CSS를 로딩하여 적용할 수도 있습니다.


JavaFX CSS는 W3C CSS 버전 2.1을 기반으로 하여 CSS 버전 3.0의 일부 기능을 추가한 것입니다. JavaFX CSS는 자신이 이해하지 못하는 CSS구문도 문제없이 호환되므로 HTML 페이지를 위해 만든 CSS를 그대로 불러와 JavaFX의 CSS로 사용할 수도 있습니다. 모든 JavaFX 고유의 프로퍼티들은 "-fx-"라는 접두어가 붙으므로 구별이 가능합니다.

더 자세한 내용은 여기를 참조하세요.

UI 컨트롤들

JavaFX UI 컨트롤들은 Scene Graph의 노드를 구성하는 API를 통해 만들 수 있습니다. JavaFX UI 컨트롤들은 플랫폼과 무관하게 동일한 외관과 기능을 가지고 CSS를 통해 스타일을 조정할 수 있습니다.

아래 그림은 현재 지원되는 UI 컨트롤들을 보여줍니다. TitlePane이나 Accordion 등의 새로운 UI 컨트롤들은 JavaFX SDK를 통해 소개되었습니다. 이 새 컨트롤들은 javafx.scene.control 패키지에 있습니다.


더 자세한 내용은 여기를 참조하세요.

레이아웃

레이아웃 컨테이너 혹은 페인은 UI 컨트롤들의 유연하고 동적인 배치를 지원합니다. JavaFX는 다음과 같은 레이아웃 모델을 지원합니다.

  • BorderPane 클래스는 노드들을 top, bottom, right, left, center 영역에 놓을 수 있습니다.
  • HBox 클래스는 하나의 행(row)에 수평으로 배치합니다.
  • VBox 클래스는 하나의 열(column)에 수직으로 배치합니다.
  • StackPane 클래스는 노드들을 뒷쪽에서 앞쪽으로 겹쳐 배치합니다.
  • GridPane 클래스는 노드들을 행과 열의 격자에 배치할 수 있게 합니다.
  • FlowPane 클래스는 컨텐츠를 수평 혹은 수직으로 배치하되 경계를 넘어서면 다음 줄로 넘어가게(flow) 합니다.
  • TilePane 클래스는 노드들을 같은 크기의 셀이나 타일에 배치합니다.
  • AnchorPane은 top, bottom, left, center 등에 앵커를 배치할 수 있게 합니다.

원하는 레이아웃을 위해 이 레이아웃 클래스들은 서로를 포함할 수도 있습니다. 레이아웃 클래스들은 javafx.scene.layout 패키지에 존재합니다.

더 자세한 내용은 여기를 참조하세요.

2D와 3D Transformation

JavaFX Scene Graph의 모든 노드들은 다음과 같은 javafx.scene.transform 클래스들을 이용하여 트랜스폼될 수 있습니다. (행렬 연산과 유사합니다)

  • translate : 노드의 x,y,z좌표를 각각 이동시킵니다.
  • scale : 노드의 크기를 확대 혹은 축소합니다.
  • shear : 한 축만을 회전시켜서 축간의 각도가 직각이 아니게 합니다.
  • rotate : 특정 축을 중심으로 회전시킵니다.
  • affine : 2D와 3D간의 선형 맵핑을 수행합니다.

더 자세한 내용은 여기를 참조하세요.

시각효과

JavaFX는 Scene Graph의 노드들을 실시간으로 시각적 효과를 줄 수 있습니다. JavaFX의 시각효과는 기본적으로 픽셀 기반이기 때문에 일단 이미지 형태로 렌더링된 후에 적용됩니다.
다음과 같은 시각효과들이 있습니다. (이외에도 많습니다)

  • Drop Shadow : 해당 컨텐츠의 그림자를 그립니다.
  • Reflection : 해당 컨텐츠의 반사된 거울 이미지를 그립니다.
  • Lighting : 광원을 흉내내어 해당 컨텐츠를 사실적으로 보이게 합니다.

더 자세한 내용을 보시려면 여기를 참조하세요.

댓글 없음:

댓글 쓰기