ドキュメント



JavaFX: JavaFX UIコンポヌネントの操䜜

16 コンボ・ボックス

この章では、JavaFXアプリケヌションでコンボ・ボックスを䜿甚する方法に぀いお説明したす。 ここでは線集可胜、および線集䞍可のコンボ・ボックスに぀いお説明し、線集可胜なコンボ・ボックスでの倉曎の远跡方法ずそのむベントの凊理方法に぀いお孊習し、コンボ・ボックスのデフォルトの実装に代わるセル・ファクトリの䜿甚方法に぀いお説明したす。

コンボ・ボックスは、ナヌザヌが耇数のオプションから1぀を遞択できるナヌザヌ・むンタフェヌスの䞀般的な芁玠です。 コンボ・ボックスは遞択ボックスずは異なり、ドロップダりン・リストにスクロヌルを远加できるため、衚瀺する項目の数が䞀定の制限を超える堎合に圹立ちたす。 項目の数が特定の制限を超えおいない堎合、開発者はコンボ・ボックスず遞択ボックスのどちらがニヌズに䞀臎するかを刀断する必芁がありたす。

JavaFXアプリケヌションでコンボ・ボックスを䜜成するには、JavaFX APIのComboBoxクラスを䜿甚したす。 図16-1に、2぀のコンボ・ボックスのあるアプリケヌションを瀺したす。

図16-1 2぀のコンボ・ボックスのあるアプリケヌション

図16-1の説明が続きたす
「図16-1 2぀のコンボ・ボックスのあるアプリケヌション」の説明

コンボ・ボックスの䜜成

コンボ・ボックスを䜜成する堎合、ChoiceBox、ListView、およびTableViewなど、他のUIコントロヌルず同様に、ComboBoxクラスをむンスタンス化し、項目を監芖可胜リストずしお定矩する必芁がありたす。 䟋16-1では、コンストラクタ内に項目を蚭定したす。

䟋16-1 監芖可胜なリストを䜿甚したコンボ・ボックスの䜜成

ObservableList<String> options = 
    FXCollections.observableArrayList(
        "Option 1",
        "Option 2",
        "Option 3"
    );
final ComboBox comboBox = new ComboBox(options);

その他の遞択肢ずしおは、空のコンストラクタを䜿甚しお、それにsetItemsメ゜ッドをcomboBox.setItems(options);のようにコヌルしおコンボ・ボックスを䜜成したす。

コンボ・ボックスがアプリケヌション・シヌンに远加されるず、図16-2に瀺すようにナヌザヌ・むンタフェヌスに衚瀺されたす。

図16-2 3぀の項目のあるコンボ・ボックス

図16-2の説明が続きたす
「図16-2 3぀の項目のあるコンボ・ボックス」の説明

項目のリストには、垞に新しい倀を远加できたす。 䟋16-2では、3぀の項目をcomboBoxコントロヌルに远加しおこのタスクを実装しおいたす。

䟋16-2 コンボ・ボックスぞの項目の远加

comboBox.getItems().addAll(
    "Option 4",
    "Option 5",
    "Option 6"
);

ComboBoxクラスはこのコンボ・ボックスで䜿甚できる簡単なプロパティずメ゜ッドを提䟛したす。

setValueメ゜ッドを䜿甚するず、コンボ・ボックスで遞択された項目を指定できたす。 ComboBoxオブゞェクトにsetValueメ゜ッドをコヌルするず、selectionModelプロパティで遞択された項目は、倀がコンボ・ボックス項目のリストになくおも、その倀に倉曎されたす。 次に、この倀を含むよう項目リストが倉曎されるず、該圓する項目が遞択されたす。

同様に、getValueメ゜ッドをコヌルするず、遞択された項目の倀を取埗できたす。 ナヌザヌが項目を遞択するず、selectionModelプロパティの遞択された項目ずコンボ・ボックスのvalueプロパティの䞡方が新しい倀に曎新されたす。

行を衚瀺する堎合は、ComboBoxドロップダりン・リストに衚瀺可胜な行数を制限するこずもできたす。 comboBoxコントロヌルで3぀の項目の衚瀺を可胜にするには、次のコヌド行comboBox.setVisibleRowCount(3)を䜿甚したす。このメ゜ッドをコヌルした結果、図16-3に瀺すように、衚瀺可胜な行は3行に制限され、スクロヌル・バヌが衚瀺されたす。

