javajavafxinvocationtargetexception

JavaFx Exception in Application start method and Exception in Application start method


I have created this javaFx class to shuffle and show play cards in different angles. But Suddenly I got an error. I tried to fix it but I still couldn't able to make it work. Code explanation is given with the code below. The program supposes to pick random png card images and display on the first row. The second row shows three joker cards in different angles. The third row shows another three different cards in 3 different angles

The code:

import java.util.ArrayList;
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

//Creating class JavaFXCardGUI which is extending Application class
//Now JavaFXCardGUI class will act as an JavaFX Application
public class JavaFXCards extends Application{

   //Overriding start method of Application class which is always a starting point of any JavaFX Application
   @Override
   public void start(Stage stage) throws Exception {

       //Creating a VBox object
       VBox vBox=new VBox();
       //Setting its spacing and padding
       vBox.setSpacing(50);
       vBox.setPadding(new Insets(20, 40, 40, 60));

       //Creating a HBox object which will store the first row cards and setting its spacing property
       HBox firstRowHBox=new HBox();
       firstRowHBox.setSpacing(50);

       //Creating a HBox object which will store the second row cards and setting its spacing property
       HBox secondRowHBox=new HBox();
       secondRowHBox.setSpacing(50);

       //Creating a HBox object which will store the third row cards and setting its spacing property
       HBox thirdRowHBox=new HBox();
       thirdRowHBox.setSpacing(50);

       //Creating a arraylist of unique 52 cards which will store the each card number
       //If that card number will be already present in the arraylist then that card will not be added
       ArrayList<Integer> lstUnique52Cards=new ArrayList<Integer>();

       //Creating a random class object
       Random random=new Random();

      //This loop will add the three cards in first row
       while(lstUnique52Cards.size()<3) {
           //Generate a randomNumber between 1 and 52 both inclusive
           //Since random.NextInt(52) will return number from 0 to 51 Hence adding 1 to
           //make it from 1 to 52
           int randomNumber=random.nextInt(52)+1;

           //If the current random generated is not present in the array list lstUnique52Cards
           //it means that the random number is unique then add that random number in array list lstUnique52Cards
           //then create the correpsonding ImageView with the card number represented by randomNumber
           //Then add the image to the firstRowHBox
           if(!lstUnique52Cards.contains(randomNumber)) {
               lstUnique52Cards.add(randomNumber);
               ImageView imgViewCard=new ImageView(new Image("c:\\Users\\Desktop\\Tempory\\card"+randomNumber+".png"));
               firstRowHBox.getChildren().add(imgViewCard);
           }
       }

      //This loop will add the three joker cards in second row
       //Here the uniqueness doesn't matter for the card
       for(int i=1;i<=3;i++) {
           //Below statement random.nextInt(2) will generate two random numbers 0 and 1 only as we are having
           //only two joker cards. Since two joker cards images number are 53.png and 54.png.
           //Hence adding 53 to get that correpsonding joker card number
           int randomNumber=random.nextInt(2)+53;

           //Creating ImageView object with the given card number image
           ImageView imgViewCard=new ImageView(new Image("c:\\Users\\Desktop\\Tempory\\card"+randomNumber+".png"));

           //If the value of i is 1 i.e. it is first card then set the rotation angle as 45
           if(i==1)
               imgViewCard.setRotate(45);

           //If the value of i is 2 i.e. it is second card then set the rotation angle as 90
           if(i==2)
               imgViewCard.setRotate(90);

           //If the value of i is 3 i.e. it is third card then set the rotation angle as 135
           if(i==3)
               imgViewCard.setRotate(135);

           //Add the imgViewCard in secondRowHBox
           secondRowHBox.getChildren().add(imgViewCard);
       }

       //This loop will add the three more unique cards
       //Initializing cardNumber with 1
       int cardNumber=1;
       while(lstUnique52Cards.size()<6) {
           //Generate a randomNumber between 1 and 52 both inclusive
           //Since random.NextInt(52) will return number from 0 to 51 Hence adding 1 to
           //make it from 1 to 52
           int randomNumber=random.nextInt(52)+1;

           //If the current random generated is not present in the array list lstUnique52Cards
           //it means that the random number is unique then add that random number in array list lstUnique52Cards
           //then create the correpsonding ImageView with the card number represented by randomNumber
           //Also set the correpsonding angle to the cardNumber of this thirdRowHBox
           //Then add the image view card to the thirdRowHBox
           if(!lstUnique52Cards.contains(randomNumber)) {
               lstUnique52Cards.add(randomNumber);
               ImageView imgViewCard=new ImageView(new Image("c:\\Users\\Desktop\\Tempory\\card"+randomNumber+".png"));
               if(cardNumber==1)
                   imgViewCard.setRotate(135);
               if(cardNumber==2)
                   imgViewCard.setRotate(90);
               if(cardNumber==3)
                   imgViewCard.setRotate(45);
               thirdRowHBox.getChildren().add(imgViewCard);
               cardNumber++; //Increment cardNumber by 1
           }
       }

       //Add all the three HBox objects in the vBox
       vBox.getChildren().add(firstRowHBox);
       vBox.getChildren().add(secondRowHBox);
       vBox.getChildren().add(thirdRowHBox);

       //Create a scene object with the child as vBox
       Scene scene = new Scene(vBox ,450, 450);

       //Setting the stage title as Cards
       stage.setTitle("Cards");

       //Setting the scene to the stage
       stage.setScene(scene);

       //Showing the stage
       stage.show();
   }

   //Main method it will invoke start method of Application class
   public static void main(String[] args) {
       launch(args);
   }
}

The error:

ant -f c:\Users\Desktop\Tempory\card jfxsa-run
init:
Deleting: c:\Users\Desktop\Tempory\card\build\built-jar.properties
deps-jar:
Updating property file: c:\Users\Desktop\Tempory\card\build\built-jar.properties
compile:
Detected JavaFX Ant API version 1.3
jfx-deployment:
jar:
Copying 12 files to c:\Users\Desktop\Tempory\card\dist\run395293642
jfx-project-run:
Executing c:\Users\Desktop\Tempory\card\dist\run395293642\JavaFXCards.jar using platform C:\Program Files\Java\jdk1.8.0_221\jre/bin/java
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Invalid URL: unknown protocol: c
    at javafx.scene.image.Image.validateUrl(Image.java:1121)
    at javafx.scene.image.Image.<init>(Image.java:620)
    at JavaFXCardGUI.start(JavaFXCardGUI.java:58)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    ... 1 more
Caused by: java.net.MalformedURLException: unknown protocol: c
    at java.net.URL.<init>(URL.java:607)
    at java.net.URL.<init>(URL.java:497)
    at java.net.URL.<init>(URL.java:446)
    at javafx.scene.image.Image.validateUrl(Image.java:1115)
    ... 11 more
Exception running application JavaFXCardGUI
Java Result: 1
Deleting directory c:\Users\Desktop\Tempory\card\dist\run395293642
jfxsa-run:
BUILD SUCCESSFUL (total time: 2 seconds)

Solution

  • MalformedURLException - you provided a wrong URL string; all you need to do is prepend "file:" before the path to your image, like this - new Image("file:c:\\Users\\Desktop\\Tempory\\card"+randomNumber+".png"). Remember to always prefix local file paths with the file: protocol.