Table 생성을 위해 가장 중요한 클래스들은 TableView, TableColumn, TableCell 이다. Table에 데이터를 채우기 위해서는 data model을 구현하고 cell factory를 구현해야 한다.
Table 클래스들은 컬럼 데이터를 정렬하거나 필요시 컬럼 크기를 재조정하는 built-in 기능들을 제공한다.
아래 화면은 e-mail 주소 정보를 담고 있는 전형적인 table 형태를 보여준다.
1. Creating a Table
아래 예제는 세 개의 컬럼을 가지는 빈 테이블을 생성한다.
Example 11-1 Adding a Table
위 예제를 실행한 결과 화면은 아래와 같다.
setVisible 메서드를 통해 컬럼의 visibility를 조정할 수 있다.
표현하고자 하는 데이터 구조가 복잡한 경우, nested column을 구성할 수 있다. 예를 들어 두 개의 e-mail 계정을 포함하는 컬럼을 만들고 싶은 경우, 두 개의 서브 컬럼을 만든 후 다른 메인 컬럼에 추가할 수 있다.
Example 11-2 Creating Nested Columns
위의 코드라인을 Example 11-1에 추가하면, 다음과 같은 결과를 확인할 수 있다.
위 화면에서 table에 데이터가 정의되지 않았기 때문에 “No content in table”이라는 표준 메시지가 보여진다. 이 때, setPlaceholder 라는 메서드를 통해 이 표준 메시지 대신 보여줄 다른 Node 객체를 지정할 수 있다.
2. Defining the Data Model
JavaFX 어플리케이션에서 table을 생성할 때, data model을 정의하는 클래스를 구현하는 것이 좋다. 아래 예제에서는 Person이라는 data model 클래스를 생성한다.
Example 11-3 Creating the Person Class
firstName, lastName, email 이라는 string property들을 생성하고 이들 각각에 대한 get, set 메서드를 제공한다.
Person 클래스를 통해 data model이 정의되었다면, ObservableList를 생성하여 table에 넣을 레코드들을 정의할 수 있다. 아래 예제는 이 과정을 보여준다.
Example 11-4 Defining Table Data in an Observable List
다음은 위에서 정의한 데이터와 table column들을 서로 연결시켜주어야 한다.
Example 11-5 Setting Data Properties to Columns
setCellValueFactory 메서드는 각 컬럼에 대해 값을 얻을 수 있는 Callback 인터페이스를 등록한다. 예제에서 나오는 PropertyValueFactory 클래스는 Callback 인터페이스를 구현하고 있으며 각 컬럼에 대한 cell value factory로 사용되고 있다. PropertyValueFactory의 생성자에는 컬럼명이 파라미터로 주어지는데, call 메서드가 호출되면 이 컬럼명에 해당하는 컬럼 값을 반환한다.
Data model에 기반하는 데이터들이 만들어지고, data model과 table의 컬럼 간의 관계가 정의되면, TableView 클래스의 setITems 메서드를 사용하여 준비된 데이터를 테이블에 추가할 수 있다.
TableView에 추가되는 데이터들은 ObservableList를 통해 관리되는데, ObservableList 내의 엘리먼트들에 변경이 발생하게되면 TableView의 내용이 자동으로 갱신된다.
Example 11-6 Creating a Table and Adding Data to It
위 예제를 실행한 결과 화면은 아래와 같다.
3. Adding New Rows
이전 예시 화면에 나오는 테이블은 다섯 개의 row들을 포함하고 있다.
이 테이블 상의 각 컬럼들에 대하여 새로운 값을 입력하기 위해 text field를 사용할 수 있다. TextField 컨트롤은 사용자로부터 텍스트 값을 입력 받을 수 있도록 해준다. 아래 코드는 각 컬럼에 대한 텍스트 값을 입력받기 위한 세 개의 text field를 생성하였고, 데이터를 추가할 수 있는 버튼을 생성하였다.
Example 11-7 Using Text Fields to Enter New Items in the Table
아래 예제는 테이블에 레코드를 추가할 수 있는 전체 코드이다.
Example 11-8 Table with the Text Fields to Enter New Items
위 예제를 실행하면 아래와 같은 화면을 볼 수 있다.
4. Sorting Data in Columns
TableView 클래스는 컬럼 데이터를 정렬할 수 있는 built-in 기능을 제공한다. 사용자가 테이블 상의 컬럼 헤더를 클릭하면 해당 컬럼 값을 기준으로 레코드가 정렬된다. 첫 번째 클릭은 오름차순으로, 두 번째 클릭은 내림차순으로 정렬이 이루어지고 세 번째 클릭은 정렬 옵션이 제거된다. 초기 디폴트로는 어떠한 정렬도 적용되지 않는다.
사용자는 테이블 내의 여러 컬럼들에 대해 정렬할 수 있다. 이 때 각 컬럼들에 대한 정렬 우선순위가 주어져야 한다. 여러 컬럼들에 대해 정렬하기 위해서는 shift 키를 누른 상태에서 정렬하고자 하는 순서대로 컬럼의 헤더를 클릭한다.
아래 화면은 first name에 대해 오름차순으로, last name에 대해 내림차순으로 정렬한 테이블 모습이다.
개발자들이 TableColumn 클래스의 setSortType 메서드를 통해 어플리케이션 코드 내에서 컬럼의 정렬을 정의할 수도 있다. 예를 들면 다음과 같은 코드 라인을 통해 emailCol 컬럼을 내림차순으로 정렬할 수 있다.
emailCol.setSortType(TableColumn.SortType.DESCENDING);
컬럼 기반 정렬을 하기 위한 또 다른 방법은 TableView 객체에 정의된 sortOrder라는 observable list에 TableColumn 인스턴스를 추가하거나 제거하는 것이다. 이 list에 들어있는 컬럼의 순서가 정렬 우선순위가 된다.
정렬을 막기 위해서는 TableColumn 클래스의 setSortable(false) 메서드를 호출하면 된다.
5. Editing Data in the Table
TableView 클래스는 테이블 형식의 데이터를 화면에 표현할 뿐만 아니라, 편집할 수 있는 기능도 제공한다. 테이블 컨텐츠를 편집하기 위해서는 setEditable 메서드를 사용한다.
TableColumn의 setCellFactory 메서드는 그 컬럼에 해당하는 테이블 셀을 제공해 줄 cell factory (실제로는 Callback 인터페이스 구현체)를 지정한다. 아래 예제에서는 셀의 편집을 위해 TextField가 테이블 셀로 사용되도록 구현하였다. setOnEditCommit 메서드는 편집 완료에 대한 이벤트 핸들러를 등록하기 위해 사용되며, 편집을 처리하고 변경된 값을 해당 테이블 셀에 반영하는 작업이 이 이벤트 핸들러에서 이루어진다.
Example 11-9 Implementing Cell Editing
어플리케이션의 완벽한 코드는 아래와 같다.
Example 11-10 TableViewSample with Enabled Cell Editing
아래 화면은 위 예제를 실행시켰을 때의 모습을 보여준다. 테이블 셀을 편집하기 위해서는 셀 안에 새로운 값을 입력하고 엔터 키를 누른다. 엔터 키가 눌리기 전까지는 셀이 편집되지 않는다.
TextField 컨트롤의 기본 구현에서는 편집이 완료되기 위해 사용자가 반드시 엔터 키를 눌러야한다. 그러나 focus의 이동 시에 편집이 완료되도록 하기 위해 TextField를 재정의할 수 있다.
Example 11-11 Alternative Solution Of Cell Editing
6. Adding Maps of Data to the Table
JavaFX SDK 2.2부터, Map 데이터가 테이블에 추가될 수 있으며, MapValueFactory 클래스를 통해 Map 데이터를 테이블에 표출할 수 있다.
Example 11-12 Adding Map Data to the Table
MapValueFactory 클래스는 Callback 인터페이스를 구현한 것으로, setCellValueFactory 메서드를 통해 TableColumn 인스턴스에 할당되어 그 컬럼에 해당하는 셀의 값을 결정하기 위해 사용된다.
generateDataInMap 메서드에서의 dataRow hash map은 하나의 레코드를 의미하는데, 이 map은 두 개의 string 키(Column1MapKey, Column2MapKey)를 사용하여 두 컬럼 값을 저장한다. 즉, TableView에 추가되는 데이터는 Map 객체들의 리스트이며, 각 Map 객체는 하나의 레코드를 나타내며 키 값을 통해 구분되는 컬럼 값들을 포함하고 있다. MapValueFactory 클래스는 Map 객체로부터 특정 컬럼의 값을 얻어 반환하는 Callable 구현체이다.
위 예제를 실행하면 아래와 같은 결과 화면을 볼 수 있다.
댓글 없음:
댓글 쓰기