2014년 11월 6일 목요일

JavaFX UI - 23.Pagination Control

Pagination 컨트롤은 작은 조각들로 나뉘어진 여러 컨텐트 페이지들을 돌아다니기 위해 사용된다. 메일박스 안의 이메일 메시지들 또는 검색 결과 조회 등에 주로 사용된다.




1. Creating a Pagination Control



Pagination 컨트롤은 페이지 컨텐트와 페이지 네비게이션 영역으로 구성된다. 페이지 컨텐트 영역에는 어플리케이션 로직에 따라 컨텐트가 디스플레이된다. 페이지 네비게이션 영역은 아래와 같은 모습으로 구성된다.

사용자는 특정 page indicator(지시자)를 클릭하거나, next 또는 previous page 버튼을 클릭하여 페이지들을 조회할 수 있다.

아래 예제는 Pagination 클래스의 세 가지 생성자 상용 예를 보여준다.

Example 23-1 Three Constructors of the Pagination Class




위 예제에서 생성한 pagination3의 모습은 아래와 같다.



페이지의 인덱스는 0부터 시작하므로, 세 번째 페이지를 선택하려면 currentPageIndexProperty를 2로 설정해야 한다.

pagination3에 아직 아무 컨텐트도 추가되지 않았으므로 pagination3 컨트롤의 페이지들는 비어있다.

Pagination 컨트롤에 직접 컨텐트를 추가할 수는 없으며, page factory 메커니즘을 사용하여야 한다. Page factory를 구현함으로써 페이지 컨텐트를 정의하고, 이 factory를 Pagination 클래스의 setPageFactory 메서드를 통해 설정한다.


2. Implementing Page Factories

setPageFactory 메서드는 pagination 컨트롤에 대한 page factory를 정의하기 위해 사용된다. 개발자는 페이지 컨텐트를 만들어내는 Callback 인터페이스를 구현함으로써 factory를 정의한다.

pagination 컨트롤 상의 페이지가 선택되면, 구현한 Callback 인터페이스의 콜백함수(call)가 호출될 것이다. 콜백함수에서는 선택된 페이지의 컨텐트를 로드하여 반환한다. 만약 선택된 페이지 인덱스가 존재하지 않으면 null을 반환해야 한다.

아래 예제는 28개 페이지를 가지는 pagination 컨트롤을 생성하고, 각 페이지 당 8 개의 검색 결과들을 가지도록 구현하였다.

Example 23-2 Adding Hyperlinks to a Pagination Control



Pagination 클래스의 생성자를 통해 전체 페이지 수와 현재 선택된 페이지 인덱스가 설정된다. 먼저 Pagination 객체를 생성하고 나중에 전체 패이지 수와 선택된 페이지 인덱스를 설정할 수도 있다. (setPageCount 메서드, setCurrentPageIndex 메서드 이용)

Pagination 컨트롤의 컨텐트는 createPage 메서드에서 생성하며, 이 메서드는 pagination factory의 콜백함수 내에서 호출된다.

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



현재Pagination 클래스는 추가된 페이지의 수가 10개를 초과하면, 10개씩 끊어서 page indicator를 화면에 보이도록 구현되어 있다. 한번에 보여지는 page indicator 수를 변경하기 위해서는 setMaxPageIndicatorCount 메서드를 사용한다.

아래 예제는 페이지 당 하나의 텍스트 컨텐트를 보여주는 어플리케이션이다. 텍스트 컨텐트는 모두 5개이고 pagination 컨트롤에 선언된 페이지 수는 28개이다.

ArrayIndexOutOfBoundsException이 발생하는 것을 피하기 위하여 페이지 인덱스를 체크하도록 구현하고 있다.

Example 23-3 Adding Text Snippets to a Pagination Control




위 예제를 실행한 어플리케이션의 모습은 아래와 같다.



경우에 따라, 표시해야 할 컨텐트 수 및 pagination 컨트롤이 가져야 할 페이지 수를 정확하게 알 수 없는 상황이 발생한다. 이러한 경우, Pagination 클래스의 생성자 호출 시, 페이지 수를 계산하는 코드를 포함시킬 수 있다. 아래 예제는 시스템 폰트 목록을 얻어 필요한 페이지 수를 계산한다.

Example 23-4 Adding Content of an Undetermined Size




