Programm lädt nur den Hintergrund (RootLayer)

Schnörz

Mitglied
Hallo zusammen

Ich bin neu im Forum und ein absoluter Java Beginner und weiss auch nicht genau wie ich mein Problem Beschreiben soll.
Nutzen tu ich Java mit Eclipse und Scene Builder unter Windows 10.
Jedenfalls möchte ich ein Programm schreiben, bei dem man einige Lebensmittel eingeben kann.
Dazu habe ich drei Packages erstellet, einmal mit einer Main Class, einer Model Class und einem Controller. Ich arbeite zudem mit Scene Builder und habe zwei fxml Dateien einmal den Layer und einmal die Übersicht. Wenn ich das Programm ausführen will, lädt leider nur der Root Layer.
Im Code selbst habe ich eigentlich keine Fehlermeldungen mehr ausser folgendem
Java:
[/B]
package rb.notvorrat.view;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import rb.notvorrat.Main;
import rb.notvorrat.model.Lebensmittel;

public class LebensmittelOverviewController {
    @FXML
    private TableView<Lebensmittel> LebensmittelTable;
    @FXML
    private TableColumn<Lebensmittel, String> NameColumn;
    @FXML
    private TableColumn<Lebensmittel, String> BeschreibungColumn;

    @FXML
    private Label NameLabel;
    @FXML
    private Label BeschreibungLabel;
    @FXML
    private Label AblaufdatumLabel;
    @FXML
    private Label AnzahlLabel;


  [I] [B] // Reference to the main application.
    private Main Main;[/B][/I]

    /**
     * The constructor.
     * The constructor is called before the initialize() method.
     */
    public LebensmittelOverviewController() {
    }

    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        // Initialize the person table with the two columns.
        NameColumn.setCellValueFactory(cellData -> cellData.getValue().NameProperty());
        BeschreibungColumn.setCellValueFactory(cellData -> cellData.getValue().BeschreibungProperty());
    }

    /**
     * Is called by the main application to give a reference back to itself.
     * 
     * @param Main
     */
    public void setMain(Main Main) {
        this.Main = Main;

        // Add observable list data to the table
        LebensmittelTable.setItems(Main.getLebensmittelData());
    }
}

Beim Kursiv geschriebenen kommt noch folgende Info The value of the field LebensmittelOverviewController.Main is not used das sollte eigentlich mit der Main verbunden sein.

Nun in der Konsole kommen jedoch ein ganzer Haufen von Fehler vor, zumindest hat es den Anschein.

Juli 05, 2021 8:55:11 AM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 16 by JavaFX runtime of version 11.0.2
Juli 05, 2021 8:55:12 AM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 16 by JavaFX runtime of version 11.0.2
javafx.fxml.LoadException:
/C:/Users/User/Desktop/Java/Workspace/Notvorrat_Beta/target/classes/rb/notvorrat/view/PersonUbersicht.fxml:46

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at rb.notvorrat.Main.showPersonUbersicht(Main.java:87)
at rb.notvorrat.Main.start(Main.java:57)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: java.lang.IllegalArgumentException: Can not set javafx.scene.control.TableView field rb.notvorrat.view.LebensmittelOverviewController.LebensmittelTable to javafx.scene.layout.GridPane
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.base/java.lang.reflect.Field.set(Field.java:793)
at javafx.fxml/javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1174)
at javafx.fxml/javafx.fxml.FXMLLoader.access$1600(FXMLLoader.java:105)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:865)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:759)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
... 13 more


Ich hoffe das ist einigermassen gut beschrieben.
Wäre toll wenn mir jemand helfen könnte.

Viele Grüsse
Schnörz
 
K

kneitzel

Gast
Dann zeig auch mal die PersonUebersicht.fxml und sag auch, was die Zeile 46 ist ... da hat er Probleme ...

