JavaFX cannot load image from resource folder

309 views Asked by At

I have been working on a JavaFX project with Maven. I am using JDK 14 with IntelliJ IDE to compile my project into a JAR artifact.

I have linked the CSS files into FXML through Scene Builder. The CSS files contain necessary background image information.

The program runs perfectly inside the IDE. But it is showing the following error when I run as a JAR.

Error loading image: jar:file:/C:/Users/Sajed/Desktop/GitHub/IFTAS/out/artifacts/IFTAS_jar/IFTAS.jar!/tgtList/main.jpg

My project structure is like the following:

src  
  -main  
    -java  
      -tgtList
        -Java File
    -resources
      -tgtList
        -FXML file
        -main.jpg
        -backgorund.css

Can someone point me out the possible areas I should be concerned with?

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.sajed</groupId>
    <artifactId>IFTA</artifactId>
    <version>1.0.0.0</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>14</maven.compiler.source>
        <maven.compiler.target>14</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.jfoenix/jfoenix -->
        <dependency>
            <groupId>com.jfoenix</groupId>
            <artifactId>jfoenix</artifactId>
            <version>9.0.10</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.32.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itext7-core -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.1.13</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx</artifactId>
            <version>16-ea+4</version>
            <type>pom</type>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>16-ea+4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>16-ea+4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-graphics -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>16-ea+4</version>
        </dependency>
    </dependencies>

</project>

background.css

.mainbg{
   -fx-background-image: url('main.jpg');
   -fx-background-size: 100% 100%;    
}

Tgt.fxml:

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

<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXComboBox?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="600.0" minWidth="800.0" styleClass="mainbg" stylesheets="@background.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tgtList.TgtController">
    <center>
        <TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
            <columns>
                <TableColumn fx:id="id" prefWidth="50.0" text="Id" visible="false" />
                <TableColumn fx:id="ser" prefWidth="50.0" text="Ser" />
                <TableColumn fx:id="tgtName" prefWidth="190.0" text="Name" />
                <TableColumn fx:id="tgtSize" prefWidth="150.0" text="Size" />
                <TableColumn fx:id="tgtPosture" prefWidth="180.0" text="Posture" />
                <TableColumn fx:id="terr" prefWidth="115.0" text="Terr" />
            </columns>
        </TableView>
    </center>
    <top>
        <GridPane BorderPane.alignment="CENTER">
            <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            </columnConstraints>
            <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            </rowConstraints>
            <children>
                <JFXComboBox fx:id="fieldTgtSize" promptText="Select" GridPane.columnIndex="3" GridPane.rowIndex="2" />
                <Label text="Tgt Size" GridPane.columnIndex="2" GridPane.rowIndex="2">
                    <GridPane.margin>
                        <Insets left="20.0" />
                    </GridPane.margin>
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </Label>
                <Label alignment="CENTER" contentDisplay="CENTER" text="TGT ASSESSMENT" underline="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.halignment="CENTER">
                    <font>
                        <Font name="System Bold" size="18.0" />
                    </font>
                </Label>
                <JFXButton fx:id="add" buttonType="RAISED" onAction="#add" style="-fx-background-color: green;" text="Add" textFill="WHITE" GridPane.columnIndex="2" GridPane.rowIndex="6">
                    <GridPane.margin>
                        <Insets left="20.0" />
                    </GridPane.margin>
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </JFXButton>
                <Label text="Posture" GridPane.rowIndex="4">
                    <GridPane.margin>
                        <Insets left="20.0" />
                    </GridPane.margin>
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </Label>
                <JFXComboBox fx:id="fieldPosture" focusColor="#4ca128" promptText="Select" GridPane.columnIndex="1" GridPane.rowIndex="4" />
                <Label text="Tgt Name" GridPane.rowIndex="2">
                    <GridPane.margin>
                        <Insets left="20.0" />
                    </GridPane.margin>
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </Label>
                <JFXTextField fx:id="fieldTgtName" focusColor="#4ca128" promptText="Write Tgt Name" GridPane.columnIndex="1" GridPane.rowIndex="2">
                    <GridPane.margin>
                        <Insets right="30.0" />
                    </GridPane.margin>
                </JFXTextField>
                <Label text="Terr" GridPane.columnIndex="2" GridPane.rowIndex="4">
                    <GridPane.margin>
                        <Insets left="20.0" />
                    </GridPane.margin>
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </Label>
                <JFXComboBox fx:id="fieldTerr" focusColor="#4ca128" promptText="Select" GridPane.columnIndex="3" GridPane.rowIndex="4" />
                <JFXButton fx:id="delete" buttonType="RAISED" onAction="#deleteFromDb" style="-fx-background-color: red;" text="Delete" textFill="WHITE" GridPane.columnIndex="3" GridPane.rowIndex="6">
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </JFXButton>
            </children>
        </GridPane>
    </top>