위 예제를 실행한 어플리케이션의 모습은 아래와 같다.




3. Styling a Pagination Control

Pagination 클래스에 선언된 STYLE_CLASS_BULLET는 pagination 컨트롤의 숫자형 page indicator 대신 bullet page indicator를 디스플레이하기 위한 스타일 정의 문자열을 가지고 있다. 이 스타일 정의를 적용함으로써 bullet page indicator를 디스플레이할 수 있다. 뿐만 아니라, caspian style sheet에 정의된 디폴트 pagination 스타일을 수정할 수도 있다.

Example 23-5 Modified Styles of the Pagination Control



아래 예제는 page indicator를 bullet 형태로 바꾸고 위 스타일 정의를 적용하는 소스코드이다.

Example 23-6 Enabling the Modified Pagination Control Style in the PaginationSample Application




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



위에서 적용한 스타일들 외에도, pagination 컨트롤의 모습을 변경하기 위하여 아래와 같은 스타일 항목을 편집할 수 있다.
  • -fx-max-page-indicator-count : 한번에 보여질 수 있는 page indicator의 최대 개수
  • -fx-arrows-visible : Next 및 Previous 버튼의 visibility 속성 (default : true)
  • -fx-tooltip-visible : page indicator 툴팁의 visibility 속성 (default : true)
  • -fx-page-information-visible : page information의 visibility 속성 (default : true)
  • -fx-page-information-alignment : page information의 정렬 설정

2014년 10월 26일 일요일

JavaFX UI - 22.Color Picker

 

Color picker 컨트롤은 사용자가 색상을 선택할 수 있도록 해주는 UI 컴포넌트이다. 색상을 선택할 때는 미리 정의된 색상 중 선택하는 방법과 RGB나 HSB 조합을 통해 색상을 지정할 수도 있다.

1. Design Overview

ColorPicker 컨트롤은 color chooser, color palette 그리고 custom color dialog로 이루어져 있다. 다음 그림은 이들 각 요소들을 보여준다.




2. Color Chooser

Color chooser는 현재 설정된 색상과 그에 대한 라벨을 표시하는 콤보박스이다.
Color picker 컨트롤은 아래와 같은 세 가지 모양의 color chooser를 지원한다.



3. Color Palette

Color palette는 미리 정의된 색상들의 집합을 가지고 있으며, ‘Custom Color dialog 창’을 열기 위한 ‘Custom Color’ 링크를 가지고 있다.

Color palette의 초기 모습은 아래와 같다.



만약 미리 정의된 사용자 정의 컬러가 있다면, 아래 그림과 같이 ‘Custom Colors’ 영역에 그 컬러가 보여진다.



Color palette는 up, down, left, right 키를 사용한 선택 이동이 가능하다.

사용자 정의 컬러 집합은 어플리케이션이 재시작될 때 복구되지는 않는다.


4. Custom Color Dialog window

Custom Color 다이얼로그 창은 Color Palette 상의 ‘Custom Color’ 링크를 클릭했을 때 열리는 modal 윈도우이다. 사용자는 Color 영역이나 수직 Color Bar를 마우스로 드래그하여 색상을 지정할 수 있다.



색상을 지정하는 또 다른 방법은 HSB (Hue Saturation Brightness) 또는 RGB (Red Green Blue) 값을 설정하거나, web color 값을 직접 입력하는 것이다. 아래 화면은 사용자 정의 컬러 세팅을 위한 세 가지 pane들이다.



사용자는 ‘Custom Color Dialog’ 상의 Opacity 슬라이더를 조정하거나 0에서 100 사이의 값을 직접 입력함으로써, 투명도를 설정할 수 있다.


5. Using a Color Picker

Color picker는 어플리케이션 scene 또는 레이아웃 컨테이너에 직접 추가되거나, 어플리케이션 툴바에 추가될 수 있다.

Example 22-1 Creating a Color Picker Control 



다음은 ColorPicker를 실제로 테스트해보기 위한 샘플 소스코드이다.

Example 22-2 Using the ColorPicker Control to Alter the Color of the Text Component



위 예제는 color picker를 생성하고 이를 통해 컬러가 변경될 때의 액션을 정의하고 있다. 컬러가 선택되면 Text 컨트롤의 컨텐트 색상이 선택된 색상으로 변경된다.

