控件选择框JavaFX

控件选择框JavaFX,java,javafx,Java,Javafx,我正在写我的函数是JavaFX为我的应用程序提供的下拉地址。但它的功能和我想的不一样 我想在单击选择框城市和选择我的城市时,选择框城市将显示属于该城市的城镇。但现在,当我改变城市时,城镇也不会随之改变。我可以用什么来修复它呢?你可以在城市组合框的selectedItemProperty中添加一个ChangeListener,在那里你可以确保正确的地区将显示在另一个组合框中。下面是一个小例子: 控制器类: package sample; import javafx.collections.FXC

我正在写我的函数是JavaFX为我的应用程序提供的下拉地址。但它的功能和我想的不一样


我想在单击选择框城市和选择我的城市时,选择框城市将显示属于该城市的城镇。但现在,当我改变城市时,城镇也不会随之改变。我可以用什么来修复它呢?

你可以在城市组合框的
selectedItemProperty
中添加一个
ChangeListener
,在那里你可以确保正确的地区将显示在另一个
组合框中。下面是一个小例子:

控制器类:

package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    private ComboBox<String>
            cityComboBox,
            districtComboBox;

    ObservableList<String>
            citys = FXCollections.observableArrayList(
            "New York City", "Hamburg"),
            newYorkCityDistricts = FXCollections.observableArrayList(
                    "Manhattan", "Brooklyn", "Queens", "The Bronx", "Staten Island"),
            hamburgDistricts = FXCollections.observableArrayList(
                    "Hamburg-Mitte", "Altona", "Eimsbüttel", "Hamburg-Nord", "Wandsbek", "Bergedorf", "Harburg");

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        cityComboBox.setItems(citys);

        cityComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            switch (newValue) {
                case "New York City":
                    districtComboBox.setItems(newYorkCityDistricts);
                    break;
                case "Hamburg":
                    districtComboBox.setItems(hamburgDistricts);
                    break;
            }
        });
    }
}
包装样品;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.control.ComboBox;
导入java.net.URL;
导入java.util.ResourceBundle;
公共类控制器实现可初始化{
@FXML
专用组合框
城市通讯亭,
区组合框;
观察者
citys=FXCollections.observableArrayList(
“纽约市”、“汉堡市”),
newYorkCityDistricts=FXCollections.observableArrayList(
“曼哈顿”、“布鲁克林”、“皇后区”、“布朗克斯”、“斯塔顿岛”),
Hamburg Districts=FXCollections.observableArrayList(
“汉堡米特”、“阿尔托纳”、“艾姆斯比特尔”、“汉堡北部”、“旺茨贝克”、“伯格多夫”、“哈堡”);
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
cityComboBox.setItems(citys);
cityComboBox.getSelectionModel().SelectEditeProperty().addListener((可观察、旧值、新值)->{
开关(新值){
案例“纽约市”:
districtComboBox.setItems(纽约城市目录);
打破
“汉堡”案:
districtComboBox.setItems(地区);
打破
}
});
}
}
FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.VBox?>


<VBox xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <ComboBox fx:id="cityComboBox" prefWidth="150.0" promptText="city" />
      <ComboBox fx:id="districtComboBox" prefWidth="150.0" promptText="district" />
   </children>
</VBox>

您的问题不清楚,但似乎试图根据用户当前在另一个
选择框中的选择填充一个问题。我不是这方面的专家,但这里有一个小小的基本例子

在这里,用户选择枚举中定义的三种状态之一。每次用户更改
状态
所选项目时,我们都会更改
城市
选择框中填充的项目

我们通过捕获
状态
选择框中所选项目的索引号来实现这一点。然后,我们使用该索引检索匹配的
状态
枚举对象。我们使用该enum对象获取该特定州的城市名称列表。最后,我们用该列表重新填充
城市
选择框中的项目

我正在使用Java14中的新功能,在这里我将值分配给
城市
。但这段代码很容易被传统语法所取代

package work.basil.example;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.List;


/**
 * JavaFX App
 */
public class App extends Application
{
    enum State
    { TEXAS, OREGON, FLORIDA }

