Javafx 在鼠标悬停时显示下拉菜单

Javafx 在鼠标悬停时显示下拉菜单,javafx,javafx-2,javafx-8,Javafx,Javafx 2,Javafx 8,我想创建如下下拉菜单: 当我将鼠标放在文本上时,我希望看到可以用来选择值的组合框。当我移除鼠标时,我想看到简单的标签。如何做到这一点?两种可能的方法: 尝试使用CSS修改组合框的外观,使其看起来像一个普通的文本字段;隐藏箭头和边框,并在“悬停”上重新显示它们。您需要查找组合框的CSS参考: 使用普通文本字段,并在:hover上显示边框(和箭头)。将鼠标侦听器附加到文本字段,以便在鼠标单击时显示弹出控件。将ListView放在PopupControl中,使其行为类似于组合框。您需要为弹出控件创建

我想创建如下下拉菜单:


当我将鼠标放在文本上时,我希望看到可以用来选择值的组合框。当我移除鼠标时,我想看到简单的标签。如何做到这一点?

两种可能的方法:

  • 尝试使用CSS修改组合框的外观,使其看起来像一个普通的文本字段;隐藏箭头和边框,并在“悬停”上重新显示它们。您需要查找组合框的CSS参考:

  • 使用普通文本字段,并在:hover上显示边框(和箭头)。将鼠标侦听器附加到文本字段,以便在鼠标单击时显示弹出控件。将ListView放在PopupControl中,使其行为类似于组合框。您需要为弹出控件创建一个实现皮肤的类。你应该可以在网上找到一些例子

  • 未被发现的:

    悬停时:

    单击并选择:

    完成选择时:

    import javafx.application.Application;
    import javafx.geometry.*;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.*;
    import javafx.stage.Stage;
    
    public class Hoverboard extends Application {
    
        public 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, 9));
    
                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);
            }
        }
    
        @Override
        public void start(Stage stage) throws Exception {
            TextChooser textChooser = new TextChooser(
                "xyzzy", "frobozz", "foobar"
            );
    
            VBox layout = new VBox(textChooser);
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(Hoverboard.class);
        }
    
    }
    

    导入javafx.application.application;
    导入javafx.geometry.*;
    导入javafx.scene.scene;
    导入javafx.scene.control.*;
    导入javafx.scene.layout.*;
    导入javafx.stage.stage;
    公共类悬停板扩展应用程序{
    公共类TextChooser扩展StackPane{
    私有标签=新标签();
    私有组合框combo=新组合框();
    公共文本选择器(字符串…选项){
    StackPane.setAlignment(标签,左中位置);
    StackPane.setAlignment(组合框,左中位置);
    label.textProperty().bind(
    combo.getSelectionModel().SelectEditeProperty()
    );
    label.visibleProperty().bind(
    combo.visibleProperty().not()
    );
    label.setPadding(新的插图(0,0,0,9));
    combo.getItems().setAll(选项);
    combo.getSelectionModel().select(0);
    combo.setVisible(false);
    label.setonmouseintered(事件->组合.setVisible(true));
    combo.showingProperty().addListener(可观察->{
    如果(!combo.isShowing()){
    combo.setVisible(false);
    }
    });
    combo.setOnMouseExited(事件->{
    如果(!combo.isShowing()){
    combo.setVisible(false);
    }
    });
    getChildren().setAll(标签、组合);
    }
    }
    @凌驾
    public void start(Stage)引发异常{
    TextChooser TextChooser=新建TextChooser(
    “xyzy”、“frobozz”、“foobar”
    );
    VBox布局=新的VBox(文本选择器);
    布局。设置填充(新插图(10));
    舞台场景(新场景(布局));
    stage.show();
    }
    公共静态void main(字符串[]args){
    发射(悬停板级);
    }
    }
    
    这里还有css样式的版本:

    与默认的有点不同,但是您可以使用css来获得所需的内容。默认样式可以在jxrt.jar中找到/com/sun/javafx/scene/control/skin/caspian/caspian.css

    CSS

    JAVA

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            HBox root = new HBox();
            primaryStage.setTitle("Combo Box Style From Css");
    
    
            ComboBox combobox = new ComboBox<String>(FXCollections.observableArrayList("One", "Two", "Three"));
            combobox.getSelectionModel().select(0);
            combobox.setId("changed");
    
            ComboBox normalCombobox = new ComboBox<String>(FXCollections.observableArrayList("One", "Two", "Three"));
            normalCombobox.getSelectionModel().select(0);
    
            root.getChildren().addAll(combobox, normalCombobox);
            Scene scene = new Scene(root, 300, 275);
            scene.setFill(Color.WHITE);
            String css = Main.class.getResource("styles.css").toExternalForm();
            scene.getStylesheets().clear();
            scene.getStylesheets().add(css);
    
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    public类主扩展应用程序{
    @凌驾
    public void start(Stage primaryStage)引发异常{
    HBox根=新的HBox();
    setTitle(“Css中的组合框样式”);
    ComboBox ComboBox=新的ComboBox(FXCollections.observableArrayList(“一”、“二”、“三”));
    combobox.getSelectionModel().select(0);
    combobox.setId(“已更改”);
    ComboBox normalCombobox=新的ComboBox(FXCollections.observableArrayList(“一”、“二”、“三”));
    normalCombobox.getSelectionModel().select(0);
    root.getChildren().addAll(组合框,normalCombobox);
    场景=新场景(根,300275);
    场景。设置填充(颜色。白色);
    字符串css=Main.class.getResource(“styles.css”).toExternalForm();
    scene.getStylesheets().clear();
    scene.getStylesheets().add(css);
    初级阶段。场景(场景);
    primaryStage.show();
    }
    公共静态void main(字符串[]args){
    发射(args);
    }
    }
    
    演示

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            HBox root = new HBox();
            primaryStage.setTitle("Combo Box Style From Css");
    
    
            ComboBox combobox = new ComboBox<String>(FXCollections.observableArrayList("One", "Two", "Three"));
            combobox.getSelectionModel().select(0);
            combobox.setId("changed");
    
            ComboBox normalCombobox = new ComboBox<String>(FXCollections.observableArrayList("One", "Two", "Three"));
            normalCombobox.getSelectionModel().select(0);
    
            root.getChildren().addAll(combobox, normalCombobox);
            Scene scene = new Scene(root, 300, 275);
            scene.setFill(Color.WHITE);
            String css = Main.class.getResource("styles.css").toExternalForm();
            scene.getStylesheets().clear();
            scene.getStylesheets().add(css);
    
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
    
        public static void main(String[] args) {
            launch(args);
        }
    }