Ansonsten hast du javafx 16 verwendet zur Erstellung aber nutzt dann javafx 11 zum ausführen. Das kann, aber muss nicht zu Problemen führen (in deinem Fall ist dies aber evtl. die Ursache - das kann man genauer sagen, wenn man das fxml sieht).
 

Schnörz

Mitglied
Hallo kneitzel
Danke für die Antwort.

Bei der Zeile 46 habe ich die Spalte mit der jeweiligen fix id (NameColumn) und (BeschreibungColumn) Verknüpft.
Ich weiss aber nicht ob das notwendig ist und was es überhaupt ist. Das Programm ist ein Nachbau einer Namensverwaltung die hat noch zwei Spalten mit Name und Nachname. Eventuell kann ich die Zeilen löschen, denn das gibt es in meinem Programm gar nicht so wie beim Beispiel.

Hier mal die PersonUebersicht:

Java:
[/B]
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="rb.notvorrat.view.LebensmittelOverviewController">
   <children>
      <ImageView fitHeight="150.0" fitWidth="200.0" layoutX="899.0" layoutY="45.0" pickOnBounds="true" preserveRatio="true" />
      <ImageView fitHeight="296.0" fitWidth="360.0" layoutX="840.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@../../../../../../../Der%20empfohlene%20Notvorrat.PNG" />
         </image>
      </ImageView>
      <GridPane layoutX="24.0" layoutY="116.0">
         <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="126.0" minWidth="10.0" prefWidth="126.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="74.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints maxHeight="60.0" minHeight="10.0" prefHeight="28.0" vgrow="SOMETIMES" />
         </rowConstraints>
         <children>
            <Label text="Anzahl Erwachsene" />
            <Label text="Anzahl Kinder" GridPane.rowIndex="1" />
            <Label text="Label" GridPane.columnIndex="1" />
            <Label layoutX="10.0" layoutY="20.0" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
         </children>
      </GridPane>
      <Label layoutX="24.0" layoutY="86.0" text="Haushalt:" underline="true" />
      <Label layoutX="24.0" layoutY="24.0" text="Notvorratmanager" underline="true">
         <font>
            <Font name="Times New Roman" size="18.0" />
         </font>
      </Label>
      <Label layoutX="24.0" layoutY="200.0" text="Lebensmittelvorrat:" underline="true" />
      <GridPane fx:id="LebensmittelTable" layoutX="24.0" layoutY="229.0">
         <columnConstraints>
            <ColumnConstraints fx:id="NameColumn" hgrow="SOMETIMES" maxWidth="107.0" minWidth="10.0" prefWidth="107.0" />
            <ColumnConstraints fx:id="BeschreibungColumn" hgrow="SOMETIMES" maxWidth="102.0" minWidth="10.0" prefWidth="102.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="91.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" 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 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>
            <Label text="Name" />
            <Label text="Beschreibung" GridPane.columnIndex="1" />
            <Label text="Ablaufdatum" GridPane.columnIndex="2" />
            <Label text="Anzahl" GridPane.columnIndex="3" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="1" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="2" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="3" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="4" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="5" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="6" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="7" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="8" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="9" />
            <ChoiceBox prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="10" />
            <Label text="kJ" GridPane.columnIndex="5" />
            <Label fx:id="NameLabel" text="Label" GridPane.rowIndex="1" />
            <Label fx:id="BeschreibungLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <Label fx:id="AblaufdatumLabel" text="Label" GridPane.columnIndex="2" GridPane.rowIndex="1" />
            <Label fx:id="AnzahlLabel" text="Label" GridPane.columnIndex="3" GridPane.rowIndex="1" />
            <Label text="Label" GridPane.columnIndex="5" GridPane.rowIndex="1" />
         </children>
      </GridPane>
      <ButtonBar layoutX="23.0" layoutY="591.0" prefHeight="40.0" prefWidth="200.0">
         <buttons>
            <Button mnemonicParsing="false" text="New.." />
            <Button mnemonicParsing="false" text="Edit.." />
            <Button mnemonicParsing="false" text="Delete" />
         </buttons>
      </ButtonBar>
      <Label layoutX="420.0" layoutY="209.0" text="Kategorie" />
   </children>
