2014년 9월 18일 목요일

JavaFX UI - 20.Menu


JavaFX 어플리케이션에서 메뉴를 생성하기 위해서는 다음 클래스들이 사용된다.
  • MenuBar
  • MenuItem
    • Menu
    • CheckMenuItem
    • RadioMenuItem
    • CustomMenuItem
      • SeparatorMenuItem
  • ContextMenu

아래 화면은 전형적인 메뉴바의 모습을 보여준다.



1. Building Menus in JavaFX Applications

Menu는 사용자에게 보여지는 actionable 항목들의 목록이다. Menu가 화면에 보여지면 사용자는 그 중 하나를 선택할 수 있다. 사용자가 하나의 항목을 선택하면 menu는 화면에서 사라진다. Menu를 사용하면, 어플리케이션에서 항상 보여질 필요가 없는 기능들을 메뉴에 위치시킴으로써, UI 공간을 절약할 수 있다.

Menu bar에 있는 메뉴 아이템들은 일반적으로 카테고리에 의해 그룹화 된다. 이를 위한 코드 패턴은 먼저 menu bar을 생성하고 카테고리 메뉴를 정의한 다음, 각 카테고리에 메뉴 아이템을 위치시킨다. JavaFX 어플리케이션에서 메뉴를 생성할 때는 다음과 같은 menu item 클래스들을 사용한다.
  • MenuItem - actionable option 생성을 위해 사용된다.
  • Menu - sub menu 생성을 위해 사용된다.
  • RadioButtonItem - 상호배타적인 선택 option을 생성하기 위해 사용된다.
  • CheckMenuItem - 선택/해제 상태 간의 토글(toggle) option을 생성하기 위해 사용된다.

한 카테고리 내의 menu item들을 분리하기 위해서는 SeparatorMenuItem 클래스를 사용한다.
카테고리를 통해 구성된 메뉴들은 일반적으로 윈도우의 상단에 위치한다. 만약 menu bar를 위한 공간 할당이 불가능하다면, 마우스 클릭에 의해 열리는 context menu을 사용할 수 있다.


2. Creating a Menu Bar

Menu ber는 UI 상의 어느 곳에든 위치할 수 있지만, 일반적으로 UI의 상단에 위치한다. Menu bar의 크기는 어플리케이션 윈도우의 너비에 맞게 재조정된다. Menu bar에 추가된 각 메뉴들은 텍스트를 가진 button으로 표현된다.

아래 예제는 식물과 관련한 정보 (이름, 학명, 사진, 요약설명)를 관리하는 어플리케이션 코드로서 여기에는 세 가지 메뉴 카테고리가 만들어 졌다. : File, Edit, View

Example 20-1 Menu Sample Application
 


 


다른 UI 컨트롤들과는 달리, Menu 클래스를 비롯한 다른 menu item 클래스들은 Node 클래스를 상속하지 않는다. 따라서 이들은 scene에 직접 추가될 수 없으며, menu bar에 추가되기 전까지는 보여질 수 없다.



3. Adding Menu Items

File 메뉴에 다음의 menu item들을 추가한다.
  • Shuffle - 식물들에 대한 정보를 로드한다.
  • Clear - 모든 정보를 제거하고 화면은 초기화한다.
  • Separator - menu item들을 분리한다.
  • Exit - 어플리케이션을 종료한다.


아래 예제는 Shuffle 메뉴를 생성하는 소스 코드이다. 사용자가 메뉴를 클릭 했을 때의 수행되는 액션은 setOnAction 메서드를 이용하여 정의한다.

Example 20-2 Adding the Shuffle Menu Item with Graphics






Shuffle 메뉴가 선택되면 이벤트 핸들러에 의해 shuffle 메서드가 호출된다. shuffle 메서드에서는 새로운 식물 정보들로 메인 화면을 재정의한다.

Clear 메뉴 아이템이 어플리케이션 scene을 초기화하기 위해 사용된다. 초기화는 메인 화면의 VBox 컨테이너를 안 보이게 함으로서 가능하다.

Example 20-3 Creating the Clear Menu Item with Accelerator



MenuItem 클래스는 개발자가 메뉴 단축키를 지정할 수 있도록 구현되었다. 위 Clear 메뉴의 경우 사용자가 Ctrl+X 단축키를 통해 메뉴 선택과 동일한 효과를 내도록 구현되었다.

Exit 메뉴는 어플리케이션을 종료한다.

Example 20-4 Creating the Exit Menu Item




