21

JavaFX 2 の学習を始めたばかりです。
現在、サンプル アプリケーションを構築しようとしています。それから私はコンボボックスで立ち往生しました。
JavaFX のコンボボックスのキーと値のペアへの参照が見つかりませんでした。http://docs.oracle.com/javafx/2/api/index.html
にあるコンボボックスの javadoc には、キーと値のペアについて多くの説明がありません。

表示値と実際の値が異なるアイテムを持つコンボボックスを作成するにはどうすればよいですか?

4

3 に答える 3

24

2 つの方法があります。 1.データモデル クラスでメソッドを
オーバーライドするだけです。toString()例:

public class Demo extends Application {

    private final ObservableList<Employee> data =
            FXCollections.observableArrayList(
            new Employee("Azamat", 2200.15),
            new Employee("Veli", 1400.0),
            new Employee("Nurbek", 900.5));

    @Override
    public void start(Stage primaryStage) {

        ComboBox<Employee> combobox = new ComboBox<>(data);
        combobox.getSelectionModel().selectFirst(); // Select first as default
        combobox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Employee>() {

            @Override
            public void changed(ObservableValue<? extends Employee> arg0, Employee arg1, Employee arg2) {
                if (arg2 != null) {
                    System.out.println("Selected employee: " + arg2.getName());
                }
            }
        });
        StackPane root = new StackPane();
        root.getChildren().add(combobox);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    public static class Employee {
        private String name;
        private Double salary;

        @Override
        public String toString() {
            return name + " (sal:" + salary + ")";
        }

        public Employee(String name, Double salary) {
            this.name = name;
            this.salary = salary;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Double getSalary() {
            return salary;
        }

        public void setSalary(Double salary) {
            this.salary = salary;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Employee クラスのオーバーライドされた toString() に注意してください。この場合、コンボボックスのキー (実際の値) がEmployeeインスタンスになり、表示値が表示されますemployee.toString()
2. 2 番目の方法は、コンボボックスの cellFactory プロパティを設定することです。

combobox.setCellFactory(new Callback<ListView<Employee>, ListCell<Employee>>() {

    @Override
    public ListCell<Employee> call(ListView<Employee> arg0) {
        return new ListCell<Employee>() {

            private final Button btn;
            {
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                btn = new Button();
            }

            @Override
            protected void updateItem(Employee item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    btn.setStyle(item.getSalary() > 1000 ? "-fx-base:red" : "-fx-base: green");
                    btn.setText(item.getName() + "=" + item.getSalary());
                    setGraphic(btn);
                }
            }
        };
    }
});

このアプローチにより、セルのレンダリングをより強力に制御できます。表示値をフォーマットするだけでなく、任意のノード (コントロール) をセル (この場合はボタン) に含めて、表示ロジック (item.getSalary()?"":"") を追加することもできます。実際の値は同じままです。つまり、Employee インスタンスです。

于 2012-05-22T10:56:54.463 に答える
16

StringConverterを実装する別の解決策があります。オブジェクトには非常に便利です:

public class Product {

    private String code;
    private String name;

    public Product(String code, String name) {
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

コンバーターの実装:

public class ProductConverter extends StringConverter<Product> {

    /** Cache of Products */
    private Map<String, Product> productMap = new HashMap<String, Product>();

    @Override
    public String toString(Product product) {
        productMap.put(product.getName(), product);
        return product.getName();
    }

    @Override
    public Product fromString(String name) {
        return productMap.get(name);
    }

}

ビュー内のコード:

    ComboBox<Product> cboProducts  = new ComboBox<Product>;
    cboProducts.setConverter(new ProductConverter());
    cboProducts.getItems().addAll(serviceManager.getProductList());

製品の値を取得するには、getValue() メソッドを呼び出します。

cboProducts.getValue()
于 2012-06-08T22:45:23.797 に答える
0

この質問が古いことは知っていますが、この問題を無意味に掘り下げるのに何時間も費やしただけなので、結果を共有することは一種の義務です. オーバーライドされた toString() メソッドを使用した ComboBox は、リストに文字列の重複がある場合でも、文字列をオブジェクトに正しく解決するようです。解決はインデックス ベースである必要があり、toString() はプレゼンテーションにのみ使用されます。

于 2014-08-10T08:10:23.137 に答える