Search code examples
javajavafxfxml

Instantiation and Load exception when trying to use an extended version of AnchorPane


For a project i was given code and had to refactor it into FXML, I'm trying to use a piece of code i was given which is an extension of AnchorPane but when i switch it from AnchorPane to World in my FXML i get an error in the Scene Builder and when i run it. I've tried a lot of stuff and just kind of stumped and don't know what to try now. I commented out the original constructor for World but can post it if it might be relevant

World:

package game;


import javafx.animation.AnimationTimer;
import javafx.scene.Node;
import javafx.scene.layout.AnchorPane;

import java.util.ArrayList;
import java.util.List;


public abstract class World extends AnchorPane {
    private AnimationTimer timer;

public void createTimer() {
        timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                act(now);
                List<Actor> actors = getObjects(Actor.class);

                for (Actor anActor: actors) {
                    anActor.act(now);
                }

            }
        };
    }

    public void start() {
        createTimer();
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

    public void add(Actor actor) {
        getChildren().add(actor);
    }

    public void remove(Actor actor) {
        getChildren().remove(actor);
    }

    public <A extends Actor> List<A> getObjects(Class<A> cls) {
        ArrayList<A> someArray = new ArrayList<A>();
        for (Node n: getChildren()) {
            if (cls.isInstance(n)) {
                someArray.add((A)n);
            }
        }
        return someArray;
    }

    public abstract void act(long now);
}

FXML

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


<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>


<?import game.End?>
<?import game.Log?>
<?import game.WetTurtle?>
<?import game.Turtle?>
<?import game.Obstacle?>
<?import game.World?>

<World maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
       prefHeight="800.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal"
       xmlns:fx="http://javafx.com/fxml/1" fx:controller="game.Level1Controller">

   <ImageView>
      <image>
         <Image url="@../backgrounds/frogbg.png" />
      </image>
   </ImageView>
   <End layoutX="13.0" layoutY="138.8">
      <image>
         <Image url="@../end/End.png" />
      </image></End>
   <End layoutX="141.0" layoutY="138.0">
      <image>
         <Image url="@../end/End.png" />
      </image>
   </End>
   <End layoutX="269.0" layoutY="138.0">
      <image>
         <Image url="@../end/End.png" />
      </image>
   </End>
   <End layoutX="398.0" layoutY="138.0">
      <image>
         <Image url="@../end/End.png" />
      </image>
   </End>
   <End layoutX="528.0" layoutY="138.0">
      <image>
         <Image url="@../end/End.png" />
      </image>
   </End>
   <Log fitHeight="30.0" layoutY="209.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/log3.png" />
      </image>
   </Log>
   <Log fitHeight="30.0" layoutX="220.0" layoutY="209.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/log3.png" />
      </image>
   </Log>
   <Log fitHeight="30.0" layoutX="440.0" layoutY="209.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/log3.png" />
      </image>
   </Log>
   <WetTurtle fitHeight="45.0" layoutX="600.0" layoutY="252.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image>
   </WetTurtle>
   <WetTurtle fitHeight="45.0" layoutX="400.0" layoutY="252.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image>
   </WetTurtle>
   <WetTurtle fitHeight="45.0" layoutX="200.0" layoutY="252.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image>
   </WetTurtle>
   <Log fitHeight="35.0" layoutY="308.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/logs.png" />
      </image>
   </Log>
   <Log fitHeight="35.0" layoutX="440.0" layoutY="308.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/logs.png" />
      </image>
   </Log>
   <Log fitHeight="35.0" layoutX="50.0" layoutY="358.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/log3.png" />
      </image>
   </Log>
    <Log fitHeight="35.0" layoutX="270.0" layoutY="358.0" pickOnBounds="true" preserveRatio="true">
        <image>
            <Image url="@../log/log3.png" />
        </image>
    </Log>
   <Log fitHeight="35.0" layoutX="490.0" layoutY="358.0" pickOnBounds="true" preserveRatio="true">
      <image>
         <Image url="@../log/log3.png" />
      </image>
   </Log>
   <Turtle fitHeight="45.0" layoutX="500.0" layoutY="402.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image></Turtle>
   <Turtle fitHeight="45.0" layoutX="300.0" layoutY="402.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image>
   </Turtle>

   <WetTurtle fitHeight="45.0" layoutX="700.0" layoutY="402.0" preserveRatio="true">
      <image>
         <Image url="@../turtle/TurtleAnimation1.png" />
      </image>
   </WetTurtle>
   <Obstacle fitHeight="28.0" layoutX="500.0" layoutY="511.0" preserveRatio="true">
      <image>
         <Image url="@../car/car1Left.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="35.0" layoutX="500.0" layoutY="557.0" preserveRatio="true">
      <image>
         <Image url="@../truck/truck2Right.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="35.0" layoutY="557.0" preserveRatio="true">
      <image>
         <Image url="@../truck/truck2Right.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="28.0" layoutX="550.0" layoutY="611.0" preserveRatio="true">
      <image>
         <Image url="@../car/car1Left.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="28.0" layoutX="400.0" layoutY="611.0" preserveRatio="true">
      <image>
         <Image url="@../car/car1Left.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="28.0" layoutX="250.0" layoutY="611.0" preserveRatio="true">
      <image>
         <Image url="@../car/car1Left.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="28.0" layoutX="100.0" layoutY="611.0" preserveRatio="true">
      <image>
         <Image url="@../car/car1Left.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="35.0" layoutX="600.0" layoutY="657.0" preserveRatio="true">
      <image>
         <Image url="@../truck/truck1Right.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="35.0" layoutX="300.0" layoutY="657.0" preserveRatio="true">
      <image>
         <Image url="@../truck/truck1Right.png" />
      </image>
   </Obstacle>
   <Obstacle fitHeight="35.0" layoutY="657.0" preserveRatio="true">
      <image>
         <Image url="@../truck/truck1Right.png" />
      </image>
   </Obstacle>
</World>

Error

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javafx.fxml.LoadException: 
/C:/Users/harry/IdeaProjects/Frogger%20Game/out/production/Frogger%20Game/game/fxml/level1.fxml:16

    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml/javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:105)
    at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1021)
    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
    at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3129)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3122)
    at Frogger.Game/game.Main.start(Main.java:25)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
    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:175)
    ... 1 more
Caused by: java.lang.InstantiationException
    at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
    at java.base/java.lang.Class.newInstance(Class.java:560)
    at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1019)
    ... 20 more
Exception running application game.Main

Process finished with exit code 1

Solution

  • World is abstract, you can't construct an instance of an abstract class.

    When you declare an element:

    <World ...>
    

    in FXML, the FXMLLoader will try to create an instance of the World class when you load the FXML document. When it does so, it will fail because World is abstract and cannot be instantiated.

    You may have other additional issues in your code or design, but you have at least the one pointed out here.

    if i want to make an instance of it but it extend AnchorPane how do i go about that?

    You can't, your class hierarchy is already defined by your extends clause, unless you change the hierarchy design (e.g. recode World so it is not abstract), you have to instantiate a concrete subclass of World.

    I have another class that extends world that isn't abstract so i should use that instead i guess?

    Yes.