위에서 새롭게 생성된 menu item들을 File menu에 추가하기 위해 다음과 같은 코드를 사용한다.

Example 20-5 Adding Menu Items



위 예제에서는 menu item들을 분리하기 위해여 separator menu을 생성하여 추가하였다.

위에 나온 Menu 예제들을 조합하여 완성된 어플리케이션을 실행하면 다음 화면과 같은 모습이다.




다음 예제는 View 메뉴를 통해 식물 정보를 구성하는 요소들(이름, 학명, 사진, 요약설명)을 숨기거나 보이도록 한다. 예제에서와 같이 createMenuItem 메서드를 구현하고 어플리케이션의 start 메서드 내에서 이를 호출하도록 한다. 이 메서드는 네 개의 CheckMenuItem 객체를 생성하여 View 메뉴에 추가한다.

Example 20-6 Applying the CheckMenuItem Class to Create Toggle Options



CheckMenuItem 클래스는 MenuItem 클래스를 상속받은 menu item 클래스이다. CheckMenuItem은 선택/해제 두 가지 상태로 토글될 수 있으며, 선택 상태가 되었을 때 해당 menu item에 체크(√) 표시가 보여진다.
 

위 예제는 네 개의 CheckMenuItem 객체를 생성하였고, 이들 각각의 selectedProperty 프로퍼티가 변경되는 이벤트가 발생하면 해당하는 정보를 디스플레이하는 컨트롤을 숨기도록 구현하였다. 아래 화면은 위 예제 코드를 어플리케이션에 적용했을 때의 모습이다.




4. Creating Submenus

Edit 메뉴에 대해서는 두 개의 menu item을 추가한다. (Picture Effect, No Effects)

Picture Effect 메뉴는 하위에 세 개의 menu item을 가지는 sub menu로 만들어, 하위 메뉴 선택에 따라 사진에 시각적 효과를 적용하도록 한다. No Effects 메뉴는 현재 적용된 시각적 효과를 제거하고 이미지의 초기 상태로 복원하는 menu item으로 만든다.

Sub menu의 하위에 생성되는 menu item은 RadioMenuItem 클래스를 사용한다. 생성된 RadioMenuItem 객체들은 하나의 toggle group으로 묶어서 아이템들이 상호배타적으로 선택될 수 있도록 한다.

Example 20-7 Creating a Submenu with Radio Menu Items


각 radio menu item들에 대한 시각적 효과를 정의하기 위하여 setUserData 메서드가 사용되었다. Toggle group 내의 한 아이템이 선택되면, 그에 해당하는 효과가 사진에 적용된다.

아래 화면은 Edit 메뉴가 추가된 어플리케이션에서 Shadow 효과 메뉴를 선택하기 직전의 모습과선택 후의 모습이다.







아직 아무 시각적 효과도 적용되지 않은 상태에서는, MenuItem 클래스의 setDisable 메서드를 이용하여 No Effects 메뉴를 비활성화 시킬 수 있다. 이를 위해 Example 20-7을 아래와 같이 수정한다.

Example 20-8 Disabling a Menu Item




Picture Effect 메뉴의 하위 RadioMenuItem들 중 아무것도 선택되지 않았다면, 아래와 같이 No Effect 메뉴가 비활성화 된다.
 




5. Adding Context Menus

요구되는 기능에 대한 UI 공간이 부족한 경우, context menu를 사용할 수 있다. Context menu는 마우스 클릭을 통해 나타나는 팝업 윈도우 메뉴이다. 하나의 context menu는 하나 이상의 menu item들을 포함할 수 있다.

위 Menu Sample 어플리케이션에서 보여지는 ImageView에 context menu를 추가하여 사용자가 이미지를 복사할 수 있도록 아래와 같은 코드를 추가한다.

Example 20-9 Defining a Context Menu



사용자가 ImageView 객체를 마우스 오른버튼으로 클릭하면, context menu의 show 메서드가 호출되어 화면에 보여진다.

Context menu의 ‘Copy Image’ 메뉴에 대해 정의된 setOnAction 메서드에서는 클립보드 객체를 하나 생성하여 현재 선택된 이미지를 클립보드에 추가한다. 아래 화면은 사용자가 ImageView 상의 이미지를 복사하는 모습이다.



더 많은 개선을 위해 context menu에 더 많은 menu item들을 추가할 수 있다. 또한 CustomMenuItem 클래스를 통해 맞춤형 menu를 만들 수도 있다. 메뉴 안에 임의의 node를 삽입하거나 menu item으로서 button이나 slider를 지정할 수도 있다.

