Search code examples
mavenjavafxfxml

populate JavaFX ListView


The ListView does not show what I expected.

I have just started to use JavaFX using Maven and Fxml. And I am wondering, why my data does not show up.

I followed several tutorials, also searched here, but can not pinpoint my fault. For sure it should be simple.

The App:

package eu.ngong.sampleFxml;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        scene = new Scene(new FXMLLoader(App.class.getResource("primary.fxml")).load(), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

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

}

The Controller:

package eu.ngong.sampleFxml;

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

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;

public class PrimaryController implements Initializable {

    String[] values = { "one", "two", "three", "four", "five" };

    @FXML
    private ListView<String> theList;

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

        this.theList.getItems().addAll(values);

    };

}

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.layout.VBox?>

<VBox id="primary" alignment="TOP_CENTER" prefHeight="970.0" prefWidth="966.0" spacing="20.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="eu.ngong.sampleFxml.PrimaryController">
   <children>
      <Label text="Primary View" />
      <ListView id="theList" fx:id="theList" minHeight="100.0" minWidth="926.0" prefHeight="893.0" prefWidth="926.0">
         <VBox.margin>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
         </VBox.margin>
         <padding>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
         </padding>
      </ListView>
   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
</VBox>

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>eu.ngong</groupId>
    <artifactId>sampleFxml</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>21-ea+5</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>21-ea+5</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <release>17</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running -->
                        <!-- Usage: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>eu.ngong.sampleFxml.App</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

This results to

while I expected to see the words "one", "two", "three", "four", "five".

You may also

git clone https://gitlab.com/ngong1/samplefxml.git

Solution

  • It is never a good idea to hard-code sizes in JavaFX (or, indeed, in any responsive UI toolkit). Let the layout panes size the components accordingly, and use the API for the layout panes to control how that is done, if needed.

    In your case you make the minimum width of the ListView 926 pixels:

      <ListView id="theList" fx:id="theList" minHeight="100.0" minWidth="926.0" prefHeight="893.0" prefWidth="926.0">
    

    but you create a Scene which is only 640 pixels wide:

        scene = new Scene(new FXMLLoader(App.class.getResource("primary.fxml")).load(), 640, 480);
    

    The ListView is therefore wider than the scene, so not all of it can be displayed. Since you tell the VBox containing the ListView to center its content:

    <VBox id="primary" alignment="TOP_CENTER" ...>
    

    the text in the cells in the list view, which is left-aligned by default in those cells, is off-screen to the left.

    If you expand the window (stretching the scene) you will actually see it is working just fine:

    enter image description here

    As mentioned: it is never a good idea to hard-code sizes. Just remove all those hard-coded sizes from the 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.layout.VBox?>
    
    <VBox id="primary" alignment="TOP_CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jamesd.examples.list.PrimaryController">
        <children>
            <Label text="Primary View" />
            <ListView id="theList" fx:id="theList">
                <VBox.margin>
                    <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
                </VBox.margin>
                <padding>
                    <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
                </padding>
            </ListView>
        </children>
        <padding>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
        </padding>
    </VBox>