I am trying to fill ListView from the content of a simple ArrayList. Here is my
Controller.java file:
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));
}
}
And here is my Style.fxml file:
<?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>
The program runs, but the song I have entered does not appear in the ListView (and the Song class does have a toString method).
What can I do?
The issue was that the Controller's wasn't being initialized as the asker of the question expected.
The operation of the FXMLLoader in Java 8 is a little weird.
If you define a no-parameter initialize()
method in your Controller and don't implement the Initializable
interface, then the FXML loader will still automatically invoke the initialize method.
If instead, you define a parameterized public void initialize(URL url, ResourceBundle rb)
method in your Controller, then the FXML loader will not automatically invoke the initialize method unless your controller also implements the Initializable
interface.
As the code in the question was using a parameterized initialize method and not also implementing Initializable, the initialization was not occurring.
The parameterized initialize method should be replaced in FXML by injection of the parameters via @FXML annotation, for more details see:
What is "automatic injection of location and resources properties into the controller" in JavaFX?
@FXML
private ResourceBundle resources;
@FXML
private URL location;
If I see correctly, you actually don't use the URL and the ResourceBundle parameters in you initialize()
method.
If the URL is the path to your fxml file, and the ResourceBundle contains internatonalization properties for your GUI, then you should define your initialize()
method without parameters, but annotated with @FXML
. The URL and the ResourceBundle should be passed to the FXMLLoader.
Like
FXMLLoader loader = new FXMLLoader(URL, rb);
and
@FXML
private void initialize() { ... }
This way initialize()
will be automatically invoked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With