is there a way to change the scene by setOnEndOfMedia in javafx ? .. i tried this but it's throwing a NullPointerException
void change(Event event){
try{
Node node=(Node) event.getSource();
Stage stage=(Stage) node.getScene().getWindow();
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("astrolabe/astrolabe_intro.fxml"));/* Exception */
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setFullScreenExitHint("");
stage.show();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
and calling change() on end of media like this
astrolabe_intro.setOnEndOfMedia(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("tewst");
Event e = new Event(null) ;
e.fireEvent(astrolabe_intro1, e);
change( e);
}
});
If the exception is coming from the FXMLLoader.load(...) line, the chances are that the path to the fxml file is wrong. Log the value of the URL you get from the call to getResource(...) to check.
But also:
Why do you need the event at all? The only place you use it in the change method is to get a node and get hold of the window. You presumably have other references to some nodes (I'm assuming this is a controller.) Why not just do
void change(){
try{
Node node= ... ;// any node in your scene will do....
Stage stage=(Stage) node.getScene().getWindow();
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("astrolabe/astrolabe_intro.fxml"));/* Exception */
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setFullScreenExitHint("");
stage.show();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
and then
astrolabe_intro.setOnEndOfMedia(new Runnable() {
#Override
public void run() {
change();
}
});
which in Java 8 you can abbreviate to
astrolabe_intro.setOnEndOfMedia(this::change);
Related
I need help to load first the animation of the button then execute the onAction method because when I click the button, the animation of the button is delayed... How to fix it?
here is the sample code:
public void viewStage(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Stage.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.getIcons().add(new Image("/img/Stage.png"));
stage.setTitle("New Stage");
stage.setScene(new Scene(root1));
stage.show();
} catch (Exception e){
System.out.println(e);
}
}
This method(abc) is called when a button is pressed in the first scene. What it does is it changes the scene to waitingScreen and calls another method waitscr()
public void abc(ActionEvent event)throws Exception{
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
//for changing the scene.
Parent administrator =
FXMLLoader.load(getClass().getResource("waitingScreen.fxml"));
stage.setScene(new Scene(administrator));
stage.show();
conn.close();
waiting_screen_Controller c = new waiting_screen_Controller();
c.waitscr(event);
What waitscr does is it starts a timer for 5 seconds and when the timer ends
it calls another method setscr() (maybe i could have started the timer in abc only)
public void waitscr(ActionEvent event)throws IOException{
timetask = new TimerTask(){
#Override
public void run() {
if(!timing){
try{
timetask.cancel();
setscr(event);
}
catch(Exception ex){
ex.printStackTrace();
}
}
else
timing = updateTime();
}
};
timer.scheduleAtFixedRate(timetask,1000,1000);
}
it updates the time
public boolean updateTime(){
System.out.println(s);
if(s==0){
return false;
}
s--;
return true;
}
what setscr does is it changes the scene back to the first one..
public void setscr(ActionEvent event)throws IOException{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("first.fxml"));
Parent parent = loader.load();
Scene s=new Scene(parent);
stage = (Stage)((Node) event.getSource()).getScene().getWindow();
System.out.print(event.getSource());
stage.setScene(s);
stage.show();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
But the problem is it gives npe in stage.
java.lang.NullPointerException
at sample.waiting_screen_Controller.setscr(waiting_screen_Controller.java:106)
at sample.waiting_screen_Controller$1.run(waiting_screen_Controller.java:45)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
I thought this was because of ActionEvent because npe is at stage but i printed the source of ActionEvent and it is not null.
You're replacing the scene before calling waitscr. This way when you call Scene.getWindow the scene is no longer associated with a window and the result is null.
You shouldn't do this from a non-application thread anyways.
By retrieving the window only once and using a Platform.runLater you should be able to fix this issue:
public void abc(ActionEvent event)throws Exception{
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
...
c.waitscr(stage);
public void waitscr(final Stage stage) throws IOException {
timetask = new TimerTask(){
#Override
public void run() {
if(!timing){
try{
timetask.cancel();
setscr(stage);
} catch(Exception ex){
ex.printStackTrace();
}
}
else
timing = updateTime();
}
};
timer.scheduleAtFixedRate(timetask,1000,1000);
}
public void setscr(Stage stage)throws IOException{
// there seems to be a try missing somewhere
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("first.fxml"));
Parent parent = loader.load();
Scene s=new Scene(parent);
Platform.runLater(() -> {
// scene update on javafx application thread
stage.setScene(s);
stage.show();
});
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
How can I change the scene within the same window, rather than it opening a new window entirely.
Below is where the selectable options are added to a choicebox, with a listener at the end to "observe" when a selection is made, which, when clicked, changes the scene.
private void formulaOption2(){
list2.removeAll(list2);
String a = "Current Ratio";
String b = "Working Capital Ratio";
String c = "Debt to Equity Ratio";
String d = "Gross Profit Margin";
list2.addAll(a,b,c,d);
ChoiceBox2.getItems().addAll(list2);
//A LISTENER TO OBSERVE WHEN USER SELECTS ITEM
ChoiceBox2.getSelectionModel().selectedItemProperty().addListener( (v, oldValue, newValue) -> {
try {
comboSelect2();
} catch (IOException ex) {
Logger.getLogger(Tab1FXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
} );
}
Below is the code that loads the FXML file:
public void comboSelect2() throws IOException {
if("Current Ratio".equals(ChoiceBox2.getSelectionModel().getSelectedItem())){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Tab2FXML.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setTitle("Current Ratio");
stage.setScene(new Scene(root1));
stage.show();
}
}
Just replace the root of the current scene with the new root you want:
public void comboSelect2() throws IOException {
if("Current Ratio".equals(ChoiceBox2.getSelectionModel().getSelectedItem())){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Tab2FXML.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
ChoiceBox2.getScene().setRoot(root1);
}
}
I have a basic JavaFX application, that opens as so
public class MyApplication extends Application {
private Stage stage;
public static void main(String[] args) {
Console.setDebug();
launch(args);
}
#Override
public void start(Stage primaryStage) {
// set stage as primary
stage = primaryStage;
stage.setFullscreen(true);
stage.show();
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
System.out.println("Closing application...");
}
});
}
}
Now to change screens i have this function, which i call
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
Scene scene = new Scene(screen);
stage.setScene(scene);
stage.setFullscreen(true);
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}
Example call would be
public void goToHome() {
replaceScene("/fxml/HomeView.fxml", new HomeController());
}
Now when i run the application, the first screen is in fullscreen mode, then when i change screens, the screen resizes to window size, then changes again to full screen??? I have tried adding
stage.setFullscreen(false);
before i call
stage.setFullscreen(true);
but this does work either. How can i change screens/scenes without it resizing?
Also is is possible to toggle full screen mode using code, say if i want the user to be able to select full screen mode, can this be done?
This is the solution:
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
stage.getScene().setRoot(screen);
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}
Thanks to Mailkov for his code, nearly worked, but had to change it slightly, to cope with the first screen loading. This now works using
private void replaceScene(String resource, IControlledScreen controller) {
try {
controller.setApp(this);
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
loader.setController(controller);
Pane screen = (Pane) loader.load();
if (stage.getScene() == null) {
Scene scene = new Scene(screen);
stage.setScene(scene);
} else {
stage.getScene().setRoot(screen);
}
} catch (Exception e) {
System.out.println("Cannot load resource " + resource);
System.out.println(e.getMessage());
}
}
I have made a simple JavaFX application, but I would like the main window to open a secondary window when the user clicks a button.
What would be the simplest way to accomplish this?
Button b = new Button();
b.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
Stage stage = new Stage();
//Fill stage with content
stage.show();
}
});
try this
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("FXML.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
((Node) (event.getSource())).getScene().getWindow().hide();
} catch (Exception e) {
e.printStackTrace();
}