JavaFX Bild leer und keine Fehlermeldung

ve987

Aktives Mitglied
Hallo,

ich versuche ein erstes kleines Projekt in JavaFX / Intellij zu erstellen.
Mein Problem ist, dass mein Bild nicht angezeigt wird. Sonst wird alles korrekt angezeigt (buttons, labels..).
Dort wo das Bild angezeigt werden soll, kommt ein leeres Feld.
Ich bekomme keine Fehlermeldung, so dass ich nicht weiss wohin 🙁

Den Ordner "Src/img" habe ich als resource folder hinzugefügt.

Das Bild befindet sich ebenso in out Ordner.

Kann mir bitte jmd behilflich sein? 🙂

Das ist die Main Klasse:

Java:
package sample;

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

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 650, 400));
        
        primaryStage.show();
    }

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

Das ist die Controller Klasse:

Java:
package sample;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller {
    @FXML
    public ImageView zdj;

    Image img;

    public Controller() {
        img = new Image(getClass().getResourceAsStream("/img/santa-mailbox.png"));
    }

public void displayImage() {
    zdj.setImage(img);
}

}

und die FXML Datei:
Java:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.text.Font?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <left>
      <AnchorPane prefHeight="400.0" prefWidth="281.0" BorderPane.alignment="CENTER">
         <children>
            <ImageView fitHeight="198.0" fitWidth="141.0" layoutX="82.0" layoutY="80.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@../../src/img/santa-mailbox.png" />
               </image>
            </ImageView>
         </children>
      </AnchorPane>
   </left>
   <right>
      <AnchorPane prefHeight="400.0" prefWidth="361.0" BorderPane.alignment="CENTER">
         <children>
            <Label layoutX="20.0" layoutY="126.0" text="Username">
               <font>
                  <Font name="System Bold" size="15.0" />
               </font>
            </Label>
            <TextField fx:id="username" layoutX="120.0" layoutY="124.0" prefHeight="25.0" prefWidth="197.0" promptText="username" />
            <Label layoutX="22.0" layoutY="161.0" text="Password">
               <font>
                  <Font name="System Bold" size="15.0" />
               </font>
            </Label>
            <PasswordField fx:id="password" layoutX="119.0" layoutY="159.0" prefHeight="25.0" prefWidth="199.0" promptText="password" />
            <Button fx:id="login" alignment="CENTER" layoutX="22.0" layoutY="264.0" mnemonicParsing="false" prefHeight="32.0" prefWidth="298.0" text="login" textAlignment="CENTER">
               <font>
                  <Font name="System Bold" size="15.0" />
               </font>
            </Button>
            <Button alignment="CENTER" layoutX="22.0" layoutY="308.0" mnemonicParsing="false" prefHeight="32.0" prefWidth="297.0" text="cancel">
               <font>
                  <Font name="System Bold" size="15.0" />
               </font>
            </Button>
            <Label layoutX="30.0" layoutY="49.0" prefHeight="36.0" prefWidth="281.0" text="Hello Santa, please login..." textFill="#c4302e">
               <font>
                  <Font name="System Bold" size="21.0" />
               </font>
            </Label>
            <Label layoutX="74.0" layoutY="218.0" text="invalid login, please try again" textFill="#f40303">
               <font>
                  <Font name="System Bold" size="14.0" />
               </font>
            </Label>
         </children>
      </AnchorPane>
   </right>
</BorderPane>
 
Irgendwie kein Wunder das man keinen fehler bekommt wenn man keine einzige fehlerabfrage oder ein Exception handling in seinem code hat
Aber dann müsste man die Exception, die geworfen wird, ja eigentlich beim Start auf der Kommandozeile sehen ...

Aber wenn man den Code anschaut, und
img = new Image(getClass().getResourceAsStream("/img/santa-mailbox.png")); soweit läuft (sprich: Controller Instanz kann erzeugt werden!), dann ist
<Image url="@../../src/img/santa-mailbox.png" /> falsch (und sieht auch extrem seltsam aus!)