</BorderPane>

TgtController.java

package tgtList;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXTextField;
import constants.IConstants;
import database.TgtDB;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import model.TgtModel;

import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Collectors;

public class TgtController implements Initializable {

    private static final TgtDB tgtDb = new TgtDB();
    ObservableList<TgtModel> obs = FXCollections.observableArrayList();
    @FXML
    TableView<TgtModel> tableView;
    @FXML
    TableColumn<TgtModel, String> id = new TableColumn<>();
    @FXML
    TableColumn<TgtModel, String> ser = new TableColumn<>();
    @FXML
    TableColumn<TgtModel, String> tgtName = new TableColumn<>();
    @FXML
    TableColumn<TgtModel, String> tgtSize = new TableColumn<>();
    @FXML
    TableColumn<TgtModel, String> tgtPosture = new TableColumn<>();
    @FXML
    TableColumn<TgtModel, String> terr = new TableColumn<>();

    @FXML
    JFXTextField fieldTgtName = new JFXTextField();
    @FXML
    JFXComboBox<Label> fieldTgtSize = new JFXComboBox<>();
    @FXML
    JFXComboBox<Label> fieldPosture = new JFXComboBox<>();
    @FXML
    JFXComboBox<Label> fieldTerr = new JFXComboBox<>();

    @FXML
    JFXButton add;
    @FXML
    JFXButton delete;

    private static void getErrorPopUp() {

        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setHeaderText("Duplicate Tgt Name");
        alert.showAndWait();
    }

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

        fieldTgtSize.getItems().addAll(Arrays.stream(IConstants.tgtSizeList).map(Label::new).collect(Collectors.toList()));
        fieldPosture.getItems().addAll(Arrays.stream(IConstants.postureList).map(Label::new).collect(Collectors.toList()));
        fieldTerr.getItems().addAll(Arrays.stream(IConstants.terrList).map(Label::new).collect(Collectors.toList()));

        loadDB();
        tableView.setItems(obs);

        //System.out.println( obs );

        ser.setCellValueFactory(cellData -> cellData.getValue().ser());
        id.setCellValueFactory(cellData -> cellData.getValue().id());
        tgtName.setCellValueFactory(cellData -> cellData.getValue().tgtName());
        tgtName.setCellFactory(TextFieldTableCell.forTableColumn());
        tgtName.setOnEditCommit(
                (TableColumn.CellEditEvent<TgtModel, String> t) -> {

                    if (!t.getNewValue().trim().equals("")) {
                        t.getTableView().getItems().get(
                                t.getTablePosition().getRow()).setTgtName(t.getNewValue());
                        updateDB();
                    }
                    loadDB();
                });

        tgtSize.setCellValueFactory(cellData -> cellData.getValue().tgtSize());
        tgtSize.setCellFactory(ComboBoxTableCell.forTableColumn(IConstants.tgtSizeList));
        tgtSize.setOnEditCommit(
                (TableColumn.CellEditEvent<TgtModel, String> t) -> {
                    if (!t.getNewValue().trim().equals("")) {
                        t.getTableView().getItems().get(
                                t.getTablePosition().getRow()).setTgtSize(t.getNewValue());
                        updateDB();
                    }
                    loadDB();
                });