JavaFX UI - 19.Titled Pane & Accordion


Titled Pane은 타이틀을 가진 panel이다. 이 panel은 열리거나 닫힐 수 있으며, UI 컨트롤 또는 이미지, 레이아웃 컨테이너에 추가된 엘리먼트 그룹 등과 같은 모든 형태의 Node들을 포함할 수 있다.

Titled Pane은 accordion 컨트롤을 이용하여 그룹화될 수 있다. Accordion 컨트롤은 여러 panel들을 생성하고 한번에 하나의 panel 만 보여주고자 할 때 사용된다.

아래 화면은 세 개의 titled pane을 묶은 accordion 컨트롤을 보여준다.

1. Creating Titled Panes

TitledPane 컨트롤을 생성하기 위해 타이틀과 내용을 정의한다. 이를 위해 TitledPane 클래스의 생성자를 사용하거나, setTextsetContent 메서드를 사용할 수 있다.

Example 19-1 Declaring a TitledPane Object

 
위 코드 샘플을 통해 보여지는 Titled pane의 모습은 아래와 같다.



Titled Pane의 크기는 내부 컨텐트의 preferred size를 수용하기 위하여 재조정된다. Titled Pane의 컨텐트로써 멀티 라인 텍스트가 지정될 수 있다.



Titled Pane의 크기를 명시적으로 지정하지 않도록 한다. Titled pane이 열리거나 닫힐 때 비정상적인 상황을 유발할 수 있다.
아래 예제 코드는 GridPane 레이아웃 컨테이너를 이용하여 titled pane의 컨텐트를 구성하는 코드이다.

Example 19-2 Titled Pane with the GridPane Layout Container


위 코드를 통해 생성된 titled pane의 모습은 아래와 같다.



디폴트로 모든 titled pane은 접힐 수 있고, 접히거나 열리는 움직임에 애니메이션 효과가 적용된다. 만약 titled pane이 접히는 것을 막고자 한다면 setCollapsible(false) 메서드를 사용한다. 또한 setAnimated(false) 메서드를 통해 애니케이션 효과도 없앨 수 있다.

Example 19-3 Adjusting the Style of a Titled Pane



2. Adding Titled Panes to an Accordion

Titled pane은 독립적으로 사용될 수도 있고, Accordion 컨트롤을 통해 그룹화되어 사용될 수도 있다.

여러 titled pane들을 하나의 accordion에 추가하는 것은 toggle 버튼들을 하나의 toggle group에 추가하는 것과 유사하다. Accordion에서는 여러 titled pane이 동시에 열릴 수 없으며, 한번에 오직 하나의 titled pane 만이 열릴 것이다.

Example 19-4 Accordion and Three Titled Panes



Accordion에 추가된 모든 titled pane들은 초기 디폴트 설정으로 인해 접혀있다. 특정 titled pane을 열려 있도록 하려면 setExpandedPane 메서드를 사용한다.




3. Processing Events for an Accordion with Titled Panes

아래 예제는 두 가지 형태의 titled pane을 생성한다. 하나는 email client UI를 가지는 독립 titled pane이고, 다른 하나는 서로 다른 이미지들을 컨텐트로 가지는 세 개의 titled pane과 이를 accordion을 통해 그룹화하였다. Accordion을 통해 선택된 titled pane의 이미지가 email client UI 상의 이미지 첨부로 설정된다.

Example 19-5 Implementing ChangeListener for an Accordion





아래 화면은 위 예제가 실행된 초기 화면이다. 아직 accordion 상에서 이미지가 선택되지 않았으므로 첨부파일 지정이 “N/A”로 표시된다.



 
사용자가 accordion에서 titled pane을 선택한다면 아래와 같이 보일 것이다.


JavaFX UI - 18.Tooltip


Tooltip 클래스는 다른 UI 컨트롤에 대한 부가 정보를 표시하기 위해 일반적으로 사용되는 UI 컴포넌트이다. 툴팁은 setTooltip 메서드를 통해 다른 컨트롤 상에 지정될 수 있다.

툴팁은 두 가지의 서로 다른 상태를 가진다. : activated, showing

마우스가 해당 컨트롤 상에서 움직일 때, 툴팁이 활성화된다. 그리고 실제로 툴팁이 보여지면 showing 상태가 된다. 화면에 보여진 툴팁 또한 활성화된 상태이다. 일반적으로 툴팁이 활성화되는 때와 실제로 보여지는 때 사이에는 약간의 시간 지연이 있다.

