Switch scenes from one package to another package javafx [duplicate] - java

This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 2 years ago.
I have two packages p1 and p2.
P1 contains the main class, controller class and one fxml file.
P2 contains the controller class and one fxml file.
I want to switch from p1 fxml to p2 fxml file.
here is the code I tried. this is in P1 package.
public void btncontinue(ActionEvent event)throws IOException {
String filepath = "file:///D:/Programs/InteliJProjects/C/src/p1/sample2.fxml";
Parent nextScene = FXMLLoader.load(getClass().getClassLoader().getResource(filepath));
Scene scene = new Scene(nextScene);
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
stage.setScene(scene);
stage.show();
}
The error i am getting is Location is required.

Well I've checked this is the code from scene1 to scene2
package sample;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class sample
{
#FXML
RadioButton male;
#FXML
AnchorPane rootPane;
public void add() throws IOException
{
AnchorPane pane = FXMLLoader.load(getClass().getResource("two.fxml"));
rootPane.getChildren().setAll(pane);
}
}
And this is how to return from scene2 to scene1
package sample;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class Two
{
#FXML
Button back;
#FXML
AnchorPane secPane;
public void returnBack() throws IOException
{
AnchorPane pane = FXMLLoader.load(getClass().getResource("sample.fxml"));
secPane.getChildren().setAll(pane);
}
}
I've tried this and it is working fine hope it will help you

Related

javac not finding another compiled class in current folder