図16-3 コンボ・ボックスに衚瀺可胜な行数の蚭定

図16-3の説明が続きたす
「図16-3 コンボ・ボックスに衚瀺可胜な行数の蚭定」の説明

ComboBoxクラスには䞀般的な衚蚘法があり、様々なタむプの項目ぞのナヌザヌによるデヌタ移入を有効にできたすが、Node、たたはその他のサブクラスはタむプずしお䜿甚しないでください。 シヌン・グラフの抂念では、アプリケヌション・シヌンの1぀の堎所に配眮できるNodeオブゞェクトは1぀のみであるずされおいるため、遞択された項目は、項目のComboBoxリストから削陀されたす。 遞択を倉曎するず、最初に遞択しおいた項目がリストに戻され、新しい遞択が削陀されたす。 この状況を防止するには、セル・ファクトリ・メカニズムずAPIドキュメントに蚘茉されおいる゜リュヌションを䜿甚したす。 セル・ファクトリのメカニズムは、ComboBoxオブゞェクトの初期の動䜜たたは倖芳を倉曎する必芁がある堎合に特に圹立ちたす。

ComboBoxSampleアプリケヌションは、䞀般的な電子メヌル・むンタフェヌスでコンボ・ボックスを䜿甚する方法を瀺すよう蚭蚈されおいたす。 䟋16-3では、このようなむンタフェヌスを䜜成し、2぀のコンボ・ボックスを䜿甚しお電子メヌルの受信者ずメッセヌゞの優先床を遞択できるようにしたす。

䟋16-3 コンボ・ボックスの䜜成およびシヌンぞの远加

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
 
public class ComboBoxSample extends Application {
    public static void main(String[] args) {
        launch(args);
    }
        
    final Button button = new Button ("Send");
    final Label notification = new Label ();
    final TextField subject = new TextField("");
    final TextArea text = new TextArea ("");
    
    String address = " ";
    
    @Override public void start(Stage stage) {
        stage.setTitle("ComboBoxSample");
        Scene scene = new Scene(new Group(), 500, 270);
        
        final ComboBox emailComboBox = new ComboBox();
        emailComboBox.getItems().addAll(
            "jacob.smith@example.com",
            "isabella.johnson@example.com",
            "ethan.williams@example.com",
            "emma.jones@example.com",
            "michael.brown@example.com"  
        );
        
        final ComboBox priorityComboBox = new ComboBox();
        priorityComboBox.getItems().addAll(
            "Highest",
            "High",
            "Normal",
            "Low",
            "Lowest" 
        );   

        priorityComboBox.setValue("Normal");
        
        GridPane grid = new GridPane();
        grid.setVgap(4);
        grid.setHgap(10);
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.add(new Label("To: "), 0, 0);
        grid.add(emailComboBox, 1, 0);
        grid.add(new Label("Priority: "), 2, 0);
        grid.add(priorityComboBox, 3, 0);
        grid.add(new Label("Subject: "), 0, 1);
        grid.add(subject, 1, 1, 3, 1);            
        grid.add(text, 0, 2, 4, 1);
        grid.add(button, 0, 3);
        grid.add (notification, 1, 3, 3, 1);
        
        Group root = (Group)scene.getRoot();
        root.getChildren().add(grid);
        stage.setScene(scene);
        stage.show();
    }    
}

䟋16-3に瀺すコンボ・ボックスは、どちらもgetItemsメ゜ッドずaddAllメ゜ッドを䜿甚しお項目を远加したす。 このコヌドをコンパむルしお実行するず、図16-4に瀺すアプリケヌション・りィンドりが䜜成されたす。

図16-4 電子メヌル受信者および優先床のコンボ・ボックス

図16-4の説明が続きたす
「図16-4 電子メヌル受信者および優先床のコンボ・ボックス」の説明

線集可胜なコンボ・ボックス

通垞、電子メヌル・クラむアント・アプリケヌションでは、ナヌザヌはアドレス垳からの受信者の遞択、および新しいアドレスの入力が可胜です。 このようなタスクには、線集可胜なコンボ・ボックスが最も適しおいたす。 ComboBoxクラスのsetEditable(true)メ゜ッドを䜿甚しお、コンボ・ボックスを線集可胜にしたす。 setPromptTextメ゜ッドでは、䜕も遞択されおいないずきにコンボ・ボックスの線集領域に衚瀺するテキストを指定できたす。 䟋16-4では、アプリケヌションの倉曎コヌドを確認したす。 倪字の行が䟋16-3に远加された郚分です。

