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();
}
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 want to make a window like eclipse loading by javafx without the bar ,
what I can do !!?
this loading screen
Just use this line. You won't see any title bar in your application.
stage.initStyle(StageStyle.UNDECORATED);
hihi,
you could try this:
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.initStyle(StageStyle.UNDECORATED);
scene.setFill(Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
I am new to JavaFX, here I want to create a new Stage and one TextArea inside it at the run-time and I want to pass a line to that text area and update it continuously.
Can anybody please give me the example of doing this?
Hyperlink link = new Hyperlink("TEST");
link.setOnAction(new EventHandler<ActionEvent>() {
#override public void handle(ActionEvent e) {
Stage stage = new Stage();
TextArea text = new TextArea():
VBox vbox = new VBox();
Button close = new Button();
close.setText("Close");
close.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
stage.close();
}
});
vbox.getChildren().addAll(text, close);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.setMinWidth(100);
stage.setMinHeight(100);
stage.show();
// ...
text.setText("update");
}
});