        tgtPosture.setCellValueFactory(cellData -> cellData.getValue().tgtPosture());
        tgtPosture.setCellFactory(ComboBoxTableCell.forTableColumn(IConstants.postureList));
        tgtPosture.setOnEditCommit(
                (TableColumn.CellEditEvent<TgtModel, String> t) -> {
                    if (!t.getNewValue().trim().equals("")) {
                        t.getTableView().getItems().get(
                                t.getTablePosition().getRow()).setTgtPosture(t.getNewValue());
                        updateDB();
                    }
                    loadDB();
                });

        terr.setCellValueFactory(cellData -> cellData.getValue().terr());
        terr.setCellFactory(ComboBoxTableCell.forTableColumn(IConstants.terrList));
        terr.setOnEditCommit(
                (TableColumn.CellEditEvent<TgtModel, String> t) -> {
                    if (!t.getNewValue().trim().equals("")) {
                        t.getTableView().getItems().get(
                                t.getTablePosition().getRow()).setTerr(t.getNewValue());
                        updateDB();
                    }
                    loadDB();
                });

        setTableEditable();
    }

    private void setTableEditable() {
        tableView.setEditable(true);
        tableView.getSelectionModel().cellSelectionEnabledProperty().set(true);
        tableView.setOnKeyPressed(event -> {
            if (event.getCode().isLetterKey() || event.getCode().isDigitKey()) {
                editFocusedCell();
            } else if (event.getCode() == KeyCode.RIGHT
                    || event.getCode() == KeyCode.TAB) {
                tableView.getSelectionModel().selectNext();
                event.consume();
            } else if (event.getCode() == KeyCode.LEFT) {
                tableView.getSelectionModel().selectPrevious();
                event.consume();
            }
        });
    }

    @SuppressWarnings("unchecked")
    private void editFocusedCell() {
        final TablePosition<TgtModel, ?> focusedCell = tableView
                .focusModelProperty().get().focusedCellProperty().get();
        tableView.edit(focusedCell.getRow(), focusedCell.getTableColumn());
    }

    @FXML
    private void add() {
        Set<String> nameSet = obs.stream().map(s -> s.tgtName().getValue()).collect(Collectors.toSet());
        System.out.println(nameSet);
        if (nameSet.contains(fieldTgtName.getText().trim())) {
            getErrorPopUp();
            return;
        }
        if (fieldTgtName.getText().trim().equals("")) return;
        if (fieldTgtSize.getValue() == null || fieldTgtSize.getValue().getText().trim().equals("")) return;
        if (fieldPosture.getValue() == null || fieldPosture.getValue().getText().trim().equals("")) return;
        if (fieldTerr.getValue() == null || fieldTerr.getValue().getText().trim().equals("")) return;

        TgtModel temp = new TgtModel(fieldTgtName.getText().trim(), fieldTgtSize.getValue().getText().trim(),
                fieldPosture.getValue().getText().trim(),
                fieldTerr.getValue().getText().trim());

        tgtDb.addTgt(temp);
        loadDB();

        fieldTgtName.clear();
        fieldTgtSize.getSelectionModel().clearSelection();
        fieldPosture.getSelectionModel().clearSelection();
        fieldTerr.getSelectionModel().clearSelection();
    }

    private void loadDB() {
        obs.clear();
        obs.addAll(tgtDb.tgtList());
    }

    private void updateDB() {
        tgtDb.UpdateDb(obs);
    }

    @FXML
    private void deleteFromDb() {

        TgtModel tgt = tableView.getSelectionModel().getSelectedItem();
        if (tgt == null) return;
        tableView.getItems().removeAll(tableView.getSelectionModel().getSelectedItems());

        tgtDb.deleteFromDb(tgt);
        updateDB();
    }
}
0

There are 0 answers