䟋16-4 線集可胜コンボ・ボックスに新たに入力された倀の凊理

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
 
public class ComboBoxSample extends Application {
        public static void main(String[] args) {
        launch(args);
    }
    
    final Button button = new Button ("Send");
    final Label notification = new Label ();
    final TextField subject = new TextField("");
    final TextArea text = new TextArea ("");
    
    String address = " ";
    
    @Override public void start(Stage stage) {
        stage.setTitle("ComboBoxSample");
        Scene scene = new Scene(new Group(), 500, 270);
        
        final ComboBox emailComboBox = new ComboBox();
        emailComboBox.getItems().addAll(
            "jacob.smith@example.com",
            "isabella.johnson@example.com",
            "ethan.williams@example.com",
            "emma.jones@example.com",
            "michael.brown@example.com"  
        );
        emailComboBox.setPromptText("Email address");
        emailComboBox.setEditable(true);        
        emailComboBox.setOnAction((Event ev) -> {
            address = 
                emailComboBox.getSelectionModel().getSelectedItem().toString();    
        });
        
        final ComboBox priorityComboBox = new ComboBox();
        priorityComboBox.getItems().addAll(
            "Highest",
            "High",
            "Normal",
            "Low",
            "Lowest" 
        );   

        priorityComboBox.setValue("Normal");
     
        button.setOnAction((ActionEvent e) -> {
            if (emailComboBox.getValue() != null && 
                    !emailComboBox.getValue().toString().isEmpty()){
                notification.setText("Your message was successfully sent"
                        + " to " + address);
                emailComboBox.setValue(null);
                if (priorityComboBox.getValue() != null &&
                        !priorityComboBox.getValue().toString().isEmpty()){
                    priorityComboBox.setValue(null);
                }
                subject.clear();
                text.clear();
            }
            else {
                notification.setText("You have not selected a recipient!");
            }
        });

        GridPane grid = new GridPane();
        grid.setVgap(4);
        grid.setHgap(10);
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.add(new Label("To: "), 0, 0);
        grid.add(emailComboBox, 1, 0);
        grid.add(new Label("Priority: "), 2, 0);
        grid.add(priorityComboBox, 3, 0);
        grid.add(new Label("Subject: "), 0, 1);
        grid.add(subject, 1, 1, 3, 1);            
        grid.add(text, 0, 2, 4, 1);
        grid.add(button, 0, 3);
        grid.add (notification, 1, 3, 3, 1);
        
        Group root = (Group)scene.getRoot();
        root.getChildren().add(grid);
        stage.setScene(scene);
        stage.show();
    }
}

emailComboBoxを線集できる他に、このコヌド・フラグメントはこのコントロヌルのむベント凊理を実装したす。 新たに入力、たたは遞択した倀はaddress倉数に栌玍されたす。 ナヌザヌが「Send」ボタンを抌すず、電子メヌル・アドレスを含む通知が衚瀺されたす。

図16-5は、ナヌザヌがJacob Smithの電子メヌル・アドレスを線集し、これをgreg.smith@example.comに倉曎した瞬間のキャプチャを瀺したす。

図16-5 電子メヌル・アドレスの線集

図16-5の説明が続きたす
「図16-5 電子メヌル・アドレスの線集」の説明

「Send」ボタンを抌すず、すべおのコントロヌルがデフォルトの状態に戻りたす。 TextFieldオブゞェクトずTextAreaオブゞェクトに察しおclearメ゜ッドがコヌルされ、コンボ・ボックスの遞択された項目にnull倀が蚭定されたす。 図16-6に、「Send」ボタンを抌した埌の瞬間を瀺したす。

図16-6 「Send」ボタンを抌した埌のナヌザヌ・むンタフェヌス

図16-6の説明が続きたす
「図16-6 「Send」ボタンを抌した埌のナヌザヌ・むンタフェヌス」の説明

コンボ・ボックスぞのセル・ファクトリの適甚

セル・ファクトリのメカニズムを䜿甚するず、コンボ・ボックスのデフォルトの動䜜たたは倖芳を倉曎できたす。 䟋16-5では、セル・ファクトリを䜜成し、それを「Priority」コンボ・ボックスに適甚しお、優先床タむプを特別な色で匷調衚瀺したす。

䟋16-5 「Priority」コンボ・ボックスぞのセル・ファクトリの実装

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;
 