</AnchorPane>
[B]
 
K

kneitzel

Gast
Ach, ich hatte beim Stacktrace nicht gut genug geschaut. Das Kernproblem ist ja:

Caused by: java.lang.IllegalArgumentException: Can not set javafx.scene.control.TableView field rb.notvorrat.view.LebensmittelOverviewController.LebensmittelTable to javafx.scene.layout.GridPane

Du hast im Controller:
Java:
    @FXML
    private TableView<Lebensmittel> LebensmittelTable;

und im fxml:
Java:
      <GridPane fx:id="LebensmittelTable" layoutX="24.0" layoutY="229.0">

Eine GridPane Instanz kann natürlich nicht in einer Variable vom Typ TableView gespeichert werden. Und genau das sagt die Meldung ja auch aus.
 
K

kneitzel

Gast
Das sind doch zwei unterschiedliche Controls. Die Frage ist doch einfach, was Du genau machen willst. In der Regel baust Du doch die UI deklarativ mit SceneBuilder auf (mit dem Controller). Wenn Du nun innerhalb des Controllers Zugriff auf Elemente der UI brauchst, dann fügst Du die entsprechend mit @FXML zu und dann hast Du Zugriff drauf. Aber natürlich nur auf die Funktionen, die da drin stehen. Also kein setItems, das Du aufrufst.

