Javafx 带有进度条的组合框工作不正常

Javafx 带有进度条的组合框工作不正常,javafx,javafx-2,javafx-8,Javafx,Javafx 2,Javafx 8,我有一个带有进度条的组合框示例 package javafxapplication4; import javafx.application.Application; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ListCell;

我有一个带有进度条的组合框示例

package javafxapplication4;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;


public class JavaFXApplication4 extends Application
{

    @Override
    public void start(Stage primaryStage)
    {

     double y1 = 15;
        ProgressBar p1 = new ProgressBar();
        p1.setLayoutY(y1);
    VBox vb1 = new VBox();
    vb1.getChildren().addAll(new Label("Progressbar 1"), p1);

    double y2 = 15;
        ProgressBar p2 = new ProgressBar();
        p2.setLayoutY(y2);
    VBox vb2 = new VBox();
    vb2.getChildren().addAll(new Label("Progressbar 2"), p2);

    double y3 = 15;
        ProgressBar p3 = new ProgressBar();
        p3.setLayoutY(y3);
    VBox vb3 = new VBox();
    vb3.getChildren().addAll(new Label("Progressbar 3"), p3);


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

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





        StackPane root = new StackPane();
        root.getChildren().add(textChooser);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    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.graphicProperty().bind(
            //combo.getSelectionModel().selectedItemProperty()
            combo.getSelectionModel().selectedItemProperty()
        );
        label.visibleProperty().bind(
            combo.visibleProperty().not()
        );
        //label.setPadding(new Insets(0, 0, 0, 10));

        combo.getItems().setAll(options);

        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);
                        }
                    }
                };
            }
        });

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

        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);
    }

    public static void main(String[] args)
    {
        launch(args);
    }
    }
}
PackageJavaFXApplication4;
导入javafx.application.application;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.control.ProgressBar;
导入javafx.scene.layout.StackPane;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.util.Callback;
公共类JavaFXApplication4扩展了应用程序
{
@凌驾
公共无效开始(阶段primaryStage)
{
双y1=15;
ProgressBar p1=新ProgressBar();
p1.设置布局(y1);
VBox vb1=新的VBox();
vb1.getChildren().addAll(新标签(“Progressbar 1”),p1;
双y2=15;
ProgressBar p2=新的ProgressBar();
p2.设置布局(y2);
VBox vb2=新的VBox();
vb2.getChildren().addAll(新标签(“Progressbar 2”),p2);
双y3=15;
ProgressBar p3=新的ProgressBar();
p3.设置布局(y3);
VBox vb3=新的VBox();
vb3.getChildren().addAll(新标签(“Progressbar 3”),p3);
TextChooser TextChooser=新建TextChooser(
vb1、vb2、vb3
);
textChooser.setStyle(“-fx字体:10px\“Verdana\”;”);
StackPane root=新的StackPane();
root.getChildren().add(textChooser);
场景=新场景(根,300,250);
setTitle(“你好,世界!”);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态类TextChooser扩展StackPane{
私有标签=新标签();
私有组合框combo=新组合框();
公共文本选择器(VBox…选项){
StackPane.setAlignment(标签,左中位置);
StackPane.setAlignment(组合框,左中位置);
label.graphicProperty().bind(
//combo.getSelectionModel().SelectEditeProperty()
combo.getSelectionModel().SelectEditeProperty()
);
label.visibleProperty().bind(
combo.visibleProperty().not()
);
//label.setPadding(新插图(0,0,0,10));
combo.getItems().setAll(选项);
setCellFactory(新回调(){
@覆盖公共ListCell调用(ListView p){
返回新的ListCell(){
@覆盖受保护的void updateItem(VBox项,布尔值为空){
super.updateItem(项,空);
如果(项==null | |空){
设置图形(空);
}否则{
设置图形(项目);
}
}
};
}
});
combo.getSelectionModel().select(0);
combo.setVisible(true);
label.setonmouseintered(事件->组合.setVisible(true));
combo.showingProperty().addListener(可观察->{
如果(!combo.isShowing()){
combo.setVisible(false);
}
});
combo.setOnMouseExited(事件->{
if(!combo.isShowing()){
combo.setVisible(false);
}
});
getChildren().setAll(标签、组合);
}
公共静态void main(字符串[]args)
{
发射(args);
}
}
}

我想在应用程序运行时显示一个进度条,其中包含正在运行的后台进程。当我将鼠标移到进度条上时,我希望看到所有进程。但是由于某些原因,代码不能正常工作-当我选择进度条时,没有显示进度条。你能帮我处理一下这个代码吗。

要更改“按钮”中的显示(即所选值的显示),你需要使用

combo.setButtonCell(...);
然而,我认为这在你的情况下是行不通的。问题是您有一个节点子类(VBox)作为组合框的类型。因此,所选项目将出现在场景图中的两个位置:一个在下拉列表中,一个在组合框按钮中。通常,使用节点作为组合框的类型是一个非常糟糕的主意:请参见:

强烈建议不要将节点放入项目列表中


您应该改为使用组合框的数据类型,并在ListCell实现中创建VBox。

要更改“按钮”中的显示(即所选值的显示),您需要使用

combo.setButtonCell(...);
然而,我认为这在你的情况下是行不通的。问题是您有一个节点子类(VBox)作为组合框的类型。因此,所选项目将出现在场景图中的两个位置:一个在下拉列表中,一个在组合框按钮中。通常,使用节点作为组合框的类型是一个非常糟糕的主意:请参见:

强烈建议不要将节点放入项目列表中

您应该为ComboBox使用数据类型,并在ListCell实现中创建VBox。

如本文所述

公共类JavaFXApplication5扩展应用程序
{
公共静态void main(字符串[]args)
{
发射(args);
}
公共类进程数据
{
private final DoubleProperty progressProp=新的SimpleDoubleProperty();
private final StringProperty progressName=新SimpleStringProperty();
公共进度数据(字符串名称,双进度)
{
progressProp.set(进程);
progressName.set(名称);
}
公共财产
{
返回progressProp;
}
公共字符串属性nameProperty()
{
返回进程名称;
}
@凌驾
//懒散的组合按钮黑客。
公共字符串toString()
{
返回progressName.get();
}
}
@凌驾
公共无效启动(