아래 화면은 password field에 툴팁을 설정한 화면이다.



1. Creating a Tooltip

위 화면과 같이 툴팁을 가진 password field를 생성하는 샘플 코드는 아래와 같다.

Example 18-1 Adding a Tooltip to the Password Field



Javafx.scene.control 패키지에 정의된 각 UI 컨트롤들은 툴팁은 설정하기 위한 setTooltip 메서드를 가진다.
Tooltip 클래스는 Labeled 클래스를 상속하였으므로, 텍스트 뿐만 아니라 그래픽 아이콘까지 지정할 수 있다.

아래 예제는 툴팁에 그래픽 아이콘을 추가하는 샘플 코드이다.

Example 18-2 Adding an Icon to a Tooltip



코드가 적용되면 아래와 같은 모습의 툴팁을 설정할 수 있다.



2. Presenting Application Data in Tooltips

아래 화면은 호텔숙박 총액을 계산하기 위하여 사용자가 툴팁에 디스플레이되는 정보를 활용할 수 있도록 구현한 어플리케이션 화면이다.



각 체크박스에는 툴팁이 설정되어 있으며, 이 툴팁들은 각 예약 옵션에 대한 비용을 표시하고 있다. 만약 사용자가 체크박스를 선택한다면, 그에 해당하는 비용이 총액에 더해질 것이다. 반대로 체크박스의 선택이 해제되면 총액에서 해당 비용이 차감된다.
아래 예제는 위 어플리케이션에 대한 소스 코드이다.

Example 18-3 Using Tooltips to Calculate Hotel Rates


2014년 9월 17일 수요일

Do you know BigTIFF?

얼마전 GeoNURIS Desktop을 사용하여 시스템을 구축 중에 있는 사용자로부터 tiff 파일을 읽는데 오류가 발생한다는 내용과 함께 해당 tiff 파일(약 4.68G)을 받았다.

지금까지 tiff 파일을 읽는데 문제가 발생한 적이 없었기에 파일이 온전치(?) 못하거나 사용자 조작 미숙일거라 판단하고, 바로 디버깅에 돌입하였다.
그러나 디버깅을 시작한지 얼마 안되어 곧바로 밀려오는 멘붕.... 이건 뭐지??

소스 없이 JAI (Java Advanced Image) 모듈을 디버깅하는데.. 도통 알 수 없는 코드 블럭을 종횡무진하면서 파일로부터 데이터를 읽어대는데... 30분이 넘도록 그러고 계신다...

예전부터 tiff 포맷이 궁금했으나.. 궂이 내가 그걸 들여다 볼 필요가 있겠냐는 생각으로 손대지 않았지만, 갑자기 승부욕이 불타올라 tiff 규격을 해부하면서 원인 파악에 나섰다.

별의 별 상상력을 다 동원해가며 문제 원인을 예상하고, 그 문제가 맞는지 테스트해 보는 과정을 별다른 진전 없이 반복하기를 사흘째... 초조.. 낙담..

Tiff 헤더에서 읽힌 버전 넘버에 별 신경을 안 쓰다가... 가만히 보니 42 (고정값)가 아니라 43 인거다.
JAI에서 버전 넘버가 이상하다는 것을 알려주기만 했어도 쉽게 갈 수 있었는데.... ㅜㅜ

버전 넘버 43을 구글링하다가 발견한 것이 BigTIFF !

Adobe 사의 Steve Carlsen에 의해 제안된 규격으로 아직 정식 규격으로 채택된거 같진 않아 보인다. BigTIFF 규격은 64bit OS에 의해 지원되는 파일 사이즈가 커짐에 따라, 4G 이상의 tiff 파일을 지원하기 위하여 제안된 규격으로써 JAI에서도 아직 지원하지 않고 있는 규격이다.

tiff 파일의 내부 구조는 굉장히 가변적이고 확장적이며, 이를 위해 tagging된 데이터 블럭들이 서로를 참조하고 있다.
기존의 tiff 규격에서는 데이터블럭의 오프셋을 나타내기 위하여 4byte unsigned int를 사용하는데, 4G 이상의 큰 파일 상에서의 오프셋을 지정하기에는 부족하였다.

BigTIFF에서는 8byte unsigned long 값을 사용하여 오프셋을 표현하도록 되어 있으며, 이 밖에 데이터타입의 추가확장을 포함한 전반적인 규격 변경이 이루어졌다.