Und der Controller sollte wenn möglich ach keine Controlls kennen müssen. Es sollte einfach gewisse Dinge bereit stellen und die UI kann dann darauf zugreifen in Form von Bindings (Das haut leider nicht 100% hin - Bidirektionale Bindings gehen nur im Code. Ein Grund, warum MVC Schrott ist und ich MVVM bevorzuge. Aber das ändert nichts an Deiner Problematik.

Also: Bau eine Oberfläche auf, die die Funktionalität hat, die du brauchst. Dann kannst Du die Funktionalität auch im Controller ansprechen. Aber dir en Auto vors Haus zu stellen (fxml) und dann (controller) zu sagen: Ich stelle mir vor, das sei ein Flugzeug und nun fliege ich los -> Das haut nicht hin.
 

Schnörz

Mitglied
oHH es hat zum ersten mal richtig aufgemacht.
1625510793650.png

Leider geht jetzt noch nichts, dachte hatte die Labels gesetzt.
Ich arbeite mal dran. Wäre toll wenn ich später noch auf dich zukommen könnte. Danke vielmals
 

Schnörz

Mitglied
Hallo zusammen kurze Frage:
Gibt es eine Möglichkeit Projekte an einem bestimmten Punkt zwischen zu speichern?
Z.b. Ich bin gerade an einem guten Punkt angelangt, mache dann weiter versaue das ganze Projekt. Anstatt neu anfangen beim letzten Speicherunkt einsteigen.
Danke vielmals
 

LimDul

Top Contributor
Die einfachste - alles regelmäßig in eine ZIP-Datei packen und irgendwo ablegen.

Die sauberste, ein Versionskontrollsystem wie GIT verwenden. Das ist aber etwas aufwendiger einzurichten und zu verstehen, aber eigentlich so wie man es in der Praxis macht.
 

mihe7

Top Contributor
Danke LimDul.
Also das wäre dann im Workspace das entsprechende Projekt, rauskopieren und zwischenspeichern korrekt?
Ohne scheiß: wurschtel nicht mit irgendwelchen Kopien rum. Das machst Du ein paar Mal, dann vergisst Du es mal, überschreibst Dir irgendwas oder es passiert sonst irgendein Blödsinn und in zwei Wochen weißt Du nicht mehr, was nun Sache ist.

Nimm git, auch wenn Du Dich da erstmal ein wenig einlesen musst.
 

Schnörz

Mitglied
Danke vielmals für die Nachrichten ich werde mich mal mit GIT auseinandersetzten und danke für das Tutorial.

Ich habe mein Tool nun weiter versucht zu Programmieren und bin an einem Punkt an dem eigentlich Daten ersichtlich sein müssten.
Es ist eine Controller vorhanden und die entsprechenden Labels, Columns usw. sollten im Scene Builder verknüpft sein.
Im Code steht auch kein Fehler "nur" eine Hinweislampe oder sowas.
Jedenfalls startet das Tool, aber es ist nicht befüllt.
Wüsste da jemand Bescheid?
Eventuell hilft die Controller Class:

Java:
package rb.notvorrat.view;


import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import rb.notvorrat.Main;
import rb.notvorrat.model.Lebensmittel;
import rb.notvorrat.util.DateUtil;

public class LebensmittelOverviewController {
    @FXML
    private TableView<Lebensmittel> lebensmittelTable;
    @FXML
    private TableColumn<Lebensmittel, String> nameColumn;
    @FXML
    private TableColumn<Lebensmittel, String> beschreibungColumn;

    @FXML
    private Label nameLabel;
    @FXML
    private Label beschreibungLabel;
    @FXML
    private Label anzahlLabel;
    @FXML
    private Label ablaufdatumLabel;
    @FXML
    private Label kalorienLabel;
    @FXML
    private Label preisinCHFLabel;

    // Reference to the main application.
    private Main main;

    /**
     * The constructor.
     * The constructor is called before the initialize() method.
     */
    public LebensmittelOverviewController() {
    }

    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        // Initialize the person table with the two columns.
        nameColumn.setCellValueFactory(
                cellData -> cellData.getValue().nameProperty());
        beschreibungColumn.setCellValueFactory(
                cellData -> cellData.getValue().beschreibungProperty());
        
        // Clear person details.
        showLebensmittelDetails(null);

        // Listen for selection changes and show the person details when changed.
        lebensmittelTable.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> showLebensmittelDetails(newValue));
    }

    /**
     * Is called by the main application to give a reference back to itself.
     * 
     * @param main
     */
    public void setMain(Main main) {
        this.main = main;
    }
        /**
         * Fills all text fields to show details about the person.
         * If the specified person is null, all text fields are cleared.
         * 
         * @param person the person or null
         */
        private void showLebensmittelDetails(Lebensmittel lebensmittel) {
            if (lebensmittel != null) {
                // Fill the labels with info from the person object.
                nameLabel.setText(lebensmittel.getname());
                beschreibungLabel.setText(lebensmittel.getbeschreibung());
                anzahlLabel.setText(Integer.toString(lebensmittel.getanzahl()));
                kalorienLabel.setText(Integer.toString(lebensmittel.getkalorien()));
                preisinCHFLabel.setText(Integer.toString(lebensmittel.getpreisinCHF()));

                // birthdayLabel.setText(...);
                ablaufdatumLabel.setText(DateUtil.format(lebensmittel.getablaufdatum()));
            } else {
                // Person is null, remove all the text.
                nameLabel.setText("");
                beschreibungLabel.setText("");
                ablaufdatumLabel.setText("");
                anzahlLabel.setText("");
                kalorienLabel.setText("");
                preisinCHFLabel.setText("");
               
            }
    }
}

Grüsse
Schnörz
 
Zuletzt bearbeitet:

Schnörz

Mitglied
Hallo wollte nochmals nachfragen ob mir hier jemand helfen könnte.
Bin ziemlich weit gekommen bei Programm. Leider wird aber der Inhalt beim TableView in den zwei Column's nicht erkannt. Habe dort eigentlich Sample Data eingefügt. Es bleibt aber immer leer??
1626286848577.png
 

Schnörz

Mitglied
Hier noch ein kleines Update. Problem soeben gelöst.
Habe die Observable List nicht an den Table gehängt.
lebensmittelTable.setItems(main.getLebensmittelData());
 

Neue Themen


Oben