Heyho,
i have a very strange load exception after starting my javafx project. The loadexception just appears when i provoke another error, otherwise everything seems to work fine. So the nullpointerexception which i also do not understand and might correlate with the load exception is the reason why i even see this loadexception.
I wrote a getController() Method in my Main class and in start() i wanted to get the controller by loader.getController(), which seems to return null. In my #FXML initialize() i instantiate the model graph, which calls my getController() Method in the constructor and when graph trie to use this constructor i certainly get a nullpointerexception..
Does anybody know the problem?
Here is the Stack trace
`javafx.fxml.LoadException:
/C:/Users/bertr/eclipse-workspace/Hashiwokakero/bin/application/view/Layout.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2571)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at application.Main.start(Main.java:30)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
... 12 more
Caused by: java.lang.NullPointerException
at application.model.Graph.<init>(Graph.java:88)
at application.view.Controller.initialize(Controller.java:68)
... 22 more
`
And the start()- Method
public class Main extends Application {
public static Controller controller;
#Override
public void start(Stage primaryStage) {
try {
//anLeitungLaden();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("view/Layout.fxml"));
Pane pane = (Pane) loader.load();
controller = loader.getController();
Scene scene = new Scene(pane);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Hashiwokakero");
primaryStage.setScene(scene);
//primaryStage.getIcons().add(new Image("resources/logo2.png"));
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
The beginning of Controller class
package application.view;
import java.io.File;
import java.util.Arrays;
import application.model.Vertex;
import application.Main;
import application.model.Edge;
import application.model.Graph;
import application.model.HashiGenerator;
import application.model.HashiGenerator2;
import javafx.animation.Animation;
import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.effect.Glow;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import javafx.util.Duration;
public class Controller {
#FXML public Pane root;
#FXML public Pane pane;
#FXML public CheckBox checkboxMusic;
#FXML public CheckBox checkboxSoundeffect;
#FXML public Button newLevelButton;
public MediaPlayer mediaPlayer;
private MediaPlayer soundeffectPlayer;
private boolean soundEffect;
public int numberOfEmptyContainer;
public Graph level;
public DragStartHandler startHandler;
#FXML private void initialize() {
String musicFile = "src/resources/star-wars-cantina-song.mp3";
Media sound = new Media(new File(musicFile).toURI().toString());
mediaPlayer = new MediaPlayer(sound);
mediaPlayer.play();
numberOfEmptyContainer=0;
checkboxMusic.setSelected(true);
checkboxSoundeffect.setSelected(true);
soundEffect = true;
newLevelButton.setVisible(false);
newLevelButton.setDisable(true);
startHandler = new DragStartHandler();
level = new Graph(pane);
and the Layout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.paint.*?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<Pane id="root" fx:id="root" prefHeight="839.0" prefWidth="1281.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.Controller">
<children>
<Pane id="pane" fx:id="pane" layoutX="21.0" layoutY="64.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="749.0" prefWidth="1209.0" style="-fx-border-radius: 100; -fx-border-width: 100;">
<children>
<Button id="newLevelButton" fx:id="newLevelButton" layoutX="363.0" layoutY="342.0" mnemonicParsing="false" prefHeight="66.0" prefWidth="484.0" style="-fx-border-color: #ffd308; -fx-border-radius: 30;" text="Weiter zu Level 2" textFill="#ffd308">
<font>
<Font name="System Italic" size="40.0" />
</font></Button>
</children></Pane>
<CheckBox id="checkboxSoundeffect" fx:id="checkboxSoundeffect" layoutX="1032.0" layoutY="23.0" mnemonicParsing="false" onAction="#handleCheckboxSoundEffect" text="Soundeffekte" textFill="WHITE" />
<CheckBox id="checkboxMusic" fx:id="checkboxMusic" layoutX="1185.0" layoutY="23.0" mnemonicParsing="false" onAction="#handleCheckboxMusic" text="Musik" textFill="WHITE" />
</children>
</Pane>
Edit:
This is my class Graph
package application.model;
import java.io.File;
import java.util.Arrays;
import application.Main;
import application.view.Controller;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class Graph {
public int numberOfContainer = 8;
public int[][] adjazenzMatrix;
public int[] nodelist;
public boolean[] nodelistvisited;
private Controller controller;
private Pane pane = new Pane();
public Edge ContainerLine ;
public Vertex startContainer;
// 3 Zeilen/ 4 Spalten
// TODO: Positionen überlegen
public Vertex createContainer(double x, double y, double radius, int anzahl) {
return new Vertex(x, y, radius,anzahl);
}
public Graph(Pane pane){
controller= Main.getController();
pane = pane;
nodelist = new int[numberOfContainer];
adjazenzMatrix = new int[numberOfContainer][numberOfContainer];
for (int i = 0; i < numberOfContainer; ++i ) {
Arrays.fill(adjazenzMatrix[i],0);
nodelist[i] = i;
}
nodelistvisited = new boolean[numberOfContainer] ;
Arrays.fill(nodelistvisited,false);
Vertex[][] containerGrid = new Vertex[][]{
{createContainer(pane.getPrefWidth()-(7*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(5*pane.getPrefHeight())/6,30,4), null ,createContainer(pane.getPrefWidth()-(7*pane.getPrefWidth())/8, pane.getPrefHeight()-(1*pane.getPrefHeight())/6,30,3)},
{createContainer(pane.getPrefWidth()-(5*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(5*pane.getPrefHeight())/6,30,5), createContainer(pane.getPrefWidth()-(5*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(3*pane.getPrefHeight())/6,30,3),null},
{null, createContainer(pane.getPrefWidth()-(3*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(3*pane.getPrefHeight())/6,30,2),createContainer(pane.getPrefWidth()-(3*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(1*pane.getPrefHeight())/6,30,1)},
{createContainer(pane.getPrefWidth()-(1*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(5*pane.getPrefHeight())/6,30,1), createContainer(pane.getPrefWidth()-(1*pane.getPrefWidth())/8, (double)pane.getPrefHeight()-(3*pane.getPrefHeight())/6,30,1),null}
};
//Zeilen X Richtung
for (int i = 0; i < 4; ++i) {
//Spalten Y Richtung
for ( int j = 0; j<3; ++j) {
if(containerGrid[i][j] != null) {
Vertex c = containerGrid[i][j];
c.setOnDragDetected(controller.startHandler);
c.setOnMouseDragReleased(controller.dragReleaseHandler);
c.setOnMouseDragEntered(controller.dragEnteredHandler);
c.setUserData(Boolean.TRUE);
c.getChildren().addAll(c.circle, c.label,c.label2);
pane.getChildren().add(c);
}
}
}
} // KostruktorLevel
public void deepSearch(int[][] matrix,int[] nodelist ,boolean[] nodelistvisited ,int current,int suche){
nodelistvisited[current]=true; // Knoten als besucht kennzeichnen
for (int i=0;i<nodelist.length;i++)
{
if(matrix[current][i] == 1&& !nodelistvisited[i]) deepSearch(matrix,nodelist,nodelistvisited,i,suche);
}
}
}
Related
I started to learn JavaFX for couple of days. I took a lot of stackoverflow examples, google-it, youtube videos, and all seems good in examples, but mine does not work and I don't know what I'm doing wrong.
So, I make tests only for now, nothing important, it is not an application in real world.
I've built a Custom Control using SceneBuilder, so this is the fxml file for it:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="cControl" prefHeight="100.0" prefWidth="100.0"
style="-fx-border-color: #111111; -fx-border-radius: 2; -fx-background-color: linear-gradient(from 50% 0% to 50% 100%, #f0f0f0, orangered); -fx-background-radius: 2;"
xmlns="http://javafx.com/javafx/19"
xmlns:fx="http://javafx.com/fxml/1"
>
<children>
<Button fx:id="btnClickMe" layoutX="12.0" layoutY="67.0" mnemonicParsing="false" onAction="#onClickMeAction" prefHeight="25.0" prefWidth="77.0" text="Button" AnchorPane.bottomAnchor="8.0" />
<Label fx:id="lblTitle" alignment="CENTER" contentDisplay="CENTER" focusTraversable="false" layoutY="1.0" prefHeight="43.0" prefWidth="100.0" text="Label" textAlignment="CENTER" AnchorPane.bottomAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="1.0" />
</children>
</AnchorPane>
The model is this:
PackTestModel.java
package com.myapp.customcontrols;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class PackTestModel {
public PackTestModel(String labelText) {
setLabelText(labelText);
}
public String getLabelText() {
return labelText.get();
}
public StringProperty labelTextProperty() {
return labelText;
}
public void setLabelText(String labelText) {
this.labelText.set(labelText);
}
private final StringProperty labelText = new SimpleStringProperty();
}
This is the controller:
package com.myapp.customcontrols;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import java.net.URL;
import java.util.ResourceBundle;
public class PackTestController implements Initializable {
#FXML
private Button btnClickMe;
#FXML
private Label lblTitle;
private final PackTestModel packTestModel;
public PackTestController(PackTestModel ptm) {
packTestModel = ptm;
}
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
lblTitle.textProperty().bind(packTestModel.labelTextProperty());
}
}
This is the code for my CustomControl class:
package com.myapp.customcontrols;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class PackTestCC extends AnchorPane {
private PackTestController packTestController;
public PackTestCC(PackTestModel model) throws IOException {
super();
FXMLLoader loader = new FXMLLoader(getClass().getResource("PackTest.fxml"));
packTestController = new PackTestController(model);
loader.setController(packTestController);
try {
Node n = loader.load();
this.getChildren().add(n);
}catch (RuntimeException e){}
}
}
And my main application Main.java file looks like this:
package com.myapp;
import com.myapp.customcontrols.PackTestCC;
import com.myapp.customcontrols.PackTestModel;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URISyntaxException;
public class Main extends Application {
private MainController2 mainController;
#Override
public void start(Stage stage) throws IOException, URISyntaxException {
Font.loadFont(getClass().getResourceAsStream("Fonts/DINOTBold.otf"), 16);
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("main-view2.fxml"));
mainController = new MainController2();
fxmlLoader.setController(mainController);
Parent n = fxmlLoader.load();
Scene scene = new Scene(n, 800, 600);
mainController.getAnchorPane().getChildren().add(new PackTestCC(new PackTestModel("This is for test")));
stage.setScene(scene);
stage.setMinWidth(800);
stage.setMinHeight(600);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
main-vew2.fxml is very simple, as long as it is for tests:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane
fx:id="anchorPane" prefHeight="300.0" prefWidth="300.0"
style="-fx-border-color: #111111; -fx-border-insets: 5;"
xmlns="http://javafx.com/javafx/19"
xmlns:fx="http://javafx.com/fxml/1" />
and this is MainController2 class:
package com.myapp;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController2 implements Initializable {
#FXML
private AnchorPane anchorPane;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
public AnchorPane getAnchorPane() {
return anchorPane;
}
}
The Custom Control must look like this, according to SceneBuilder UI:
but, when I run my application, all I see is only the border from main-view2.fxml:
What I'm doing wrong, what I'm missing here?
I have created small java Program using javafx. in which i'm trying to save any text file or java file. it save file on expected location but without extension this might be the silly question but i don't have any experience with javaFX,
1.Main.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
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);
}
}
2.Controller.java
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Controller {
#FXML
private TextArea TextArea;
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
void OnButtonClicked(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("Java files (*.java)", "*.java");
fileChooser.getExtensionFilters().add(extFilter);
File selectedFile = fileChooser.showSaveDialog(null);
if(selectedFile != null){
SaveFile(TextArea.getText(), selectedFile);
}
}
private void SaveFile(String content, File file){
try {
FileWriter fileWriter;
fileWriter = new FileWriter(file);
fileWriter.write(content);
fileWriter.close();
} catch (IOException ex) {
Logger.getLogger(Main.class
.getName()).log(Level.SEVERE, null, ex);
}
}
#FXML
void initialize() {
}
}
3.sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?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/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Button layoutX="269.0" layoutY="275.0" mnemonicParsing="false" onAction="#OnButtonClicked" text="Save" />
<TextArea fx:id="TextArea" layoutX="169.0" layoutY="14.0" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>
I'm currently new to JavaFx and java technology, help will be appreciated!!!
The filter in the FileChooser is only for filtering existing files in the active folder. If you want to add a default file extension you need something like:
String fileName = file.toString();
if (!fileName.endsWith(".java"))
fileName += ".java";
I am new in javafx. I am building a basic program in javafx.
But getting error "at java.lang.reflect.Method.invoke(Method.java:497)" while running the program ...........
program is:
package myjfxapp;
import com.sun.javaws.Main;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class NewFXMain extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("main.fxml"));
Pane root = loader.load();
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Fxml code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?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/8.0.60">
<children>
<Button layoutX="221.0" layoutY="58.0" mnemonicParsing="false" text="Button" />
<CheckBox layoutX="211.0" layoutY="152.0" mnemonicParsing="false" text="CheckBox" />
</children>
</AnchorPane>
Stack trace:
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:497)
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)
Your help will be obliged....
You used
new FXMLLoader(Main.class.getResource(...));
and for some reason imported com.sun.javaws.Main. Your class is called NewFXMain, so you need
new FXMLLoader(NewFXMain.class.getResource(...));
or just
new FXMLLoader(getClass().getResource(...));
im devlop javaFx login app from tutorial on youtube for school homework. but after click login button. the login function can't show window main scene (AdminLayout.fxml). just login window hide. Thank you
this is my Error
Caused by: 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.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 more
Caused by: java.lang.NullPointerException
at mpn.manda.controller.LoginLayoutController.Login(LoginLayoutController.java:58)
... 55 more
line 58 at LoginLayoutController.java
Pane p = fxmlLoader.load(getClass().getResource("view/AdminLayout.fxml").openStream());
File LoginLayoutController.java
package mpn.manda.controller;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import mpn.manda.model.LoginModel;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* #author Xaxxis
*/
public class LoginLayoutController implements Initializable {
public LoginModel loginModel = new LoginModel();
#FXML
private Label isConnected;
#FXML
private TextField usernameField;
#FXML
private PasswordField passwordField;
#Override
public void initialize(URL location, ResourceBundle resource) {
if (loginModel.isDbConnected()) {
isConnected.setText("Connected");
} else {
isConnected.setText("Not Connected");
}
}
public void Login (ActionEvent event) {
try {
if (loginModel.isLogin(usernameField.getText(), passwordField.getText())) {
((Node)event.getSource()).getScene().getWindow().hide();
Stage primaryStage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource("view/AdminLayout.fxml").openStream());
AdminLayoutController adminController = (AdminLayoutController)fxmlLoader.getController();
adminController.GetUser(usernameField.getText());
Scene scene = new Scene(p);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} else {
isConnected.setText("Username and password is not correct");
}
} catch (SQLException e) {
isConnected.setText("Username and password is not correct");
}
catch(IOException e) {
e.printStackTrace();
}
}
}
MainApp.java
package mpn.manda;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Xaxxis
*/
public class MainApp extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("view/LoginLayout.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
</pre>
AdminLayoutController.java
<pre>
package mpn.manda.controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
/**
* FXML Controller class
*
* #author Xaxxis
*/
public class AdminLayoutController implements Initializable {
#FXML
private Label userLabel;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void GetUser(String user) {
// TODO
userLabel.setText(user);
}
public void Logout(ActionEvent event) {
}
}
LoginLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.URL?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.paint.RadialGradient?>
<?import javafx.scene.paint.Stop?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mpn.manda.controller.LoginLayoutController">
<stylesheets>
<URL value="#/mpn/manda/css/application.css" />
</stylesheets>
<children>
<Label fx:id="isConnected" layoutX="18.0" layoutY="94.0" prefHeight="28.0" prefWidth="485.0" text="Status" textFill="#f20202">
<font>
<Font size="15.0" />
</font>
</Label>
<Label layoutX="94.0" layoutY="135.0" text="Username" />
<Label layoutX="94.0" layoutY="183.0" text="Password" />
<TextField fx:id="usernameField" layoutX="203.0" layoutY="130.0" promptText="Your username" />
<PasswordField fx:id="passwordField" layoutX="203.0" layoutY="178.0" promptText="Your password" />
<Button layoutX="203.0" layoutY="236.0" mnemonicParsing="false" onAction="#Login" prefHeight="27.0" prefWidth="78.0" text="Login..." />
<Button layoutX="288.0" layoutY="236.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="78.0" text="Cancel" />
<Label layoutX="47.0" layoutY="24.0" prefHeight="59.0" prefWidth="381.0" text="Welcom To The App">
<font>
<Font size="31.0" />
</font>
<textFill>
<RadialGradient centerX="0.5" centerY="0.5" radius="0.5">
<stops>
<Stop color="#3c361c" />
<Stop color="#9a8d8d" offset="0.9330855018587361" />
<Stop color="#9a8d8d" offset="1.0" />
</stops>
</RadialGradient>
</textFill>
</Label>
</children>
</AnchorPane>
AdminLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mpn.manda.controller.AdminLayoutController">
<top>
<Label fx:id="userLabel" prefHeight="17.0" prefWidth="154.0" text="Halo, " BorderPane.alignment="CENTER" />
</top>
<bottom>
<Button mnemonicParsing="false" text="Logout.." BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
The path is wrong.
getClass().getResource("view/AdminLayout.fxml")
will resolve the path relative to the current class (so it is looking for /mpn/manda/controller/view/AdminLayout.fxml). Assuming (since the resource works correctly in MainApp) the view package is mpn.manda.view (i.e. AdminLayout.fxml and LoginLayout.fxml are in the same package), you can either do
getClass().getResource("/mpn/manda/view/AdminLayout.fxml")
(note the leading /, which resolves relative to the classpath), or
MainApp.class.getResource("view/AdminLayout.fxml")
which will resolve the path relative to the MainApp class.
Do not be tempted to use .. to reference a "parent package": this might work when you are reading resources and classes from the file system (e.g. during development), but will fail if your application is bundled in a jar file (which it will be at production time).
As an aside, you should prefer loading the FXML by specifying the URL of the FXML resource, instead of the stream. This is because any resource resolutions in the FXML file itself will fail if you do not specify a URL to the FXMLLoader. So I recommend
FXMLLoader fxmlLoader = new FXMLLoader(MainApp.class.getResource("view/AdminLayout.fxml"));
Pane p = fxmlLoader.load();
// ...
If you like the structure where you have one package (view) for the FXML files and one (controller) for the controllers (I don't, FWIW), another technique you might like is to define an empty class for the purpose of resolving view resources:
package mpn.manda.view ;
public abstract class View { }
And now you can load any FXML from anywhere with
FXMLLoader loader = new FXMLLoader(View.class.getResource("LoginLayout.fxml"));
Parent root = loader.load();
and
FXMLLoader loader = new FXMLLoader(View.class.getResource("AdminLayout.fxml"));
Parent p = loader.load();
etc. etc.
Forgive me if what I ask is obvious but I can't figure out how to create a binding in a StyleClassedTextArea, using RichTextFx. What I want to do is to have the area and a button (that will trigger text-processing of some kind) and disable the button if the area is empty.
My code is the following
Main.java
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
package application;
import java.net.URL;
import java.util.ResourceBundle;
import org.fxmisc.richtext.StyleClassedTextArea;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableStringValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
public class Controller implements Initializable {
#FXML private StyleClassedTextArea mainArea;
#FXML private Button processButton;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
// TODO Auto-generated method stub
processButton.disableProperty().bind(Bindings.isEmpty((ObservableStringValue) mainArea.textProperty()));
}
}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import org.fxmisc.richtext.StyleClassedTextArea?>
<AnchorPane prefHeight="308.0" prefWidth="291.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="application.Controller">
<children>
<VBox layoutY="6.0" prefHeight="308.0" prefWidth="291.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<StyleClassedTextArea fx:id="mainArea" />
<Button fx:id="processButton" mnemonicParsing="false" text="process" />
</children>
</VBox>
</children>
</AnchorPane>
and this because mainTextArea.textProperty() returns ObservableValue<String> when I cast it throws an exception with the following stack trace
javafx.fxml.LoadException:
/C:/Users/dcg601/workspace/javafx/bin/application/Main.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
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 application.Main.start(Main.java:22)
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(Unknown Source)
Caused by: java.lang.ClassCastException: org.reactfx.value.SuspendableValWrapper cannot be cast to javafx.beans.value.ObservableStringValue
at application.Controller.initialize(Controller.java:20)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 17 more
It's crazy but it works:
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
// TODO Auto-generated method stub
ObservableValue<String> qwer = mainArea.textProperty();
ObservableStringValue qwerQ = new ObservableStringValue() {
public String get() { return qwer.getValue(); }
public String getValue() { return qwer.getValue(); }
public void addListener( InvalidationListener listener ) {
qwer.addListener( listener );
}
public void removeListener( InvalidationListener listener ) {
qwer.removeListener( listener );
}
public void addListener( ChangeListener<? super String> listener ) {
qwer.addListener( listener );
}
public void removeListener( ChangeListener<? super String> listener ) {
qwer.removeListener( listener );
}
};
processButton.disableProperty().bind(Bindings.isEmpty( qwerQ ) );
}
But probably better to add a simple listeners:
mainArea.textProperty().addListener( ( ov, oldv, newv ) -> {
processButton.setDisable( newv.isEmpty() );
});