This question already has answers here:
Javafx - Can application class be the controller class
(2 answers)
Closed 2 years ago.
Why in this simple code, i'm get a exception?
I'm just trying to add a button to the panel, I can't find the problem by searching, the feeling that either I am the only one, or I do not understand some fundamental things.
This code performs the only function, it just adds a button to the form built in fxml
public class Wtf extends Application {
#FXML
public AnchorPane noteList;
#Override
public void start(Stage primaryStage) throws Exception {
final FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("wtf.fxml"));
final Parent root = loader.load();
Button button = new Button();
noteList.getChildren().add((button));
Scene scene = new Scene(root);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane fx:controller="Wtf" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane fx:id="noteList" layoutX="119.0" layoutY="68.0" prefHeight="292.0" prefWidth="288.0">
<children>
<VBox layoutX="44.0" layoutY="14.0" prefHeight="207.0" prefWidth="190.0" />
</children>
</AnchorPane>
</children>
</Pane>
StackTrace:
Exception in Application start method
Exception in thread "main" 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 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.NullPointerException
at tests.Wtf.start(Wtf.java:25)
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
This works for me, using the FXML file to place the button
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And the FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button layoutX="274.0" layoutY="175.0" mnemonicParsing="false" text="Button" />
</children>
</AnchorPane>
EDIT
If you want to use the FX Id then make a seperate Class since its a better practice. Like this...
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("ButtonTestClass.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
New class used for the button
public class ButtonTestClass {
#FXML
private Button buttonId;
}
And the FXML File...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.ButtonTestClass">
<children>
<Button fx:id="buttonId" layoutX="331.0" layoutY="131.0"
mnemonicParsing="false" text="Button" />
</children>
</AnchorPane>
Related
I created a custom component called PlayerView which has an associated PlayerView.fxml FXML layout and PlayerView.java class to instantiate the component. I then include multiple instances of this component in another FXML Layout called Board.fxml and attempt to refer to these instances in Board's controller Board.java by using the #FXML annotation to create an injection. However, this injection does not work as intended since I get a NullPointerException when I attempt to refer to PlayerView instances in my controller.
PlayerView.fxml
<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
...
</fx:root>
PlayerView.java
public class PlayerView extends VBox {
public PlayerView() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("PlayerView.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public void init(String name) {
...
}
}
Board.fxml
<VBox xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="pablo.Board" prefHeight="400.0" prefWidth="600.0" alignment="CENTER">
<BorderPane>
<top>
<PlayerView BorderPane.alignment="TOP_CENTER" fx:id="playerView2"/>
</top>
<bottom>
<PlayerView BorderPane.alignment="BOTTOM_CENTER" fx:id="playerView1"/>
</bottom>
<left>
<PlayerView BorderPane.alignment="CENTER_LEFT" fx:id="playerView3"/>
</left>
<right>
<PlayerView BorderPane.alignment="CENTER_RIGHT" fx:id="playerView4"/>
</right>
...
</BorderPane>
...
</VBox>
Board.java
public class Board extends Application {
...
#FXML PlayerView playerView1, playerView2, playerView3, playerView4;
#Override
public void start(Stage primaryStage) throws IOException, ClassNotFoundException {
Parent root = FXMLLoader.load(getClass().getResource("Board.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Pablo!");
primaryStage.setScene(scene);
primaryStage.show();
playerViews = new PlayerView[]{ playerView1, playerView2, playerView3, playerView4 };
playerView1.init(playerName); // NullPointerException occurs at this line
...
}
}
Stack Trace
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.NullPointerException
at pablo.Board.start(Board.java:39)
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)
Is there anything wrong with the way that I am using the #FXML annotation in Board.java to refer to my PlayerView instances in Board.fxml? How should I be referring to them instead?
Define PlayerView:
PlayerView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
<Label fx:id="nameLbl" alignment="CENTER" contentDisplay="CENTER" prefHeight="66.0" prefWidth="87.0" text="--" />
</fx:root>
PlayerView.java which also serves as controller:
public class PlayerView extends VBox {
#FXML Label nameLbl;
public PlayerView() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("PlayerView.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public void init(String name) {
nameLbl.setText(name);
}
}
Board.fxml and its controller:
<?xml version="1.0" encoding="UTF-8"?>
<?import fx_tests.a_test.PlayerView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" prefHeight="400.0"
prefWidth="600.0" alignment="CENTER" fx:controller="foo.bar.BoardController">
<BorderPane>
<top>
<PlayerView fx:id="playerView2"/>
</top>
<bottom>
<PlayerView fx:id="playerView1"/>
</bottom>
<left>
<PlayerView fx:id="playerView3"/>
</left>
<right>
<PlayerView fx:id="playerView4"/>
</right>
</BorderPane>
</VBox>
Let the controller change Boaed state as needed:
public class BoardController{
#FXML PlayerView playerView1, playerView2, playerView3, playerView4;
public PlayerView getBottom(){
return playerView1;
}
public PlayerView getTop(){
return playerView2;
}
public PlayerView getLeft(){
return playerView3;
}
public PlayerView getRight(){
return playerView4;
}
}
Get the controller in Board and use it :
public class Board extends Application {
#FXML PlayerView playerView1, playerView2, playerView3, playerView4;
#Override
public void start(Stage primaryStage) throws IOException, ClassNotFoundException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Board.fxml"));
VBox root = loader.load();
BoardController controller = loader.getController();
Button btn = new Button("Add Names");
btn.setOnAction(e->{
controller.getTop().init("Top");
controller.getBottom().init("Bottom");
controller.getLeft().init("Left");
controller.getRight().init("Right");
});
root.getChildren().add(btn);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(null);
}
}
To continue this post, I implemented part of the solution that was suggested.
I have my main panel and I want to drew on it a component which is a different class (steerwheel).
My main controller :
public class WindowController {
#FXML SteerWheel steerwheel;
... other componenets..
}
My new component :
public SteeringWheel() {
myLabel = new Label();
innerCircle = new Circle();
backgroundCircle = new Circle();
System.out.println("steerwheel created.");
}
.. other methods..
My mainwindow.fxml file :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import view.SteerWheel?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9.0.1" fx:controller="view.WindowController">
<center>
<SteerWheel fx:id="steerwheel" />
</center>
</BorderPane>
and my steerwheel.fxml file :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.text.Font?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="view.SteerWheel"
prefHeight="400.0" prefWidth="600.0">
<Label fx:id="mylabel" prefHeight="30.0" prefWidth="102.0" text="mytest" translateY="30" translateX="90">
<StackPane >
<Circle fx:id="innerCircle" fill="darkgray" radius="170" />
<Circle fx:id="backgroundCircle " fill="black" radius="80" />
</StackPane>
</AnchorPane>
My main code that loads the fxml files (in a different file from all mentioned) :
public class Main extends Application {
public static Stage primaryStage;
#Override
public void start(Stage primary_stage) {
this.primaryStage=primary_stage;
FXMLLoader fxl=new FXMLLoader();
try {
BorderPane root = fxl.load(getClass().getResource("mainwindow.fxml").openStream());
WindowController wc=fxl.getController();
Scene scene = new Scene(root,700,700);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
I'm seeing the constructor`s output but to the console but the component isn't displayed on the window.
Update
I tried to add a call for the fxml file of the steerwheel in my Window.fxml :
<BorderPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9.0.1" fx:controller="view.WindowController">
<center>
<VBox maxHeight="-Infinity" prefHeight="450.0" prefWidth="400.0" BorderPane.alignment="TOP_CENTER">
<children>
<fx:include source="steerwheel.fxml" fx:id="steerwheel" />
</children>
</VBox>
</center>
</BorderPane>
Now I'm getting the following error :
Caused by: java.lang.IllegalArgumentException: Can not set view.steerWheel field view.WindowController.steerWheel to javafx.scene.layout.AnchorPane
I found the following post that described the same issue I had :
Passing data from one controller to another in javafx. java.lang.IllegalArgumentException
#fabian also answered there how to solve the issue.
The solution I implemented :
My main fxml file :
<BorderPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9.0.1" fx:controller="view.WindowController">
<center>
<VBox maxHeight="-Infinity" prefHeight="450.0" prefWidth="400.0" BorderPane.alignment="TOP_CENTER">
<children>
<fx:include fx:id="steerwheel" source="steerwheel.fxml" />
</children>
</VBox>
</center>
</BorderPane>
In the controler of the fxml file I added an AnchorPane object that named after the fx:id and I renamed the steerWheel obj to steerwheelController :
public class WindowController {
#FXML AnchorPane steerwheel;
#FXML steerWheel steerwheelController;
Afterwards, I had to use the setLocation method in my main in order to load the inner fxml file (otherwise I got an error..) :
FXMLLoader fxl=new FXMLLoader();
try {
fxl.setLocation(getClass().getResource("Window.fxml"));
BorderPane root = fxl.load();
WindowController wc=fxl.getController();
Hoping it will help someone :)
This question already has an answer here:
Missing titlebar on javafx app, with OpenJFX
(1 answer)
Closed 3 years ago.
public class Hello extends Application{
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("hellofxml.fxml"));
Scene scene = new Scene(root,500,500);
stage.setScene(scene);
stage.setTitle("hello world");
// stage.initStyle(StageStyle.TRANSPARENT);
stage.show();
}
public static void main(String[] args) {
launch(args);
System.out.println("hello");
}
}
The output of this code gives me a simple window without any close, minimize , maximize buttons, in other words a titleless window
I want to know where the problem
images links are
https://ibb.co/5YNfR1G
https://ibb.co/Hq9pM0S
fxml code
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="Hello.HellofxmlController">
<children>
<Button fx:id="ok_btn" layoutX="238.0" layoutY="174.0" mnemonicParsing="false" text="ok" />
</children>
</AnchorPane>
This is a known issue with GTK3 and JavaFX and is already answered here
I want to add an application icon to my program. I've tried to do that as following, but it haven't worked:
primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("lock.png")));
primaryStage.getIcons().add(new Image(Controller.class.getResourceAsStream("lock.png")));
final Parent root = FXMLLoader.load(getClass().getResource("passwordGenerator.fxml"));
or
primaryStage.getIcons().add(new Image("lock.png"));
Also I tried to do that without a FXML file and it worked.
How can I add an application Icon with a FXML file?
here the solution it works with me :
Main class :
public class JavaFXIcons extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.getIcons().add(new Image(JavaFXIcons.class.getResourceAsStream("stackoverflow.jpg"))) ;
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxicons.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Say I have a window, with a button. And everytime that button is pressed I want the current window to be disposed and a new one to be shown.
In Swing, that was easy, but I can't find the syntax for it in JavaFx?
So in this case, with my example code, how do I do this?
public class Main extends Application {
Parent root;
Scene scene;
#Override
public void start(Stage primaryStage) throws Exception {
root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.setResizable(false);
primaryStage.show();
root.setOnMouseClicked((MouseEvent mouseEvent) -> {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
if (mouseEvent.getClickCount() == 2) {
Stage stage = new Stage();
stage.setScene(primaryStage.getScene());
stage.show();
primaryStage.close();
}
}
});
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Trying to create a new window: http://sv.tinypic.com/r/1jkq4w/8
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController">
<children>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Label fx:id="labelPlayerTotal" layoutX="510.0" layoutY="335.0" prefHeight="15.0" prefWidth="121.0" text="Playertotal:" />
<Label fx:id="labelDealerTotal" layoutX="510.0" layoutY="359.0" prefHeight="15.0" prefWidth="112.0" text="Dealertotal:" />
<TextArea fx:id="dealerArea" layoutY="29.0" prefHeight="159.0" prefWidth="503.0" />
<TextArea fx:id="playerArea" layoutY="244.0" prefHeight="159.0" prefWidth="503.0" />
<Button fx:id="stayButton" layoutX="512.0" layoutY="173.0" mnemonicParsing="false" onAction="#drawCardForDealer" prefHeight="25.0" prefWidth="72.0" text="STAY" />
<Button fx:id="hitButton" layoutX="512.0" layoutY="130.0" mnemonicParsing="false" onAction="#drawCardForPlayer" prefHeight="25.0" prefWidth="72.0" text="HIT" />
<Label fx:id="labelWinner" layoutX="104.0" layoutY="208.0" prefHeight="15.0" prefWidth="296.0" />
<MenuBar fx:id="helpBar">
<menus>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" onAction="#aboutApplication" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</AnchorPane>
</children>
</VBox>
You can just hide (i.e. dispose) the window by calling hide() or close() on it.
And you can just show a new window with exactly the same code you used before:
primaryStage.close();
Stage stage = new Stage();
root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
scene = new Scene(root);
stage.setScene(scene);
stage.sizeToScene();
stage.setResizable(false);
stage.show();
But this seems like way too much for what you want to achieve. Why not just replace the root of the existing scene, and use the existing stage?
try {
scene.setRoot(FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")));
} catch (Exception exc) {
exc.printStackTrace();
throw new RuntimeException(exc);
}
Note though that (either way you do this) you have now replaced the root of the scene; the new root does not have the same mouse handler associated with it. If you use the second method, you can just put the handler on the scene (which doesn't change) instead. Or, perhaps better, is that you can define the listener in the FXML and controller:
<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController"
fx:id="root"
onMouseClicked="reload">
<!-- ... -->
</VBox>
And the controller:
package blackjack ;
public class FXMLDocumentController {
// ...
#FXML
private VBox root ;
// ...
#FXML
private void reload() throws Exception {
// Really, it would be way better here to reset the whole UI to its initial
// state, instead of reloading it from scratch. This should work as a
// quick hack though.
Scene scene = root.getScene();
scene.setRoot(FXMLLoader.load(Main.class.getResource("FXMLDocument.fmxl")));
}
// ...
}