【问题标题】:Filling the Combobox with choices用选项填充组合框
【发布时间】:2026-01-11 00:25:01
【问题描述】:

在编程或 java 方面,我只是一个完整的初学者。 因此,一开始我的计划是使用 JavaFX(与场景构建器结合)创建一个窗口,其中我确实有一个按钮,可以将我引导到另一个窗口,我确实有一个组合框。我现在用谷歌搜索了几个小时,以找到一种方法来填充该组合框,但我发现的所有解决方案都不适合我。这就是为什么我认为我在这里犯了一些错误,我希望你能以某种方式帮助我。或者在列表中给我一个提示,我应该学习/阅读什么来自己解决问题。 因此,首先,这是我构建第一阶段的 main.java 代码。

main.java:

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root= FXMLLoader.load(getClass().getResource("Scene-Hauptmenu.fxml"));
            primaryStage.setTitle("Fishbase");
            primaryStage.sizeToScene();
            primaryStage.setResizable(false);
            primaryStage.setScene(new Scene(root));
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }       
    }

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

在我的“Scene-Hauptmenu.fxml”中,最重要的是引导我进入第二个窗口的按钮:

Scene-Hauptmenu.fxml:

<Button id="btn_gefangen" fx:id="btn_gefangen" mnemonicParsing="false" onAction="#gefangen" text="Ich habe Fische gefangen!" GridPane.rowIndex="1" />

到目前为止一切正常,我可以毫无问题地切换到第二个窗口。但我认为我的主要问题在于我的控制器类,所以就在这里。

MyController.java:

public class MyController implements Initializable{
    private Node node;
    private Stage stage;
    private Scene scene;
    private FXMLLoader fxmlLoader;
    private Parent root;

    @FXML
    private Button btn_gefangen;

    @FXML
    private ComboBox<String> chobo_fisch; 

    @FXML
    private Button btn_gefangen_zurueck;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }

    public void gefangen(ActionEvent event) throws IOException{

        node = (Node) event.getSource();
        stage = (Stage) node.getScene().getWindow();
        scene = stage.getScene();

        fxmlLoader = new FXMLLoader (getClass().getResource("gefangen.fxml"));

        root = (Parent) fxmlLoader.load();
        scene.setRoot(root);
        stage.sizeToScene();
        stage.setTitle("Fische eintragen");          
    }


    public void gefangen_zurueck(ActionEvent event) throws IOException{
        node = (Node) event.getSource();
        stage = (Stage) node.getScene().getWindow();
        scene = stage.getScene();
        fxmlLoader = new FXMLLoader (getClass().getResource("Scene-Hauptmenu.fxml"));
        root = (Parent) fxmlLoader.load();
        scene.setRoot(root);
        stage.sizeToScene();
        stage.setTitle("Fishbase");     
    }   
}

所以按钮“btn_gefangen”将我带到另一个窗口,在那里我确实有带有 fx:id “chobo_fisch”的组合框。

格方根.fxml:

<ComboBox fx:id="chobo_Fisch" prefWidth="150.0"/>

所以我用谷歌搜索了几个小时,但我仍然没有找到任何解决方案来用适用于我的代码的选项填充组合框。我做错了什么?有人可以帮我吗?

最好的问候

詹尼克

【问题讨论】:

  • 你为什么只声明字段,而不是局部变量?如果以后不需要访问它,将数据保存在字段中是没有意义的。事实上,这增加了你的类的足迹,除了使某些对象无法用于垃圾收集,即使它们不再需要。此外,我建议对不同的 fxml 使用不同的控制器类。控制器指定初学者最常开始使用的控制器的方法(fx:控制器)导致每次加载 fxml 时都会创建控制器实例。没有来自不同 fxml 的节点可用。

标签: java javafx combobox fxml


【解决方案1】:

我发现了三个变体,具体取决于您的设置:

第一个变体

// Weekdays 
String week_days[] = 
    { "Monday", "Tuesday", "Wednesday", 
      "Thrusday", "Friday" }; 

// Create a combo box 
ComboBox combo_box = new ComboBox(FXCollections.observableArrayList(week_days)); 

(来源:https://www.geeksforgeeks.org/javafx-combobox-with-examples/

第二个变种

final ComboBox emailComboBox = new ComboBox();
emailComboBox.getItems().addAll(
            "jacob.smith@example.com",
            "isabella.johnson@example.com",
            "ethan.williams@example.com",
            "emma.jones@example.com",
            "michael.brown@example.com"  
        );

来源:(https://docs.oracle.com/javafx/2/ui_controls/combo-box.htm)

第三种变体(用于 FXML)

<ComboBox fx:id="someName">
     <items>
         <FXCollections fx:factory="observableArrayList">
              <String fx:value="1"/>
              <String fx:value="2"/>
              <String fx:value="3"/>
              <String fx:value="4"/>
          </FXCollections>
      </items>
      <value>
           <String fx:value="1"/>
      </value>
</ComboBox>

编辑

正如 f* 所说,您应该确保包含 FXML 导入:

<?import javafx.collections.FXCollections?>
<?import java.lang.String?>

第二个可能不需要。

【讨论】:

  • 当我尝试您的第 3 个变体时,我收到以下错误:原因:javafx.fxml.LoadException:FXCollections 不是有效类型。 /D:/workspace/Fishbase/bin/application/gefangen.fxml:33
  • @JannikVöhl 您需要确保在 fxml 文件的开头包含正确的导入处理指令:&lt;?import javafx.collections.FXCollections?&gt; &lt;?import java.lang.String?&gt;(第二个可能已经被 java.lang.* 的导入覆盖)
  • 哦,我的...我以为我已经为此编写了导入行,但实际上我没有。很抱歉,它现在可以正常工作了,非常感谢你,并对我的愚蠢问题感到抱歉!
  • 首先没有愚蠢的问题 :) 其次,我建议使用为您添加这些导入的良好 IDE,例如 IntelliJ Idea(社区版)、Netbeans 或 Eclipse。全部免费。
  • 我确实使用 Eclipse,但它不建议导入 FXML 文件,至少对我来说不是:D
【解决方案2】:

我对这些东西不熟悉,但我认为如果我理解你想要的东西,它应该是这样的,或者至少也很接近。 示例如下:

ComboBox<String> stuff = new ComboBox<>(); stuff.getItems().addAll("1","2","5","10");

注意:我是 * 的新手。

【讨论】:

    【解决方案3】:

    试试这个:

    ObservableList<String> items = FXCollections.observableArrayList();
        items.add("a");
        items.add("b");
        chobo_fisch.getItems().addAll(items);
    

    【讨论】:

    • 遗憾的是,我只得到一个 java.lang.NullPointerException
    【解决方案4】:

    您的组合框必须填充项目(在您的情况下为字符串):

        List<String> list = new ArrayList<String>();
        list.add("Item 1");
        list.add("Item 2");
        chobo_fisch.setItems(FXCollections.observableArrayList(list));
    

    如果您使用更复杂对象的组合框,您可以使用 cellfactory 来选择显示的值:

        chobo_fisch.setCellFactory(obj -> new ChoboFischListCell());
        chobo_fisch.setButtonCell(new ChoboFischListCell());
    

    其中 ChoboFischListCell 是一个扩展 ListCell 的类,您可以在其中实现应显示对象的哪个字段。

    【讨论】: