【问题标题】:JavaFX FXML Controller initialize method not invoked未调用 JavaFX FXML 控制器初始化方法
【发布时间】:2016-02-08 20:22:15
【问题描述】:

我正在尝试从一个简单的 ArrayList 的内容中填充 ListView。这是我的

Controller.java 文件:

package design;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;

public class Controller {

    @FXML private Button buttontest;
    @FXML private ListView<Song> listViewofSongs;

    protected List<Song> songList = new ArrayList<>();
    protected ListProperty<Song> listProperty = new SimpleListProperty<Song>();
    Song Language = new Song("Peter", "myalbum", "yes", 2010);

    public void addSong(Song song){
        songList.add(song);
    }

    public void initialize(URL url, ResourceBundle rb) {
            addSong(Language);
            listViewofSongs.setItems(FXCollections.observableList(songList));
     }



}

这是我的 Style.fxml 文件:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<GridPane prefHeight="499.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="design.Controller">
   <columnConstraints>
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints maxWidth="0.0" minWidth="0.0" prefWidth="0.0" />
      <ColumnConstraints maxWidth="0.0" minWidth="0.0" prefWidth="0.0" />
   </columnConstraints>
   <rowConstraints>
      <RowConstraints />
      <RowConstraints />
      <RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints maxHeight="10.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints maxHeight="10.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints fillHeight="false" maxHeight="500.0" minHeight="10.0" prefHeight="240.0" />
      <RowConstraints fillHeight="false" maxHeight="500.0" minHeight="10.0" prefHeight="149.0" />
      <RowConstraints fillHeight="false" maxHeight="500.0" minHeight="10.0" prefHeight="50.0" />
   </rowConstraints>
   <children>
      <Pane prefHeight="64.0" prefWidth="700.0">
         <children>
            <Label layoutX="259.0" layoutY="14.0" text="Song Library">
               <font>
                  <Font name="Consolas Bold" size="26.0" />
               </font>
               <padding>
                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
               </padding>
            </Label>
         </children>
      </Pane>
      <Separator prefWidth="200.0" GridPane.rowIndex="4" />
      <ListView fx:id="listViewofSongs" editable="true" prefHeight="239.0" prefWidth="700.0" GridPane.rowIndex="5" />

      <Label text="Song Info" GridPane.halignment="CENTER" GridPane.rowIndex="6" GridPane.valignment="TOP">
         <GridPane.margin>
            <Insets bottom="10.0" />
         </GridPane.margin>
         <font>
            <Font name="Consolas" size="22.0" />
         </font>
         <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </padding>
      </Label>
      <Label GridPane.rowIndex="6" />
      <Label text="NAME" GridPane.rowIndex="6">
         <font>
            <Font name="Calibri" size="19.0" />
         </font>
         <GridPane.margin>
            <Insets bottom="60.0" left="200.0" />
         </GridPane.margin>
      </Label>
      <TextField maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="343.0" GridPane.rowIndex="6">
         <GridPane.margin>
            <Insets bottom="60.0" left="275.0" />
         </GridPane.margin>
      </TextField>
      <Label text="ARTIST" GridPane.rowIndex="6">
         <font>
            <Font name="Calibri" size="19.0" />
         </font>
         <GridPane.margin>
            <Insets left="200.0" />
         </GridPane.margin>
      </Label>
      <TextField maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="343.0" GridPane.rowIndex="6">
         <GridPane.margin>
            <Insets left="275.0" />
         </GridPane.margin>
      </TextField>
      <Label text="ALBUM" GridPane.rowIndex="6">
         <font>
            <Font name="Calibri" size="19.0" />
         </font>
         <GridPane.margin>
            <Insets bottom="-60.0" left="200.0" />
         </GridPane.margin>
      </Label>
      <TextField maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="343.0" GridPane.rowIndex="6">
         <GridPane.margin>
            <Insets bottom="-60.0" left="275.0" />
         </GridPane.margin>
      </TextField>
      <Label text="YEAR" GridPane.rowIndex="6">
         <font>
            <Font name="Calibri" size="19.0" />
         </font>
         <GridPane.margin>
            <Insets bottom="-120.0" left="200.0" />
         </GridPane.margin>
      </Label>
      <TextField maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="25.0" prefWidth="343.0" GridPane.rowIndex="6">
         <GridPane.margin>
            <Insets bottom="-120.0" left="275.0" />
         </GridPane.margin>
      </TextField>
      <Button mnemonicParsing="false" prefHeight="28.0" prefWidth="75.0" text="ADD" GridPane.rowIndex="7">
         <GridPane.margin>
            <Insets left="125.0" />
         </GridPane.margin>
         <font>
            <Font name="Corbel" size="15.0" />
         </font>
      </Button>
      <Button mnemonicParsing="false" prefHeight="28.0" prefWidth="75.0" text="EDIT" GridPane.rowIndex="7">
         <font>
            <Font name="Corbel" size="15.0" />
         </font>
         <GridPane.margin>
            <Insets left="325.0" />
         </GridPane.margin>
      </Button>
      <Button mnemonicParsing="false" prefHeight="28.0" prefWidth="75.0" text="DELETE" GridPane.rowIndex="7">
         <font>
            <Font name="Corbel" size="15.0" />
         </font>
         <GridPane.margin>
            <Insets left="525.0" />
         </GridPane.margin>
      </Button>
      <Separator orientation="VERTICAL" prefHeight="200.0" GridPane.rowIndex="7">
         <GridPane.margin>
            <Insets left="250.0" />
         </GridPane.margin>
         <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </padding>
      </Separator>
   </children>
</GridPane>

程序运行了,但是我输入的歌曲没有出现在ListView中(而且Song类确实有toString方法)。

我能做什么?

【问题讨论】:

  • 为什么不把listViewOfSongs.getItems().add(song)写成你的addSong实现呢?
  • 即使这样,它仍然不显示。
  • 您可能还有其他问题,请提供mcve 以重现它。
  • 我添加了我的 Style.fxml...没有太多代码。你看不出它为什么不起作用?
  • 我想通了。需要实现 Initializable 并添加 @Override

标签: java javafx


【解决方案1】:

问题是控制器没有被初始化为预期的问题提问者。

Java 8 中 FXMLLoader 的操作有点奇怪。

  1. 如果你在 Controller 中定义了一个无参数的 initialize() 方法并且没有实现 Initializable 接口,那么 FXML 加载器仍然会自动调用 initialize 方法。

  2. 如果相反,您在 Controller 中定义了参数化的 public void initialize(URL url, ResourceBundle rb) 方法,那么 FXML 加载器将不会自动调用初始化方法除非您的控制器也实现了 Initializable 接口。

由于问题中的代码使用了参数化的初始化方法并且没有实现 Initializable,因此没有进行初始化。


参数化的初始化方法应该在FXML中通过@FXML注解注入参数来替换,更多细节见:

【讨论】:

  • 如果你有一个无参数initialize 实现Initializable会发生什么?是否会被调用?两者都做?编辑:查看代码,似乎Initializable 优先,并禁止对无参数initialize 方法的任何调用。
  • 很棒的答案...我想知道那些编写规范的人怎么会错过这样的功能!谢谢
【解决方案2】:

如果我没看错,您实际上并没有在 initialize() 方法中使用 URL 和 ResourceBundle 参数。 如果 URL 是您的 fxml 文件的路径,并且 ResourceBundle 包含您的 GUI 的国际化属性,那么您应该定义不带参数的 initialize() 方法,但使用 @FXML 进行注释。 URL 和 ResourceBundle 应该传递给 FXMLLoader。

喜欢

FXMLLoader loader = new FXMLLoader(URL, rb);

@FXML
private void initialize() { ... }

这样initialize()会被自动调用。

【讨论】:

  • 用@FXML 注释为我修复了它。
【解决方案3】:

我需要在类中实现 Initializable 并在调用方法之前添加一个@Override。

【讨论】:

    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多