1

Everything was fine until I tried using HBox. now I get a long "Exception in Application constructor" error.

java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class Text_Processor
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:891)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
    at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:803)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    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:184)
    ... 1 more
Caused by: java.lang.NullPointerException: Children: child node is null: parent = HBox@4f9175a0
    at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:542)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:233)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.addAll(VetoableListDecorator.java:103)
    at javafx.graphics/javafx.scene.layout.HBox.<init>(HBox.java:251)
    at Text_Processor.<init>(Text_Processor.java:24)
    ... 14 more

Exception running application Text_Processor

import java.io.*;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.net.URL;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.util.Collections;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Text_Processor extends Application implements EventHandler<ActionEvent> {
    Button button, button2, button3;
    HBox hbox = new HBox(button, button2, button3);

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Word Analyzer");

        button = new Button();
        button.setText("Click First to Fetch The Raven Text");
        button.setOnAction(this);
        button2 = new Button();
        button2.setText("Click Here Next to parse the file");
        button2.setOnAction(this);
        button3 = new Button();
        button3.setText("Click Here Last to display results");
        button3.setOnAction(this);
        hbox.getChildren().addAll(button, button2, button3);

        Scene scene = new Scene(hbox, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void handle(ActionEvent event) {
        if (event.getSource() == button) ;
        {
            System.out.println("Fetching Text From Source https://www.gutenberg.org/files/1065/1065-h/1065-h.htm");
            URL url;
            try {
                url = new URL("https://www.gutenberg.org/files/1065/1065-h/1065-h.htm"); //Create object for URL.
                BufferedReader readr = new BufferedReader(new InputStreamReader(url.openStream())); //Open a reader to stream the file
                BufferedWriter writer = new BufferedWriter(new FileWriter("Test_Download.txt")); //Create file to store the downloaded info.
                String line;
                while ((line = readr.readLine()) != null) //Read the html source code from the website.
                {
                    writer.write(line); //Write the html code to a local file.
                }
                readr.close();
                writer.close();
            } catch
            (IOException e) {
                System.out.println("Error: " + e.getMessage());
                e.printStackTrace();
            }

        }

        if (event.getSource() == button2) ;
        {
            System.out.println("Parsing text of your downloaded file...");
            try {
                File input = new File("Test_Download.txt"); //Open the newly written file containing the HTML from The Raven.
                Document doc = Jsoup.parse(input, "UTF-8"); //Parse the file to eliminate the tags
                String body = doc.body().text(); //Save the parsed words to a string.
                BufferedWriter writer = new BufferedWriter(new FileWriter("Test_Download.txt"));//rewrite the file without the tags.
                writer.write(body);
                writer.close();
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
                e.printStackTrace();
            }

        }

        if (event.getSource() == button3) ;
        {
            try {
                File file = new File("Test_Download.txt"); //Open the file we have written for a word count analysis.
                Scanner sc = new Scanner(file); //Create a scanner to read the rewritten text file.
                int i = 0, indexOfWord = 0, count = 0;
                List<String> words = new ArrayList<String>(); //Create two arrays to store the words and word count.
                List<Integer> wordCount = new ArrayList<Integer>();

                while (sc.hasNext()) //Starting here we read each individual word of the file.
                {
                    String word = sc.next();
                    word = word.replaceAll("\\p{Punct}", " "); //This removes the punctuation and any non letters.;
                    if (words.contains(word))//Here if the word already exist we just increment a counter for that word.
                    {
                        indexOfWord = words.indexOf(word);
                        count = wordCount.get(indexOfWord);
                        count = count + 1;
                        wordCount.add(indexOfWord, count);
                    } else {
                        words.add(i, word);
                        wordCount.add(i, 1);
                        i++;
                    }
                }
                sc.close();


                Integer max = Collections.max(wordCount); //At this point we go through the array and sort it by max occurrences of words
                System.out.println("max word occurence is:" + max);// and then display them in descending order.
                System.out.println("|Count|Word");
                System.out.println("|-----|-----------------|");

                int no_of_elements = words.size();

                while (max != 0) {
                    for (int j = 0; j < no_of_elements; j++) {
                        String word = words.get(j);
                        count = wordCount.get(j);
                        if (count == max) {
                            //if(word.isEmpty()){continue;}// I put this in because the program was displaying random blanks for some reason.
                            System.out.printf("|%-4d", count);
                            System.out.printf(" |" + word + "\n");
                        }

                    }
                    max--;
                }
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
                e.printStackTrace();
            }

        }
    }
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406
dheeke
  • 37
  • 4
  • 2
    Didn’t look into it too much but one thing that sticks out is that u initiate the HBox with null buttons. u might need to initiate the buttons before setting them in the HBox. – korpe Oct 28 '21 at 23:43
  • 1
    Thank you @korpe, that was it. – dheeke Oct 28 '21 at 23:49

1 Answers1

4

The error is self-explanatory.

Caused by: java.lang.NullPointerException: Children: child node is null: parent = HBox@4f9175a0
  . . .
  at Text_Processor.<init>(Text_Processor.java:24)

Which is caused by the second line here:

Button button, button2, button3;
HBox hbox = new HBox(button, button2, button3);

Obviously, the button references are all null when passed to the HBox constructor, and that is not allowed.

To fix it, just change the constructor call to this:

HBox hbox = new HBox();

You add the buttons to the hbox later in the app anyway, so you don't need to do it at initialization time in this case. Later in your code you already have this:

hbox.getChildren().addAll(button, button2, button3);

Orthogonal to your question, but on a style note (and you can ignore this if you want), I wouldn't implement EventHandler on the Application class. I think the application class is best defined just implementing the Application lifecycle.

Instead I would name my buttons by their actions and provide methods with the same name, for example:

Button fetchButton = new Button("Click First to Fetch The Raven Text"); 
fetchButton.setOnAction(e -> fetch());

. . .

private void fetch() {
    // perform the fetch task.
}

Ideally fetch would be defined in a separate service class so that it could be unit tested independent of the UI, but putting it as a method on the application would be fine for a small application.

Similarly for other tasks.

Then you can get rid of the (IMO) harder to read, more error prone and more difficult to test common action event handler (which I think has errors in it because you are placing ; after the if condition and before the { code block starts).

Also on a style note, don't use names like Text_Processor, google Java naming conventions and apply them. It makes your code more readable and easier to understand for other Java developers. Plus some tooling assumes the naming conventions are followed and breaks if it is not (e.g. the JavaFX PropertyValueFactory).

jewelsea
  • 150,031
  • 14
  • 366
  • 406