Wenn das Bild als Ressource im Projekt ist (Also ggf. Eclipse Projekt und alles in src Ordner? Eclipse packt immer alles zusammen in einen Ordner.) und davon gehe ich aus wenn die Zeile in Controller funktioniert, dann wäre im fxml eher das erfolgreich:
<Image url="@/img/santa-mailbox.png" />
 
Aber dann müsste man die Exception, die geworfen wird, ja eigentlich beim Start auf der Kommandozeile sehen ...

Aber wenn man den Code anschaut, und
img = new Image(getClass().getResourceAsStream("/img/santa-mailbox.png")); soweit läuft (sprich: Controller Instanz kann erzeugt werden!), dann ist
<Image url="@../../src/img/santa-mailbox.png" /> falsch (und sieht auch extrem seltsam aus!)

Wenn das Bild als Ressource im Projekt ist (Also ggf. Eclipse Projekt und alles in src Ordner? Eclipse packt immer alles zusammen in einen Ordner.) und davon gehe ich aus wenn die Zeile in Controller funktioniert, dann wäre im fxml eher das erfolgreich:
<Image url="@/img/santa-mailbox.png" />
Ah jeah , habe zu <Image url="@/img/santa-mailbox.png" /> geändert und hat funktioniert 🙂 Vielen Dank!!!
 
Er sagt das er mit IntelliJ arbeitet.

Javafx "sollte" abstürzen wenn eine Ressource nicht gefunden wurde im Java Code.. also sollte es in der XML falsch sein

Java:
img = new Image(getClass().getResourceAsStream("/img/santa-mailbox.png"));
wenn man diese Zeile anschaut müsste von Controller/img/santa-mailbox.png etwas geladen worden sein -> Annahme dass es richtig gelaufen ist

Java:
<Image url="@../../src/img/santa-mailbox.png" />
wohin zielt dann dieser Pfad?
das ist ja in /src/img/santa... -> kann nicht stimmen wenn es oben funktioniert hat

und genauso umgekehrt ..einer muss falsch sein

oder man hat 2mal die Bild Datei das wäre schon mal das erste das nicht passt
 
@Mart
Der TE sagt ja das es mit dem nach der änferung von Kneizel geht.
Seine Ordner strucktur wird wol gleich zu Eclipse sein.

PS was hat dieser Satz mit meiner Aussage zu tun das er IJ benutzt?
Javafx "sollte" abstürzen wenn eine Ressource nicht gefunden wurde im Java Code.. also sollte es in der XML falsch sein

PS das Zietat sollte agr nicht in meinen Post sein ist zufällig dor hin gekommen wolte ich nicht.
 
@Mart
Der TE sagt ja das es mit dem nach der änferung von Kneizel geht.
Seine Ordner strucktur wird wol gleich zu Eclipse sein.

PS was hat dieser Satz mit meiner Aussage zu tun das er IJ benutzt?
es ist egal ob intelli j oder eclipse ...javafx stürzt bei nicht gefundenen Ressourcen innerhalb des Codes ab...deswegen konnte es auch nicht innerhalb gewesen sein egal welche exceptions kommen
 
es ist egal ob intelli j oder eclipse ...javafx stürzt bei nicht gefundenen Ressourcen innerhalb des Codes ab...deswegen konnte es auch nicht innerhalb gewesen sein egal welche exceptions kommen
Nein, JavaFX stürzt dann nicht ab. Und das Verhalten hat auch erst einmal nichts mit JavaFX zu tun.

getRessourceAsStream gibt null zurück, wenn die Ressource nicht gefunden wird. Also kein Absturz.
Und der Konstruktor von Image würde bei null eine NPE werfen. - Das würde ich auch nicht als Absturz bezeichnen. Eine Exception ist nicht gleichzusetzen mit einem Absturz (aus meiner Sicht).

Selbst die nicht behandelte Exception ist kein Absturz sondern ein Beenden des Programmes.
 
@kneitzel
nach einer InvocationTargetException oder welche man auch immer zusammen bringt ..vllt auch Illegal Argument Exception
läufts dann mit solche Exceptions weiter
Java:
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)....
und dann öffnet sich das Programm nicht mehr..ja schon es stürzt nicht ab wenn es sich nicht einmal öffnet
 
So erstmal vielen Dank für alle Antworten 🙂

