JavaFX | 속성 이벤트 처리 | ComboBox의 SelectionModel 이벤트 처리

계속해서 ComboBox에 대해 설명하겠다. 이것은 사실은 ListView 알면 거의 같은 방식으로 처리 할 수 있다.

ComboBox에도 선택 상태를 관리하는 모델 클래스가 설정된 속성이 있는데 이는 “getSelectionModel"으로 선택 모델 클래스를 얻을 수 있다.

그리고 그 selectedItemProperty에서 얻을 수 있는 속성에 addListener으로 이벤트 리스너를 설정하여 선택 변경시의 처리를 설정 할 수 있다.

그럼 이것도 살펴 보도록 하자. 이전에 FXML에 있던 <center> 태그 안에서 다음과 같이 작성한다.

<ComboBox fx:id="combo1">
<items>
    <FXCollections fx:factory="observableArrayList">
        <String fx:value="One" />
        <String fx:value="Two" />
        <String fx:value="Three" />
    </FXCollections>
</items>
</ComboBox>

이것으로 String 값을 항목으로 설정한 ComboBox가 준비되었다. 다음에는 이 이벤트 처리를 컨트롤러 클래스에서 제공하는 뿐이다.

아래와 같이 소스 코드를 작성해 보자.

package com.devkuma.javafx;
 
import java.net.URL;
import java.util.ResourceBundle;
 
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
 
 
public class AppController implements Initializable {
    @FXML Label label1;
    @FXML ComboBox<String> combo1;
     
    @Override
    public void initialize(URL location, ResourceBundle resources) {
 
        combo1.getSelectionModel().selectedItemProperty().
            addListener((ObservableValue<? extends String> observ,
                    String oldVal, String newVal)->{
            label1.setText(oldVal + "->" + newVal);
        });
    }
}

여기에서는 ComboBox에 제네릭 형으로 String를 지정하고 있다. 아래와 같은 형식이다.

@FXML ComboBox<String> combo1;

이것으로 String 값을 항목으로 가진 설정이 된다. 이벤트 리스너는 다음과 같이 설정한다.

combo1.getSelectionModel().selectedItemProperty().addListener ......

getSelectionModel에서 얻어진 선택 모델 selectedItemProperty에 addListener을 설정한다. 조금 까다롭다. 이벤트 리스너 설정은 다음과 같은 형태로 정의된다.

addListener((ObservableValue<? extends String> observ, String oldVal, String newVal) -> {
    // 이벤트 처리
});

첫번째 인수 ObservableValue<? extends String> observ이라는 형태로 정의되어 있다. ComboBox의 정의도 <String>가 지정되어 있기 때문에, ObservableValue도 extends String 클래스로 정의된다. 다음에는 변경 전과 변경 후의 값이 각각 String으로 전달된다.

이 “ObservableValue는 거기에 저장된 값을 extends하는 형태로 작성된다"는 것은 정말 이상한 형태일 것이다. 어쨌든, 실제로 프로그램을 작성한 ObservableValue 슈퍼 클래스가 어떤 결정 때문이다. 조금 이해하기 어렵겠지만, “선택 모델에 설정된 클래스를 상속해서 ObservableValue은 준비된다"는 것을 명심하자.