아래 화면은 새로 선택된 색상이 Text 컨트롤에 적용되는 모습이다.



유사하게, 선택된 색상을 graphic Node에 적용할 수 있다. 아래 예제는 T셔츠를 디자인하기 위해 color picker를 사용하는 코드이다.

Example 22-3 Using ColorPicker to Alter the Color of a Graphical Object




Color picker를 가지고 작업할 때, getCustomColors 메서드를 이용하여 생성되어 있는 사용자 정의 컬러들을 ObservableList 형태로 얻어 올 수 있다. 그러나 어플리케이션이 시작될 때 임의의 사용자 지정 컬러들을 color picker에 등록할 수는 없다.

Example 22-4 Obtaining the Custom Colors




6. Changing the Appearance of a Color Picker

Color picker의 디폴트 모습은 com.sun.javafx.scene.control.skin.ColorPickerSkin 클래스에 의해 정의되어 있다. Color picker에 다른 skin을 적용하려면, 아래 예제처럼 CSS 스타일 파일 상에서 color-picker 클래스의 ?fx-skin 프로퍼티를 재정의한다.

Example22-5 Setting an Alternative Skin for a Color Picker




다음 예제는 Color picker의 모습을 변경하기 위하여 split-button CSS 클래스와 arrow-button CSS 클래스를 사용한다.

 Example 22-6 Setting Appearance for a Color Picker


caspian.css 파일에 정의된 다양한 CSS 클래스들을 통해, color picker의 디폴트 스타일을 변경할 수 있다. 이 파일은 JavaFX SDK가 설치된 디렉토리 아래의 rt/lib 디렉토리에 있는 jfxrt.jar 파일에 묶여 있다.

이를 풀기 위하여 다음과 같은 명령을 실행한다.

jar -xf jfxrt.jar com/sun/javafx/scene/control/skin/caspian/caspian.css


다음 예제는 color picker의 배경색과 라벨의 기본 스타일을 변경한다.

Example 22-7 Modifying the Default Appearance of a Color Picker



위와 같은 스타일 정의를 ControlStyle.css 라는 파일에 저장한 후, 이를 어플리케이션에 적용하기 위해서는 다음과 같은 코드를 사용한다.

scene.getStylesheets().add("colorpickersample/ControlStyle.css");

ColorPickerSample 예제에 위와 같이 스타일을 변경하는 코드를 반영한 후, 실행하면 color picker의 모습이 아래 화면과 같이 변한다.



ColorPicker 클래스는 ComboBoxBaxe 클래스를 상속하여 CSS 속성까지도 동일하게 가진다. Combo box와 Color picker의 모습을 통일시키기 위하여 combo-box-baxe CSS 스타일을 아래와 같이 새롭게 정의할 수 있다.

Example 22-8 Setting the Combo-Box-Base Styles



ColorPickerSmaple 어플리케이션에 위 예제 스타일을 적용하면 아래 모습과 같다.


JavaFX UI - 21.Password Field


PasswordField 클래스는 특화된 text field의 한 종류로서 사용자가 입력한 문자들을 숨기기 위해 echo character를 출력한다. 아래 그림은 prompt message를 가진 password field의 모습이다.



1. Creating a Password Field

아래 코드 예제와 같이 PasswordField를 생성할 수 있다.

Example 21-1 Creating a Password Field 



TextField 클래스와 마찬가지로 PasswordField 클래스도 setText 메서드를 제공하여 초기에 입력될 텍스트 문자열을 지정할 수 있다. 그러나 지정된 텍스트가 화면에는 echo character들로 보여진다. 디폴트 echo character는 asterisk(*) 이다.



Password field에 입력된 값은 getText 메서드를 통해 얻을 수 있다.


2. Evaluating the Password

아래 예제는 password field를 사용하는 일반적인 사용 예시이다.

Example 21-2 Implementing the Authentication Logic



Password field에 대한 인증 로직은 setOnAction 메서드에 의해 정의되었다. 만약 입력된 값이 정해진 암호와 일치하지 않으면 아래와 같이 경고 메시지가 보여진다.



입력된 값이 정해진 암호와 일치하면 아래와 같은 확인 메시지가 보여진다.



보안을 위해, 입력된 값이 사용된 후에는 password field를 비우는 것이 좋다.


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를 지정할 수도 있다.