    @Override
    public void start ( Stage stage )
    {
        // Data model

        List < String > citiesTexas = List.of( "Austin" , "Dallas" , "Houston" );
        List < String > citiesOregon = List.of( "Bend" , "Eugene" , "Portland" );
        List < String > citiesFlorida = List.of( "Miami" , "Orlando" );

        // Widgets

        var citiesLabel = new Label( "Cities: " );
        ChoiceBox cities = new ChoiceBox();

        var statesLabel = new Label( "States: " );
        ChoiceBox < State > states = new ChoiceBox();
        states.getItems().addAll( State.values() );
        states.getSelectionModel().selectedIndexProperty().addListener(
                new ChangeListener < Number >()
                {
                    @Override
                    public void changed ( ObservableValue < ? extends Number > observable , Number oldValue , Number newValue )
                    {
                        State state = State.values()[ newValue.intValue() ];
                        List < String > cityList =
                                switch ( state )
                                        {
                                            case TEXAS -> citiesTexas;
                                            case OREGON -> citiesOregon;
                                            case FLORIDA -> citiesFlorida;
                                        };
                        cities.getItems().setAll( cityList );
                    }
                }
        );


        // Arrange
        var pane = new GridPane();
        pane.addRow( 0 , statesLabel , states );
        pane.addRow( 1 , citiesLabel , cities );
        pane.setVgap( 12 );

        pane.setPadding( new Insets( 14 ) );
        var scene = new Scene( pane , 640 , 480 );
        stage.setScene( scene );
        stage.show();
    }

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

在实际工作中,我会在enum
State
上添加一个
getDisplayName
方法,该方法返回一个字符串以向用户演示。我将配置
ChoiceBox
以使用该方法进行显示,而不是默认显示所有caps枚举常量名称。但对于这个特定的答案,这样的工作是不必要的

请包括一些代码;如果没有答案,很难/不可能确定问题。此外,重写一点这个问题更可取:它包括一些语法错误,使其难以理解。就我所知,“城镇”和“城市”也是同义词。你的意思是“城镇/城市”和“地区”还是“州/地区”和“城市”或类似的东西?请使用java编码约定-作为一名经验丰富的开发人员,你应该知道;)可能有一个我不知道的原因,但是在
states.getSelectionModel().selectedItemProperty()
中添加一个侦听器,然后直接打开
newValue
?另外,lambdas和switch表达式(后者需要最新的Java版本)不是更容易吗使侦听器基本上成为一行程序…我考虑的更多是
cities.getItems().setAll(switch(state){…})避免了更多的重复。我的理解是它是JDK 14中的标准:(您提供的链接似乎是指开关变量类型上的模式匹配。)
package work.basil.example;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.List;


/**
 * JavaFX App
 */
public class App extends Application
{
    enum State
    { TEXAS, OREGON, FLORIDA }

    // Data model
    List < String > citiesTexas = List.of( "Austin" , "Dallas" , "Houston" );
    List < String > citiesOregon = List.of( "Bend" , "Eugene" , "Portland" );
    List < String > citiesFlorida = List.of( "Miami" , "Orlando" );

    @Override
    public void start ( Stage stage )
    {
        // Widgets
        var citiesLabel = new Label( "Cities: " );
        ChoiceBox cities = new ChoiceBox();

        var statesLabel = new Label( "States: " );
        ChoiceBox < State > states = new ChoiceBox();
        states.getItems().addAll( State.values() );
        states
                .getSelectionModel()
                .selectedItemProperty()
                .addListener(
                        ( ObservableValue < ? extends State > observable , State oldValue , State newValue ) ->
                                cities.getItems().setAll( this.fetchCitiesForState( newValue ) )
                );

        // Arrange
        var pane = new GridPane();
        pane.addRow( 0 , statesLabel , states );
        pane.addRow( 1 , citiesLabel , cities );
        pane.setVgap( 12 );

        pane.setPadding( new Insets( 14 ) );
        var scene = new Scene( pane , 640 , 480 );
        stage.setScene( scene );
        stage.show();
    }

    // Data model
    List < String > fetchCitiesForState ( State state )
    {
        return
                switch ( state )
                        {
                            case TEXAS -> citiesTexas;
                            case OREGON -> citiesOregon;
                            case FLORIDA -> citiesFlorida;
                        };
    }

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