##完成した画面
ComboBoxを開いたときはいい感じにグループっぽく見えて、選択後は左寄せ
##実際のコード
OptGroupComboBox.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>
<?import optGroupComboBox.Java.*?>
<?import optGroupComboBox.Java.Enum.*?>
<AnchorPane style = "-fx-background-color: darkgray" fx:controller="optGroupComboBox.Java.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ComboBox fx:id="optGroupComboBox" layoutX="249.0" layoutY="48.0" prefHeight="25.0" prefWidth="80.0" onAction="#trimLabelPosition" >
<cellFactory>
<ComboBoxCellFactory />
</cellFactory>
<buttonCell>
<ComboBoxCell />
</buttonCell>
<items>
<FXCollections fx:factory="observableArrayList">
<ComboBoxOptions fx:value="GROUP1"/>
<ComboBoxOptions fx:value="A" />
<ComboBoxOptions fx:value="B" />
<ComboBoxOptions fx:value="GROUP2" />
<ComboBoxOptions fx:value="C" />
<ComboBoxOptions fx:value="D" />
</FXCollections>
</items>
</ComboBox>
</children>
</AnchorPane>
今回やりたい事にはあまりかかわりがないのでデザインは適当に
Mainクラス
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
AnchorPane anchorPane = FXMLLoader.load(getClass().getResource("OptGroupComboBox.fxml"));
Scene root = new Scene(anchorPane);
root.getStylesheets().add("sample/css/optGroup.css");
primaryStage.setScene(root);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
よくあるstageの定義とfxml、CSSの読み込みをしてるだけ
Controllerクラス
package optGroupComboBox.Java;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.effect.Effect;
import javafx.util.Callback;
import optGroupComboBox.Java.Enum.ComboBoxOptions;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
private ComboBox<ComboBoxOptions> optGroupComboBox;
@FXML
private void trimLabelPosition(ActionEvent event) {
optGroupComboBox.setId("selected");
}
@Override
public void initialize(URL location, ResourceBundle resources) {
optGroupComboBox.setCellFactory(new Callback<ListView<ComboBoxOptions>, ListCell<ComboBoxOptions>>() {
@Override
public ListCell<ComboBoxOptions> call(ListView<ComboBoxOptions> param) {
return new ListCell<ComboBoxOptions>() {
@Override
protected void updateItem(ComboBoxOptions item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText("");
setGraphic(null);
} else {
setText(item.getLabel());
if (item.isOption().equals("NOT_OPTION")) {
setId("notOption");
setDisable(true);
} else {
setId("option");
}
}
}
};
}
});
}
}
initializeの中でComboBoxに対してカスタムcell?を持ったListCellをsetしている。
Actionevent内では選択肢を押された後に左寄せに直すcssを適用。
ComboBoxOptions
package optGroupComboBox.Java;
public enum ComboBoxOptions {
GROUP1("Group1","NOT_OPTION"),
A("A","OPTION"),
B("B","OPTION"),
GROUP2("Group2","NOT_OPTION"),
C("C","OPTION"),
D("D","OPTION");
private String label;
private String isOption;
ComboBoxOptions(String label, String isOption){
this.label = label;
this.isOption = isOption;
}
public String getLabel(){
return this.label;
}
public String isOption(){
return this.isOption;
}
}
EnumでComboBoxの選択肢を定義。
ここで選択肢としないものはNOT_OPTIONとしておく
optGroup.css
#notOption{
-fx-font-weight: bold;
}
#option{
-fx-padding:0 0 0 15;
}
#selected{
-fx-padding: 0 0 0 -5;
}
ここも単純にJavaFX用のCSSで太字化とpaddingの設定をちょろっと書いただけ
###参考にしたサイト
http://docs.oracle.com/javafx/2/ui_controls/combo-box.htm
http://stackoverflow.com/questions/20283940/javafx-combobox-with-custom-object-displays-object-address-though-custom-cell-fa
一応見た目はいい感じになったのだけれど、OPTIONと定義している選択肢を選んだあとに矢印キーなどで選択し直すとNOT_OPTIONと定義している選択肢が選択されてしまう、、、しかもEnumの列挙型名がそのまま表示される、、、
動きとしてはやっぱりGroup2をスキップしてC,Dが選べたりGroup1には移動せずにAで止まってほしいけどもどう制御すればいいかわからずお手上げ
参考サイトを見ればわかる通り私はそれほど深いところは理解していないのでどなたか解決法をご教示頂けるとすごくうれしいです。
一応Gitにも上げているのでpullRequestもらえたらとってもうれしいです。https://github.com/kurituedia/JavaFXTips