将标签和进度条显示在组合框中

时间:2013-12-06 20:21:32

标签: javafx javafx-2 javafx-8

我有这个代码,用于将文本显示到组合框中。

ProgressBar pb1 = new ProgressBar(0.6);
        ProgressIndicator pi1 = new ProgressIndicator(0.6);
        VBox vb1 = new VBox();
        vb1.getChildren().addAll(new Label("Progressbar 1"), pi1);

        ProgressBar pb2 = new ProgressBar(0.6);
        ProgressIndicator pi2 = new ProgressIndicator(0.6);
        VBox vb2 = new VBox();
        vb2.getChildren().addAll(new Label("Progressbar 2"), pi2);

        ProgressBar pb3 = new ProgressBar(0.6);
        ProgressIndicator pi3 = new ProgressIndicator(0.6);
        VBox vb3 = new VBox();
        vb3.getChildren().addAll(new Label("Progressbar 3"), pi3);


        TextChooser textChooser = new TextChooser(
            vb1, vb2, vb3
        );

        textChooser.setStyle("-fx-font: 10px \"Verdana\";");

        VBox layout = new VBox(textChooser);
        layout.setPadding(new Insets(22, 22, 22, 22));



public static class TextChooser extends StackPane {
        private Label label = new Label();
        private ComboBox<String> combo = new ComboBox<>();

        public TextChooser(String... options) {
            StackPane.setAlignment(label, Pos.CENTER_LEFT);
            StackPane.setAlignment(combo, Pos.CENTER_LEFT);

            label.textProperty().bind(
                combo.getSelectionModel().selectedItemProperty()
            );
            label.visibleProperty().bind(
                combo.visibleProperty().not()
            );
            label.setPadding(new Insets(0, 0, 0, 10));

            combo.getItems().setAll(options);
            combo.getSelectionModel().select(0);
            combo.setVisible(false);

            label.setOnMouseEntered(event -> combo.setVisible(true));
            combo.showingProperty().addListener(observable -> {
                if (!combo.isShowing()) {
                    combo.setVisible(false);
                }
            });
            combo.setOnMouseExited(event -> {
                if (!combo.isShowing()) {
                    combo.setVisible(false);
                }
            });

            getChildren().setAll(label, combo);
        }
    }

在我的情况下,我无法将VBox插入组合框中。知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

代码的最大问题是,当形式参数为TextChooser时,尝试使用VBox构建String。将构造函数更改为public TextChooser(VBox... options),将ComboBox声明更改为private ComboBox<VBox> combo = new ComboBox<>();

现在,您将能够将项目添加到组合框中,如果它有效,您就完成了。如果您遇到将Node添加到ComboBox的问题,则可能需要添加更多代码。 ComboBoxhttp://docs.oracle.com/javafx/2/api/javafx/scene/control/ComboBox.html的Javadoc中描述了问题和解决方案。为了解决您选择的项目将从组合框中删除的事实,您需要更改此代码(取自javadoc):

combo.setCellFactory(new Callback<ListView<VBox>, ListCell<VBox>>() {
    @Override public ListCell<VBox> call(ListView<VBox> p) {
        return new ListCell<VBox>() {
            @Override protected void updateItem(VBox item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    setGraphic(item);
                }
            }
        };
    }
});
在行getItems().setAll(options);之后

这就是您的完整示例代码将变成的内容:

    ProgressBar pb1 = new ProgressBar(0.6);
    ProgressIndicator pi1 = new ProgressIndicator(0.6);
    VBox vb1 = new VBox();
    vb1.getChildren().addAll(new Label("Progressbar 1"), pi1);

    ProgressBar pb2 = new ProgressBar(0.6);
    ProgressIndicator pi2 = new ProgressIndicator(0.6);
    VBox vb2 = new VBox();
    vb2.getChildren().addAll(new Label("Progressbar 2"), pi2);

    ProgressBar pb3 = new ProgressBar(0.6);
    ProgressIndicator pi3 = new ProgressIndicator(0.6);
    VBox vb3 = new VBox();
    vb3.getChildren().addAll(new Label("Progressbar 3"), pi3);


    TextChooser textChooser = new TextChooser(
        vb1, vb2, vb3
    );

    textChooser.setStyle("-fx-font: 10px \"Verdana\";");

    VBox layout = new VBox(textChooser);
    layout.setPadding(new Insets(22, 22, 22, 22));



public static class TextChooser extends StackPane {
    private Label label = new Label();
    private ComboBox<VBox> combo = new ComboBox<>();

    public TextChooser(VBox... options) {
        StackPane.setAlignment(label, Pos.CENTER_LEFT);
        StackPane.setAlignment(combo, Pos.CENTER_LEFT);

        label.textProperty().bind(
            combo.getSelectionModel().selectedItemProperty()
        );
        label.visibleProperty().bind(
            combo.visibleProperty().not()
        );
        label.setPadding(new Insets(0, 0, 0, 10));

        combo.getItems().setAll(options);

        // vvvv Begin Optional Part vvvv
        combo.setCellFactory(new Callback<ListView<VBox>, ListCell<VBox>>() {
            @Override public ListCell<VBox> call(ListView<VBox> p) {
                return new ListCell<VBox>() {
                    @Override protected void updateItem(VBox item, boolean empty) {
                        super.updateItem(item, empty);

                        if (item == null || empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(item);
                        }
                    }
                };
            }
        });
        // ^^^^ End Optional Part ^^^^

        combo.getSelectionModel().select(0);
        combo.setVisible(false);

        label.setOnMouseEntered(event -> combo.setVisible(true));
        combo.showingProperty().addListener(observable -> {
            if (!combo.isShowing()) {
                combo.setVisible(false);
            }
        });
        combo.setOnMouseExited(event -> {
            if (!combo.isShowing()) {
                combo.setVisible(false);
            }
        });

        getChildren().setAll(label, combo);
    }
}