How do I change a scene in javaFX without a button? - java

How can I change a scene without directly interacting with it (like using a button). What I would like for my program to do is change scene, and then using the Initializable class, the program would wait 1.5 seconds then change scene.
I am currently using a PauseTransition to do this, however I get a ClassCastException. Also, I do not understand what Intellij is trying to tell me about the Node. It says 'Find why 'event.getSource()' could be javafx.animation.PauseTransition (not-null)'.
Thanks in advance.
Stack Trace:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class javafx.animation.KeyFrame cannot be cast to class javafx.scene.Node (javafx.animation.KeyFrame and javafx.scene.Node are in module javafx.graphics of loader 'app')
at Dice.Game/sample.RoundCounterController.lambda$initialize$0(RoundCounterController.java:54)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:180)
at javafx.graphics/javafx.animation.Timeline.doPlayTo(Timeline.java:177)
at javafx.graphics/javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
at javafx.graphics/com.sun.scenario.animation.shared.SingleLoopClipEnvelope.timePulse(SingleLoopClipEnvelope.java:99)
at javafx.graphics/javafx.animation.Animation.doTimePulse(Animation.java:1101)
at javafx.graphics/javafx.animation.Animation$1.lambda$timePulse$0(Animation.java:186)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/javafx.animation.Animation$1.timePulse(Animation.java:185)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:515)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:829)
RoundCountController.java
import javafx.animation.KeyFrame;
import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.animation.Transition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class RoundCounterController implements Initializable {
#FXML private Label roundLabel;
private static int roundCounter = 0;
#FXML private AnchorPane pane;
private Stage stage;
private Scene scene;
private Parent root;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
PauseTransition pauseTransition = new PauseTransition(Duration.seconds(1.5));
pauseTransition.setOnFinished(event -> {
try {
Parent root = FXMLLoader.load(getClass().getResource("p1GameScene.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
});
pauseTransition.play();
}
}

Related

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

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

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();

addAll() method not working?

so maybe I'm not using the method how it's intended to be used but a video I watched by youtube user thenewboston used it exactly like this and it worked just fine. Help would be appreciated
package checkers;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import javafx.scene.Scene ;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.application.*;
import javafx.stage.*;
public class Checkers extends Application {
Stage window;
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Title");
HBox layout = new HBox();
Button startButton = new Button("Start");
Button quitButton = new Button("Quit");
layout.getChildren().addAll(startButton, quitButton);
Scene startScene = new Scene(layout, 400, 300);
window.setScene(startScene);
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
`
The error I am receiving is as follows -
"The method addAll(int, Collection) in the type List is not applicable for the arguments (Button, Button)"
You imported the wrong type of Button. You want import javafx.scene.control.Button; not import java.awt.Button;

Categories