I have a problem with javaFX jar application.
When I compile my project in IDEA it looks like this:
enter image description here
But when I build jar application, after pressing AUTHORIZATION in first window,
it doesn't open next window. I use FXML scenes.
First window is calling from start() method in Main class, others from controllers classes.
Method in main class.
public void start(Stage primaryStage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("Interface.fxml"));
Scene scene = new Scene(parent);
primaryStage.setScene(scene);
primaryStage.setTitle("Hello Client");
primaryStage.show();
}
And one of the controllers class:
#FXML
public void Autentification(ActionEvent actionEvent) throws Exception {
UserInform.AccauntName = name;
UserInform.UserName = name;
int intPort = Integer.parseInt(port);
messages.PrintMessage("Authentication started\n", Out);
ConnectionForUI.session.tryConnect(name, pass, host, intPort);
//Run next window
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../ClientField.fxml"));
Parent root = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setTitle("Client");
stage.setScene(new Scene(root));
stage.show();
}
Autentification method runs when I press Authorization button, and here runs next window.
I'm new in Java FX so if you know how to repaid this problem, I will be very grateful.
Exception:
enter image description here
Problem was in the way to me FXML files. You have to set absolute way to files, like"/file_name.fxml". It helped to me.
Related
I am completly lost atm. I have been working with scenebuilder and javaFX in the past but I am stuck like 5 hours now and I didnt get a step further. Let me explain:
I have a working java Eclipse Project, using maven dependencies
The Main is where I want to use JavaFX or load a fxml into
The programm takes many many VCC Files and extracts the data to put it all together in an excel
The programm works but I cant load a FXML file into the main or even show a pane in there
Now does my Java Main class has to extend Application? I tried both ways - doenst work.
Some example code:
public void start(Stage primaryStage) {
try {
bpmain = new BorderPane(FXMLLoader.load(new File("src\\fxml\\UserInterface.fxml").toURI().toURL()));
primaryStage.setScene(new Scene(bpmain));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
or this (from original Docs)
public void start(Stage stage) {
Circle circ = new Circle(40, 40, 30);
Group root = new Group(circ);
Scene scene = new Scene(root, 400, 300);
stage.setTitle("My JavaFX Application");
stage.setScene(scene);
stage.show();
}
but this start method is just not getting called... where do I put that?
What my Programm should look like is pretty simple actually. I want a small UI Windows that lets you pick a Folder where the VCC data lives in and a OK Button that basically should run the Main method.
So a TextField that when its picked a Path in the Main gets replaced (filepath) and just a simple OK Button that says: yeah run the main - because the main works perfectly it is just that I cant show that ui and I dont know how to really connect it to the Main.java
Any help is appreciated - Ty
Option 1
public class Launch extends Application {
public static Stage stage = null;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Option 2:
public class SidebarController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void btnHome_OnMouseClicked(MouseEvent event) throws IOException {
BorderPane borderPane = (BorderPane) ((Node) event.getSource()).getScene().getRoot();
Parent sidebar = FXMLLoader.load(getClass().getResource("/fxml/ContentArea.fxml"));
borderPane.setCenter(sidebar);
}
}
I am trying to create a stage in JavaFX that can pop up to the front in windows, while the main stage stays minimized.
This only works however, when the main stage is visible on the screen. I have tried making it work using Modality, but then the user can't interact with the main stage, which is not what i want.
The problem can be reproduced with the following Application:
public class MainApp extends Application {
#Override
public void start(Stage stage) throws Exception {
Scene mainScene = new Scene(new Parent() {});
Stage mainStage = new Stage();
mainStage.setScene(mainScene);
mainStage.show();
mainStage.setIconified(true);
Scene popUpScene = new Scene(new Parent() {});
Stage popUpStage = new Stage();
popUpStage.setScene(popUpScene);
Thread.sleep(5000);
popUp(popUpStage);
}
public static void popUp(Stage popUpStage){
if (popUpStage.isIconified()) popUpStage.setIconified(false);
popUpStage.show();
popUpStage.requestFocus();
popUpStage.toFront();
}
}
Is there anyone who has an answer to this problem?
Just add these two line to popUp. First line brings it to front. Second line allows interaction with the main stage or other windows.
popUpStage.setAlwaysOnTop(true);
popUpStage.setAlwaysOnTop(false);
I am very new to using JavaFX and have having some trouble using JavaFX with FXML. I am creating a program with a "Setup" button that when clicked, opens a new window with the connection (to an Arduino) settings. On the menu is another button ("Connect") that connects to the board. This closes the window. I'm looking to have this change the text of the original "setup" button to "disconnect", however, I don't seem to be able to access the button from the "setup window". Whenever I click "connect" I get the following error:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
I read online that this is a wrapper for a null pointer exception. I assume that the "setup" button is null and that's why I can't change it, but I can't work out why.
Here is an excerpt from MainController.java:
#FXML
protected void setUpConnection(ActionEvent e) {
SetupController setupController = new SetupController();
setupController.init(this);
}
The above method gets called when the "setup" button is clicked (set in the file: setupMenu.fxml). This then opens up the separate window. Here is the code in SetupController.java that opens the window:
private void openSetupWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("setupMenu.fxml"));
Parent root1 = (Parent)loader.load();
Stage stage = new Stage();
stage.setTitle("Setup Connection");
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception exc) {
exc.printStackTrace();
}
}
When the connect button is clicked, the following method (in SetupController.java) is called:
private void changeButtonText(ConnectionEventType e) {
Button b = main.getSetupButton();
if(e == ConnectionEventType.CONNECT) {
b.setText("Disconnect");
}
else {
b.setText("Setup Connection...");
}
}
(main is the MainController object that was passed in to setupController.init() )
The above code is where I am getting the error.
Just to clarify, I have 2 separate fxml files, one for the main window and one for the pop up. sample.fxml(the main window) has its controller set to MainController and is set up in Main.java (below):
#Override
public void start(Stage primaryStage) throws Exception{
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
GridPane root = loader.load();
Scene scene = new Scene(root, 1200, 900);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Nest Control");
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
Am I trying to access the button incorrectly? Is anyone able to help? Like I said, I don't have much experience with using JavaFX or FXML.
I think the answer you are looking for is to store the controllers for each window you open so you can access the variables within the controllers, however without the rest of your code would be hard to advise you, but heres an example of what i mean:
private SetupController yourController;
#Override
public void start(Stage primaryStage) throws Exception{
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
GridPane root = loader.load();
this.yourController=loader.<SetupController>getController();
Scene scene = new Scene(root, 1200, 900);
}
}
You could then pass the variable yourController to other instances in a Model-view-controller type way and access its methods.
or something like this in your case :
private void changeButtonText(ConnectionEventType e) {
Button b = this.yourController.getButton(); //a method that returns your #FXML button object in your controller
if(e == ConnectionEventType.CONNECT) {
b.setText("Disconnect");
}
else {
b.setText("Setup Connection...");
}
}
Or alternatively have a specific method within the controller that will set the text of the button without having to return the button object.
See the examples here and here
However please note the error you get seems to typically attributed to missing #FXML annotations so maybe make sure in this instance that you have annotated all the variables in any controllers also. See here for more details.
I actually want to build a fx application that go from one fxml to another (with this process :fxml number 1 load then go with a click and another load).
I have made stage in my main class static and use it again and again.
according to Restriction of stack space in ram is it a good idea ?? or there is a better way?
these are parts of my code:
public class Main extends Application {
public static Stage stage;
#Override
public void start(Stage primaryStage) throws Exception{
stage=primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("MainWidget.fxml"));
stage.setTitle("Welcome");
stage.setScene(new Scene(root, 300, 275));
stage.show();
}
and my controller is(loading another fxml!! )
public void someButtonController{
Parent root = FXMLLoader.load(getClass().getResource("/View/ShowWidget.fxml"));
Scene scene = new Scene(root,300,300);
Main.stage.setScene(scene);
Main.stage.show();}
I would not expose the Stage at all. Doing so couples your FXML-Controller pair to your Main class and prevents you ever using it without that class.
Instead, do something like
#FXML
private Button someButton ;
// ...
public void someButtonController{
Window window = someButton.getScene().getWindow();
if (window instanceof Stage) {
Parent root = FXMLLoader.load(getClass().getResource("/View/ShowWidget.fxml"));
Scene scene = new Scene(root,300,300);
Stage stage = (Stage) window ;
stage.setScene(scene);
stage.show(); // isn't it necessarily showing already?
}
}
Here I'm assuming that the controller is the controller for an FXML file representing Nodes that are displayed in the Stage you're trying to access. If that's not the case, you can still do something similar though it will be more complex.
The first stage that I load it always open properly as fullscreen.
stage.setFullScreen(true);
stage.setScene(login_scene);
But when I change to another FXML the applications stays fullscreen (no top toolbar.. ), but the actual view content gets resized on the prefWidth/prefHeight of the root AnchorPane from FXML (I can see the desktop in my bottom right corner :|), and I want it to be dynamic to my screen resolution.
Thanks.
#Later Edit:
So on the start method of my main Class I load a Scene (created from an FXML doc) and set it to the Stage (the start method param). I save this stage for later use.
When I press a button with the same stage I save previously I change the scene to another FXML document
#Screenshots:
http://tinypic.com/r/2079nqb/6 - 1st scene works normally - code from start override method of the main class
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
stage.setScene(new Scene(root));
stage.setFullScreen(true);
stage.show();
currentStage = stage;
}
http://tinypic.com/r/szfmgz/6 - after reloading the second scene - the code below from sample controller class
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.setScene(new Scene(root));
}
I have no idea about the real cause but here are 2 quick workarounds.
In the handleButtonAction method:
1) Don't create new scene just replace its content
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.getScene().setRoot(root);
}
2) If you really nead to create new scene then toggle fullscreen
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.setScene(new Scene(root));
Platform.runLater(new Runnable() {
#Override
public void run() {
JavaFXApplication12.currentStage.setFullScreen(false);
JavaFXApplication12.currentStage.setFullScreen(true);
}
});
}
If I am right to know your concern then You should use your primary stage as static or you can make it available to other controller by making getters and setters. So to get same stage to load other fxmls you can set it to when you are loading a fxml and also make sure that do not create another scene. Because due to new scene you actual content resized.
So you can use this
In Main.java:
YourController objYourController = loader.getController();
objYourController.setDialogStage(primaryStage);
In YourController.java:
public void setMystage(Stage primaryStage) {
this.primaryStage= primaryStage;
}
//To load another FXML
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
primaryStage.getScene().setRoot(rootLayout);
Hope it will help you.