So eine allgemeine Frage hätte ich noch:

Was ist besser:

Soll der Controller das Interface Initializable implementieren und in der initialize-Methode wird das ImageView initialisiert

ODER

das ImageView in einem Controller Kontruktor zu initialisieren?
 
Wenn Du deklarativ die Oberfläche erstellst, dann solltest Du sowas im FXML haben. wenn es da nicht geht, dann in der initialize Methode. Konstruktor ist quatsch, da zu dem Zeitpunkt noch nicht die Initialisierung vom FXMLLoader durchgelaufen ist. Und dazu muss übrigens kein Interface implementiert werden - Du brauchst also kein "implements Initializable" oder so.
 
Danke Euch beiden 🙂

Habe meine Controller Klasse angepasst.
Sieht das jetzt besser aus mit der initialize Methode?

Java:
package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable{
    
    @FXML
    private ImageView imageView;
    @FXML
    private Label wrongLogin;
    @FXML
    private TextField username;
    @FXML
    private PasswordField password;
    @FXML
    private Button login;


       @Override
     public void initialize(URL url, ResourceBundle resourceBundle) {
           Image image = new Image(getClass().getResourceAsStream("/img/santa-mailbox.png"));
           imageView= new ImageView(image);
        
               }

    public void userLogin(ActionEvent actionEvent) {
        checkLogin();
    }

    private void checkLogin() {
        if (username.getText().toString().equals("xxx") &&
                password.getText().toString().equals("1111")) {

            wrongLogin.setText("login successful");

        } else if (username.getText().isEmpty() || password.getText().isEmpty()){
            wrongLogin.setText("please enter your data");
        } else {
            wrongLogin.setText("wrong user or password");
        }
    }

    public void userCancel(ActionEvent actionEvent) {
    }




}
 
Der Code widerspricht sich:
Java:
    @FXML
    private ImageView imageView;
=> Da sagst Du ja, dass das Control aus dem FXML kommen soll. Der FXMLLoader soll Dir ja die Refrenz zu der erzeugten Instanz geben.

Java:
           imageView= new ImageView(image);
Hier erstellst Du eine neue Instanz. Das ist ansonsten auch komplett Scherzlos, denn das Control ist ja auch nirgends eingebunden - außer eben, dass Du die Referenz in einer Variablen hast. Dadurch wird die in keiner Weise angezeigt oder so.

Hat denn das Anzeigen des Bildes rein mit der FXML Datei nicht geklappt?
 
Hat denn das Anzeigen des Bildes rein mit der FXML Datei nicht geklappt?
Ich habe jetzt die initialise - Methode gelöscht und es hat tatsächlich geklappt 😀 Das Bild wird angezeigt.

Blöde Frage (Sorry bin Anfänger 😉 ) Der Controller zieht sich also den Pfad aus FXML Datei mittels @FXML ? Und das reicht völlig aus?
 
Andere Frage: Könnt Ihr mir bitte ein JavaFX Tutorial empfehlen?
Es kann auch gerne auf Englisch sein.
Ich gucke mir Tutorials auf Youtube an, aber bin nicht so zufrieden mit denen, die ich gefunden habe.
 
Nein, der FXMLLoader lädt die fxml Datei und erzeugt ein entsprechendes Konstrukt.
Wenn da ein Controller angegeben wird, so wird auch der Controller erzeugt.
Bei einem Controller wird nach der Erzeugung der Controller analysiert: @FXML Annotations bei Variablen sorgen dafür, dass nach einer fx:id mit gleichem Namen geschaut wird. (Das gleich passiert auch mit non private Feldern!)
 
Nein, der FXMLLoader lädt die fxml Datei und erzeugt ein entsprechendes Konstrukt.
Wenn da ein Controller angegeben wird, so wird auch der Controller erzeugt.
Bei einem Controller wird nach der Erzeugung der Controller analysiert: @FXML Annotations bei Variablen sorgen dafür, dass nach einer fx:id mit gleichem Namen geschaut wird. (Das gleich passiert auch mit non private Feldern!)
Ahhh jetzt ist es etwas klarer geworden, danke für die Erklärung 🙂
 

Neue Themen


Zurück
Oben