결국 BigTIFF를 읽을 수 있도록 JAI 코드를 확장하여, GeoNURIS Desktop에 반영하였더니, 드디어 문제의 tiff 파일이 열렸다.  그 순간 소름이 확 돋았다는 ... ㅋ
심지어 ArcMap이나 QGIS와 비교하여 속도가 더 빠르다는 사실에 뿌듯~~

앞으로 BigTIFF를 읽을 때도 GeoNURIS Desktop에서~~  (^^) v


혹시나 비슷한 문제로 헤딩(?)하시는 분들이 있을까 해서 정보 공유합니다.
 BigTIFF 관련 내용은 아래 링크를 참고하세요~
BigTIFF File Format Proposal

2014년 9월 16일 화요일

JavaFX UI - 17.HTML Editor


HTMLEditor 컨트롤은 풍부한 기능을 갖춘 텍스트 편집기이다. HTML5 문서 편집이 가능하고, 다음과 같은 편집 기능들을 포함한다.

  • 텍스트 포맷팅 : bold, italic, underline, strike
  • Paragraph setting : format, font family, font size
  • 포그라운드 및 백그라운드 색상
  • Text indent (들여쓰기)
  • Bulleted and numbered lists
  • 텍스트 정렬
  • Adding a horizontal rule
  • 복사/붙여넣기

아래 화면은 JavaFX 어플리케이션에 텍스트 편집기가 추가된 모습이다.



1. Adding and HTML Editor

HTMLEditor
컨트롤은 아래 예제에서와 같이 직접 scene에 추가될 수도 있고, 별도의 레이아웃 컨테이너를 통해 추가될 수도 있다.

Example 17-1 Adding an HTML Editor to a JavaFX Application



위 예제를 실행하면 아래와 같은 어플리케이션이 나타난다.


텍스트 포맷팅을 위한 툴바는 기본 구현에서 제공되는 것으로써, 이를 숨길 수는 없다. 그러나 CSS 스타일을 통해 편집기 모습을 변경할 수 있다.

Example 17-2 Styling the HTMLEditor



위와 같은 스타일을 Example 17-1에 적용하면 아래와 같은 모습으로 바뀐다.



위에서 적용된 스타일은 컴포넌트 border와 툴바의 폰트가 변경되었다.

HTMLEditor 클래스는 어플리케이션이 시작될 때 편집 영역에 나타날 컨텐츠를 설정하기 위해 setHtmlText 메서드를 제공한다.

Example 17-3 Setting the Text Content



위 예제를 실행하면 아래와 같은 모습이다.



2. Using an HTML Editor to Build the User Interface

HTMLEditor
컨트롤을 이용하여 인스턴트 메신저 서비스, 이메일 클라이언트 심지어는 CMS (content management system) 까지도 구현할 수 있다.

아래 예제는 이메일 클라이언트에서 흔히 볼 수 있는 UI를 구성한 것이다.

Example 17-4 HTMLEditor Added to the Email Client UI





위 예제를 실행한 화면은 아래와 같다.



setPrefWidthsetPrefHeight 메서드를 통해 HTMLEditor의 너비와 높이를 지정할 수 있다. 위 예제에서는 높이만 지정하고 너비는 따로 지정하지 않았다. 이 때 너비는 HTMLEditor의 컨테이너인 VBox 컨테이너에 의해 정해진다. 텍스트 컨텐츠가 정해진 편집 영역의 높이를 넘어가면 수직 스크롤바가 나타날 것이다.


3. Obtaining HTML Content

HTMLEditor
컨트롤의 텍스트를 편집하거나 초기 컨텐츠를 지정하는 것 이외에, 입력된 텍스트를 HTML 형식으로 얻어올 수 있다.

다음 예제는 이러한 작업을 구현한 것이다.

Example 17-5 Retrieving HTML Code



 
 
HTMLEditor 클래스의 getHTMLText 메서드는 현재 입력된 텍스트 컨텐츠를 HTML 문자열 형식으로 반환한다. 위 예제에서는 이러한 HTML 컨텐츠를 별도의 TextArea에 표시해준다.
 




위 예제를 확장하여, HTMLEditor의 컨텐츠를 파일로 저장한 후, 이를 WebView 컨트롤에서 로딩할 수 있다. 아래 예제는 이를 구현한 코드이다.


Example 17-6 Rendering Edited HTML Content in a Browser




위 예제를 실행한 모습은 아래와 같다.