I'm using OpenJDK11.
I have two Java files in the current folder, that are supposed to run together to be a JavaFX application.
One of them is called Main.java and runs the main window. Another is Alert.java, and is supposed to run an alternate window which is an alert type.
Now, I ran the following command:
javac -cp "c:\projects\java\currentProject" --module-path "c:\Program Files\Java\javafx-sdk-11.0.1\lib" --add-modules=javafx.controls,javafx.fxml Alert.java Main.java
While Alert.java compiled just fine, Main.java could not import the Alert class and gave an error on "import Alert". I tried "import Alert.Alert" and "import currentProject.Alert" but still, it didn't work.
Also, I declared package "package currentProject" at the start of each file and it still gave an error.
What am I supposed to do to get it running? I already failed on installing JavaFX on all available IDEs, so I'm not going to use an IDE other than Atom. But how do I compile it properly?
more info -
file structure:
c->projects->java->economicManager->( Alert.java ,Main.java, financialManager.fxml, alert.fxml, Alert.class, Alert$Controller.class, Main.class [previously compiled version])
Alert.java:
package financialManager;
import javafx.stage.Stage;
import javafx.stage.Modality;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import java.util.Map;
public class Alert {
public Stage stage;
private Controler_Class controler;
public Alert(Parent root) {
Controler_Class clas = new Controler_Class(root);
this.controler = clas;
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("financial report");
stage.setScene(scene);
this.stage = stage;
stage.showAndWait();
}
private class Controler_Class{
Parent root;
public Controler_Class(Parent root){
}
}
}
Main.java:
package financialManager;
import Alert;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import java.util.Map;
public class Main extends Application{
#Override
public void start(Stage stage) throws Exception{
final int width = 300;
final int height = 450;
stage.setTitle("hello mofos");
FXMLLoader loader = new FXMLLoader(getClass().getResource("financialManager.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, width, height);
Map<String, Object> mapper = loader.getNamespace();
AnchorPane pane = (AnchorPane) mapper.get("splitpane1_anchorpane");
if(pane != null)
SplitPane.setResizableWithParent(pane, false);
else
System.out.println("it's null you idiot!");
Button btn = (Button) mapper.get("economicReport");
btn.setOnMouseClicked((event) -> {
FXMLLoader loader2 = new FXMLLoader(getClass().getResource("alert.fxml"));
Parent parent = loader2.load();
Alert alert = new Alert(parent);
});
/*
ChangeListener<Number> stageSizeListener = (observable, oldValue, newValue) ->
pane.setDividerPositions(0.20219435736677116);
stage.widthProperty().addListener(stageSizeListener);
stage.heightProperty().addListener(stageSizeListener);
*/
stage.setScene(scene);
stage.show();
}
public static void main(String[] args){
launch();
}
}
I see that you are importing the Alert class wrongly. Your package is financialManager, so you should use it in the import line like this:
import financialManager.Alert;
About your issues with IDEs, I made JavaFX work fine with Eclipse and IntelliJ on OpenJDK 11 without any issues a few days ago - For OpenJDK you will need OpenJFX, and if you are interesting in some reading, this is the link from Oracle's blog on their plans for JavaFX.
Good luck!

Swap JavaFX scene when clicking a button

I am trying to create a program to teach people about GNU/Linux and the command line, I have my 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 {
Stage window;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
primaryStage.setTitle("Learnix");
primaryStage.setScene(new Scene(root, 800, 500));
primaryStage.show();
}
}
And the controller to go with it.
package sample;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import java.io.IOException;
public class loginController {
public Button loginBtn;
public void loginBtnClick() throws IOException {
System.out.println("You are logged in");
}
}
I have tried things such as:
FXMLLoader.load(getClass().getResource("lessons.fxml"));
But I can't figure out how to get it to swap scenes. I have seen many tutorials on YouTube and it Stack Overflow but many of them have all of the JavaFX on the main.java and not in separate files as I am using scenebuilder.
Thank you.
You can either call Stage.setScene() to change the whole scene or just substitute a root to the new one by Scene.setRoot():
Parent newRoot = FXMLLoader.load(getClass().getResource("lessons.fxml"));
primaryStage.getScene().setRoot(newRoot);

javaFX circle in a layout not visible

I made a circle and added as a child to a group. then I added the group as a child to a layout(Region). I added Region to the scene. I made both with different colours but I cannot see the circle
Analog_clock.java
package analog_clock;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Analog_clock extends Application {
#Override
public void start(Stage primaryStage) {
Circle circle = new Circle();
circle.setCenterX(100.0f);
circle.setCenterY(100.0f);
circle.setRadius(50.0f);
circle.setFill(Color.ALICEBLUE);
Group g = new Group();
g.getChildren().add(circle);
Background_region_ bg = new Background_region_();
bg.getChildrenUnmodifiable().add(g);
Scene scene = new Scene(bg, 300, 250);
scene.getStylesheets().add(this.getClass().getResource("style.css").toExternalForm());
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Background_Region_.java
package analog_clock;
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.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Background_region_ extends Region
{
//CONSTRUCTOR
public Background_region_()
{
setStyle("-fx-background-color: #ACACE6");
}
}
style.css
.circle{-fx-stroke: #cdd0d7;}
The problem is the Region Class only has an Unmodifiable List of children via its public API, that means, the only way to add children to it is to subclass it (e.g Pane). So use Pane or another subclass, something like this for example:
Pane bg = new Pane();
bg.setBackground(new Background(new BackgroundFill(Color.web("#ACACE6"), null,null)));
bg.getChildren().add(g);
Use Pane instead of Region. Region is a special parent class for control's developers.
Next line throws exception in your code:
bg.getChildrenUnmodifiable().add(g);
Note word "Unmodifiable". It means your are not supposed and can't modify this list.

javafx communication between controller and main

Why does the following code always show null in the console when I want to get the controller ?
RenewCardFXML2_controller controller=loader.getController();
and the console prints null when i press the button.
I have two controllers and want to use textfield from the main app(membershipcards)-txt_numberOfCard_GENERAL inside the second fxml file whick has its own controller.
txt_numberOfCard_GENERAL.getText command from seccond controller and use its value.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package membershipcards;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.SplitPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import membershipcards.RenewCardFXML2_controller;
/**
*
* #author Primary
*/
public class mainGUIController implements Initializable {
#FXML
private ImageView logoimg;
#FXML
private SplitPane splitMenuContent;
#FXML
private Button btnCards;
#FXML
private Button btnRenewCard;
#FXML
private Button bntNewClient;
#FXML
private Button btnEditCard;
#FXML
private Button btnStatistics;
#FXML
private AnchorPane detailsPane;
#FXML
private Button btnCardN;
#FXML
public TextField txt_numberOfCard_GENERAL;
#FXML
public TextField txt_memberName_GENERAL;
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
private void loadCardsFXML1(ActionEvent event) {
try {
detailsPane = (AnchorPane) FXMLLoader.load(getClass().getResource("CardsFXML1.fxml"));
} catch (IOException ex) {
Logger.getLogger(mainGUIController.class.getName()).log(Level.SEVERE, null, ex);
}
splitMenuContent.getItems().set(1, detailsPane);
}
#FXML
private void loadRenewCardFXML2(ActionEvent event)throws IOException {
FXMLLoader loader = new FXMLLoader();
detailsPane = (AnchorPane) loader.load(getClass().getResource("RenewCardFXML2.fxml"));
splitMenuContent.getItems().set(1, detailsPane);
RenewCardFXML2_controller controller=loader.getController();
controller.setMGC(this);
System.out.println(controller);
}
}
The FXMLLoader.load(URL) method you are calling is a static method. Consequently, you have not called load on the FXMLLoader instance you created, and since that instance hasn't loaded the FXML, it has not initialized its controller field.
(A good IDE will give you a warning on your loader.load(...) line about calling a static method from a non-static context, or something similar. Eclipse, for example, says "The static method load(URL) should be accessed in a static way.")
The following will work:
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("RenewCardFXML2.fxml"));
detailsPane = loader.load();
splitMenuContent.getItems().set(1, detailsPane);
RenewCardFXML2_controller controller=loader.getController();
Note that you can reduce the first two lines of that code block to a single line
FXMLLoader loader = new FXMLLoader(getClass().getResource("RenewCardFXML2.fxml"));
detailsPane = loader.load();

JavaFX, Open a Screen in same Window

I'm trying to implement an application, which has a simple navigation. One Main Menu, 3 Submenus, with another 3 Submenus each.
I need the application open every submenu recursively in the same Window with the Mainmenu as the root screen. I must be able to return to that menu by going via the "Back" Button on each Submenu.
I implemented a Main class, a Controller Class and a FXML-file for EACH (!) Menu and Submenu.
E.g. my Main Menu
package application;
import org.apache.log4j.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
// Initialize Logger
private static final Logger logger = Logger.getLogger(Main.class);
#Override
public void start(Stage primaryStage)
{
try
{
AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("MainFrame.fxml"));
Scene scene = new Scene(root,1000,500);
primaryStage.setScene(scene);
primaryStage.show();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
logger.info("Starting application.");
launch(args);
}
}
My MainController
package application;
import org.apache.log4j.Logger;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class MainFrameController
{
private static final Logger logger = Logger.getLogger(MainFrameController.class);
#FXML
private Button btn_random1;
#FXML
private Button btn_random2;
#FXML
private Button btn_random3;
#FXML
private Button btn_random4;
public void initialize()
{
//mainService = new MainService();
}
#FXML
private void onRandomButton1() throws Exception
{
logger.info("onRandomButton1Clicked");
Stage stage = new Stage();
AnchorPane root;
root = (AnchorPane)FXMLLoader.load(getClass().getResource("RandomFXML1.fxml"));
Scene scene = new Scene(root,1000,500);
stage.setScene(scene);
stage.show();
}
#FXML
private void onRandomButton2()
{
logger.info("onRandomButton1");
}
#FXML
private void onRandomButton3()
{
logger.info("onRandomButton2");
}
#FXML
private void onRandomButton4()
{
Platform.exit();
logger.info("onRandomButton3");
}
}
Is there a way to simply change my code, so it does open in the same window?
I took a look at several tutorials with relatively complex ways of solving this, I'd like to stick to my code and not changing too much, otherwise I'd have to start all over again.
Pls note, that this is only one of many Main/Controller/FXML combinations, I have about 10 screens and "subscreens", which are being navigated like this (by java opening a new window).
Ideas anyone? Or maybe a relatively simple tutorial (for which I dont have to change my whole code)?
Thanks!
Have an empty controller at the root (or perhaps with a single empty anchorpane) and have it open the other controllers and add it to the current pane?
I currently have a similar setup but with a tab pane: each module is loaded into a separate tab. Each module itself has an fxml file, a controller etc. The core code dynamically creates new tabs etc for each module and loads them.

Categories