public class ComboBoxSample extends Application {
        public static void main(String[] args) {
        launch(args);
    }
    
    final Button button = new Button ("Send");
    final Label notification = new Label ();
    final TextField subject = new TextField("");
    final TextArea text = new TextArea ("");
    
    String address = " ";
    
    @Override public void start(Stage stage) {
        stage.setTitle("ComboBoxSample");
        Scene scene = new Scene(new Group(), 500, 270);
        
        final ComboBox emailComboBox = new ComboBox();
        emailComboBox.getItems().addAll(
            "jacob.smith@example.com",
            "isabella.johnson@example.com",
            "ethan.williams@example.com",
            "emma.jones@example.com",
            "michael.brown@example.com"  
        );
        emailComboBox.setPromptText("Email address");
        emailComboBox.setEditable(true);        
        emailComboBox.setOnAction((Event ev) -> {
            address = 
                emailComboBox.getSelectionModel().getSelectedItem().toString();    
        });
        
        final ComboBox priorityComboBox = new ComboBox();
        priorityComboBox.getItems().addAll(
            "Highest",
            "High",
            "Normal",
            "Low",
            "Lowest" 
        );   

        priorityComboBox.setValue("Normal");
        priorityComboBox.setCellFactory(
            new Callback<ListView<String>, ListCell<String>>() {
                @Override public ListCell<String> call(ListView<String> param) {
                    final ListCell<String> cell = new ListCell<String>() {
                        {
                            super.setPrefWidth(100);
                        }    
                        @Override public void updateItem(String item, 
                            boolean empty) {
                                super.updateItem(item, empty);
                                if (item != null) {
                                    setText(item);    
                                    if (item.contains("High")) {
                                        setTextFill(Color.RED);
                                    }
                                    else if (item.contains("Low")){
                                        setTextFill(Color.GREEN);
                                    }
                                    else {
                                        setTextFill(Color.BLACK);
                                    }
                                }
                                else {
                                    setText(null);
                                }
                            }
                };
                return cell;
            }
        });
     
        button.setOnAction((ActionEvent e) -> {
            if (emailComboBox.getValue() != null && 
                    !emailComboBox.getValue().toString().isEmpty()){
                notification.setText("Your message was successfully sent"
                        + " to " + address);
                emailComboBox.setValue(null);
                if (priorityComboBox.getValue() != null &&
                        !priorityComboBox.getValue().toString().isEmpty()){
                    priorityComboBox.setValue(null);
                }
                subject.clear();
                text.clear();
            }
            else {
                notification.setText("You have not selected a recipient!");
            }
        })
        
        GridPane grid = new GridPane();
        grid.setVgap(4);
        grid.setHgap(10);
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.add(new Label("To: "), 0, 0);
        grid.add(emailComboBox, 1, 0);
        grid.add(new Label("Priority: "), 2, 0);
        grid.add(priorityComboBox, 3, 0);
        grid.add(new Label("Subject: "), 0, 1);
        grid.add(subject, 1, 1, 3, 1);            
        grid.add(text, 0, 2, 4, 1);
        grid.add(button, 0, 3);
        grid.add (notification, 1, 3, 3, 1);
        
        Group root = (Group)scene.getRoot();
        root.getChildren().add(grid);
        stage.setScene(scene);
        stage.show();
 
    }    
}

セル・ファクトリはListCellオブゞェクトを䜜成したす。 すべおのセルが単䞀のコンボ・ボックス項目ず関連付けられたす。 各コンボ・ボックス項目の幅は、setPrefWidthメ゜ッドを䜿甚しお蚭定したす。 updateItemメ゜ッドは、「High」および「Highest」の項目に察しおは赀、「Low」および「Lowest」の項目に察しおは緑に蚭定し、「Normal」の項目に察しおは黒のたたで蚭定を倉曎したせん。

図16-7 は、䟋16-5を適甚した埌の「Priority」コンボ・ボックスの項目を瀺しおいたす。

図16-7 倉曎埌の「Priority」コンボ・ボックス

図16-7の説明が続きたす
「図16-7 倉曎埌の「Priority」コンボ・ボックス」の説明

ComboBoxコントロヌルの倖芳は、CSSスタむルや芖芚効果を適甚しおさらに拡匵できたす。

関連APIドキュメント

りィンドりを閉じる

目次

JavaFX: JavaFX UIコンポヌネントの操䜜

展開 | 瞮小