0

I recently started using JavaFX along with FXML. I wrote a small, simple program to test some features of FXML. Here's my code. Main-Class:

package main;

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

import javax.swing.*;
import java.io.IOException;

public class Main extends Application {

    @FXML
    private RadioButton button;

    @Override
    public void start(Stage primaryStage) {

        Parent root = null;
        try {
            root = FXMLLoader.load(getClass().getResource("Main.fxml"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        String input = JOptionPane.showInputDialog("Enter something.");
        button.setText(input);

        Scene scene = new Scene(root,300,200);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

}

Main.fxml:

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

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


<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="248.0" prefWidth="366.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.Main">
   <children>
      <RadioButton layoutX="140.0" layoutY="116.0" mnemonicParsing="false" fx:id="rb" on/>
   </children>
</Pane>

If i execute this program, I get an error message:

javafx.fxml.LoadException: 
/C:/Users/kenta/IdeaProjects/Other%20projects/Test/out/production/Test/main/Main.fxml:7

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:922)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at main.Main.start(Main.java:24)
    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)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: main.Controller
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:920)
    ... 22 more
Exception in Application start method
Exception in thread "main" 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$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at main.Main.start(Main.java:30)
    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)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$148(WinApplication.java:191)
    ... 1 more

Process finished with exit code 1

How can I work with the RadioButton variable "button"?

Kenta1561

Kenta1561
  • 29
  • 1
  • 10
  • 1
    Possible duplicate of [Javafx - Can application class be the controller class](http://stackoverflow.com/questions/33303167/javafx-can-application-class-be-the-controller-class) – Itai Jul 07 '16 at 18:07
  • See linked question. As a side note - it is generally a bad idea to mix JavaFX and Swing (JOptionPane is a Swing component). It can be done, but should usually be avoided if possible. – Itai Jul 07 '16 at 18:08
  • I don't mind making an own Controller class, I'm just still getting errors, I want to know how to work with the variable in a class defined in an FXML file. – Kenta1561 Jul 07 '16 at 18:11
  • 1
    I have linked this question not only because you use your `Application` as a controller, but because James_D's answer explains the way FXML loading, controller initialization and node injection works really well. – Itai Jul 07 '16 at 18:21
  • I can get it to work, but without messing around with Swing or trying to affect the RadioButton in the start() method. No idea why you're using Swing mixed with JavaFX. Just use the JavaFX Dialog instead. Or create a custom one. And I wouldn't use the main app as a controller either. That's not a good idea. – ManoDestra Jul 07 '16 at 18:30
  • I just used JOptionPane to show that I want to know how to like replace a text or generally work with a component as a variable. I want to know how to edit them. I didn't want to go to detail of mixing Swing and JavaFX inside one program. – Kenta1561 Jul 07 '16 at 18:32
  • 1
    "I didn't want to go to detail of mixing Swing and JavaFX inside one program". Yeah. Don't. Just don't. – ManoDestra Jul 07 '16 at 18:33
  • ? I could also write simply radioButton.setText("Test") but then I suppose you would say that I should set the text directly in the FXML file. I want to know how to replace it afterwards. – Kenta1561 Jul 07 '16 at 18:35
  • Create a separate controller first and foremost. Then set properties of the RadioButton in there. You'll want a [ToggleGroup also](https://community.oracle.com/thread/2390081?start=0&tstart=0). – ManoDestra Jul 07 '16 at 18:36
  • Set the properties in the FXML file or in the Controller class? And what do you actually mean with properties? – Kenta1561 Jul 07 '16 at 18:40
  • 1
    The stack trace you posted isn't generated by the code you posted. Please fix your question so that it is at least consistent. – James_D Jul 07 '16 at 23:07

1 Answers1

2

Try applying the following fixes to your code:

Replace

root = FXMLLoader.load(getClass().getResource("Main.fxml"));

with

FXMLLoader loader=new FXMLLoader(getClass().getResource("Main.fxml"));
loader.setController(this);
root = loader.load();

This will make your main class the controller. If you dont do this, the FXMLLoader will create a new instance of your main class which is different from the instance your calling FXMLLoader.load(URL) from.

Change your fxml file to the following:

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

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


<Pane minHeight="0" minWidth="0" prefHeight="248.0" prefWidth="366.0" xmlns:fx="http://javafx.com/fxml">
   <children>
      <RadioButton layoutX="140.0" layoutY="116.0" mnemonicParsing="false" fx:id="button"/>
   </children>
</Pane>

The value of fx:id must be identical to the name of the field you want to save the RadioButton in. Also the namespace declaration should be xmlns:fx="http://javafx.com/fxml". Furthermore, setting the maxHeight and maxWidth properties to -Infinity will prevent the layout from having a size bigger than 0 pixels. You could also omit the <children> and </children> tags.

If you want to learn FXML, I suggest this documentation: Introduction to FXML

0xJonas
  • 289
  • 1
  • 7