我正在尝试创建一个下拉列表,在javafx中显示用户的名字、姓氏和用户ID

问题描述 投票:0回答:1

我正在创建一个 javafx/fxml 应用程序。我有一个显示名字、姓氏和 ID 的下拉列表。我希望下拉列表具有每列的标题,并在相应的列中显示数据。我将如何创建这个下拉菜单?

我尝试在组合框中创建列表视图,但无法正常工作。我也尝试过使用表格视图,但我也无法正常工作。

fxml javafx-11
1个回答
0
投票

您可以将单元工厂设置为 ComboBox,以您想要的方式创建单元。然而,实现标题并仅滚动值单元格会很棘手。

为了让事情简单,我宁愿使用一个自定义实现,它看起来像一个下拉列表,但使用一些不同的节点构建。

总体思路是:

  • 创建一个按钮来显示值。
  • 单击按钮时,会在位于按钮底部的
    TableView
    中显示
    Popup
  • 单击一行时,按钮中的值/文本将更新并关闭弹出窗口。

请查看下面的演示。如果这不能满足您的需求,那么我认为您需要使用细胞工厂实现。

import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;

public class DropDownWithTableDemo extends Application {
    String defaultVal = "Select...";

    ObjectProperty<TableObj> valueObj = new SimpleObjectProperty<>();

    @Override
    public void start(Stage primaryStage) throws Exception {
        TableView<TableObj> tableView = buildTable(valueObj);
        Popup popup = new Popup();
        popup.getContent().add(tableView);
        popup.setAutoHide(true);

        Label valueLabel = new Label(defaultVal);
        valueLabel.setMaxWidth(Double.POSITIVE_INFINITY);
        HBox.setHgrow(valueLabel, Priority.ALWAYS);

        StackPane arrow = new StackPane();
        arrow.setStyle("-fx-background-color:#444444;-fx-shape:\"M 0 0 h 7 l -3.5 4 z\";-fx-padding: 4px;");
        arrow.setMaxSize(8, 8);

        HBox pane = new HBox(10, valueLabel, arrow);
        pane.setAlignment(Pos.CENTER_LEFT);
        pane.setMaxWidth(Double.POSITIVE_INFINITY);

        Button dropDownBtn = new Button();
        dropDownBtn.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        dropDownBtn.setPrefWidth(150);
        dropDownBtn.setGraphic(pane);
        dropDownBtn.setOnMouseClicked(e -> {
            if (!popup.isShowing()) {
                Bounds bounds = dropDownBtn.localToScreen(dropDownBtn.getLayoutBounds());
                popup.show(dropDownBtn, bounds.getMinX(), bounds.getMaxY());
            }
        });

        valueObj.addListener((obs, old, val) -> {
            if (val != null) {
                valueLabel.setText(val.firstName.getValue());
            } else {
                valueLabel.setText(defaultVal);
            }
            popup.hide();
        });

        Scene scene = new Scene(new StackPane(dropDownBtn), 400, 200);
        primaryStage.setTitle("TableView DropDown");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TableView<TableObj> buildTable(ObjectProperty<TableObj> valueObj) {
        TableView<TableObj> tableView = new TableView<>();
        TableColumn<TableObj, String> idCol = new TableColumn<>("ID");
        TableColumn<TableObj, String> fnCol = new TableColumn<>("First Name");
        TableColumn<TableObj, String> lnCol = new TableColumn<>("Last Name");

        idCol.setCellValueFactory(p -> p.getValue().id);
        fnCol.setCellValueFactory(p -> p.getValue().firstName);
        lnCol.setCellValueFactory(p -> p.getValue().lastName);

        ObservableList<TableObj> items = FXCollections.observableArrayList();
        for (int x = 1; x < 50; x++) {
            items.add(new TableObj("" + x, "First " + x, "Last " + x));
        }

        tableView.getColumns().addAll(idCol, fnCol, lnCol);
        tableView.setItems(items);
        tableView.setRowFactory(param -> new TableRow<>() {
            {
                setOnMouseClicked(e -> {
                    if (getItem() != null) {
                        valueObj.set(getItem());
                    }
                });
            }
        });
        return tableView;
    }

    class TableObj {
        private StringProperty id;
        private StringProperty firstName;
        private StringProperty lastName;

        public TableObj(String test1, String test2, String test3) {
            this.id = new SimpleStringProperty(test1);
            this.firstName = new SimpleStringProperty(test2);
            this.lastName = new SimpleStringProperty(test3);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.