I have a window with a button. Clicking this button opens a modal window.
Now, I want to close this second window by clicking a button, but I can't figure out how.
public class StartMenu extends Application {
#Override
public void start(Stage primaryStage) {
final Button b = new Button("Go");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
AnotherWindow aw = new AnotherWindow ();
aw.start(stage);
}
});
((Group) scene.getRoot()).getChildren().add(b);
primaryStage.setScene(scene);
primaryStage.show();
}}
public class AnotherWindow extends Application {
#Override
public void start(Stage primaryStage) {
final Button b = new Button("Back");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
//Code to close window
}
});
((Group) scene.getRoot()).getChildren().add(b);
primaryStage.setScene(scene);
primaryStage.show();
}}
I found the following post by Krzysztof Sz. that helped me find the solution.
public class AnotherWindow extends Application {
#Override
public void start(Stage primaryStage) {
final Button b = new Button("Back");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
((Button)t.getTarget()).getScene().getWindow().hide();
}
});
((Group) scene.getRoot()).getChildren().add(b);
primaryStage.setScene(scene);
primaryStage.show();
}}
It is the following piece of code that let's me close the current (modal) window when the button is clicked:
((Button)t.getTarget()).getScene().getWindow().hide();
You want to close a modal window from a click on a different window? If a modal window is visible, how will you get back to the other window?
You might want to use one window: when a button is clicked, hide all the controls in that window and make visible the information you wanted to have in your modal window, along with a button to click. When that button is clicked, reset the window to its' original state.
This just becomes an exercise in showing/hiding controls in a container.
Related
public class Testing extends Application {
#Override
public void start(Stage stage)
{
Button button1 = new Button("First button");
Button button2 = new Button("Second button");
EventHandler<ActionEvent> aHandler = new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event)
{
button2.setText("Working");
}
};
button1.addEventHandler(ActionEvent.ACTION, aHandler);
HBox hbox = new HBox(40,button1, button2);
Scene scene = new Scene(hbox, 840, 400);
stage.setScene(scene);
stage.setTitle("Testing");
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
You can see that this is a javafx Testing class where I am testing eventHandlers and it works fine but when I split the code and add it into on its own methods then the eventHandlers does not work like in the code below
public class Testing extends Application {
#Override
public void start(Stage stage)
{
EventHandler<ActionEvent> aHandler = new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event)
{
button2().setText("Working");
}
};
button1().addEventHandler(ActionEvent.ACTION, aHandler);
stage.setScene(scene());
stage.setTitle("Testing");
stage.show();
}
public Button button1()
{
Button btn = new Button("First button");
return btn;
}
public Button button2()
{
Button btn = new Button("Second button");
return btn;
}
public HBox hbox()
{
HBox hbox = new HBox(40,button1(), button2());
return hbox;
}
public Scene scene()
{
Scene scene = new Scene(hbox(), 840, 400);
return scene;
}
public static void main(String[] args)
{
launch(args);
}
}
Now this code does not work. Please help.
Please note: If any one have another idea to encapsulate eventHandlers then please mention it if you can because my goal is to define eventHandlers in one class and registering it in another class.
Thank you.
Of course it's not working, you are creating an instance of Button every call to button1() and button2(). The instance of button1 and button2 in the HBox are different instances from the one you added the event handler.
I definitely recommend not splitting like what you are doing. This kind of splitting makes it hard to troubleshoot problems, and you are creating new instances whenever you call any of those methods. Stick to what you are doing originally.
I'm trying to close popup window by button, but I don't have any idea.
When I used Java Swing, I remember the function was automatic...
So.. What should I do?
And I also want to make more space between button and text. If you have any idea, please help me.
Stage dialogStage = new Stage();
dialogStage.initModality(Modality.WINDOW_MODAL);
Button button = new Button();
button.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.ENTER) {
}
}
});
VBox vbox = new VBox(new Text("Wrong ID & PW!!"), new Button("Ok."));
vbox.setAlignment(Pos.CENTER);
vbox.setPadding(new Insets(15));
dialogStage.setScene(new Scene(vbox));
dialogStage.show();
Call dialogStage.close()
button.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.ENTER) {
dialogStage.close();
}
}
});
Also you are adding a new Button("Ok.") to the VBox which is wrong, add the button which you created before
As for the space between the button and text, this should work
VBox.setMargin(text, new Insets(20));
VBox.setMargin(button, new Insets(20));
I made a custom Minimize button this way:
public MinimizeButton() {
Button button = new Button("-");
button.getStyleClass().clear();
button.getStyleClass().add("actionbutton");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage stage = (Stage) ((Button) event.getSource()).getScene().getWindow();
stage.setIconified(true);
}
});
this.getChildren().add(button);
}
And I obviously called
primaryStage.initStyle(StageStyle.UNDECORATED);
The button is working well.
The issue is that when I try to maximize the Window once the Stage is iconified, it takes a couple of seconds for the Window to redraw the Stage.
Any ideas on how to make the "Maximizing process" of the Window faster?
Fixed it by using
primaryStage.initStyle(StageStyle.TRANSPARENT);
instead of
primaryStage.initStyle(StageStyle.UNDECORATED);
Let's say I want to create a method that adds a button to a StackPane. then I want to access to that button, for exemple I want to add an EventHandler from the main:
public class Test extends Application {
#Override
public void start(Stage primaryStage) throws ParseException {
StackPane root = new StackPane();
addButton(root);
// HERE I WANT TO ADD AN EVENT HANDLER TO b BUT I CANNOT ACCESS IT
// b.addEventHandler();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public void addButton(StackPane sp){
final Button b = new Button("Test");
sp.getChildren().add(b);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Add event handler to the button when you creating the button
public void addButton(StackPane sp){
final Button b = new Button("Test");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
//your logic
}});
sp.getChildren().add(b);
}
Since button is local to your addButton you need to have a reference to it. Return the reference of your button from addButton method and use it.
It would be better to use it this way
public Button addButton(){
//create Button
}
You can add this button to the StackPane in your start()
Alternatively,
This approach is not recommended.
You can get the Button out of the StackPane
Button button = (Button)root.getChildren().get(0);
N.B. Use this only if you are sure of the position of the Button
UPDATE
If you just want to separate your design from the action performed by the controls, JavaFX provides an eligant way to do it, using FXML.
It helps you to design the UI without any indulgence of the actions that they need to perform. And later, these FXML's can be binded to their actions through Controllers(Java Interface)
Scope the UI controls to the instance of the application class, instead of making them local to the method.
public class Test extends Application {
private Button b ;
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane();
addButton(root);
b.addEventHandler(...);
// ...
}
private void addButton(Pane pane) {
b = new Button("Test");
pane.getChildren().add(b);
}
// ...
}
Or, if you really want to separate the layout from the event handling, do the layout in FXML and inject the controls into a controller class, which can be responsible for the event handlers.
I am attempting to create a scene with multiple buttons and I am having some issues.
What I have now is this:
public class Tester extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn1 = new Button();
btn1.setText("Start Game");
Button btn2 = new Button();
btn2.setText("Exit");
btn2.setOnAction(new EventHandler<ActionEvent>());
btn1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Game Start");
}
});
Pane root = new Pane();
btn1.setLayoutX(500);
btn1.setLayoutY(530);
root.getChildren().add(btn1);
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();
I am trying to figure out what I need to do to have a second button. At the moment, I cant seem to have a second event handler.
Any help will be greatly appreciated.
Here is an update to your program to:
Define an action (display "Wumpus Hunt Complete!") for the second button.
Add the second button to the scene so that it can be seen.
The event handler for taking action for a button is an example of an anonymous inner class.
Sample Code:
Button btn1 = new Button();
btn1.setText("Start Game");
Button btn2 = new Button();
btn2.setText("Exit");
btn2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Wumpus Hunt Complete!");
}
});
btn1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Game Start");
}
});
Pane root = new Pane();
btn1.setLayoutX(500);
btn1.setLayoutY(530);
root.getChildren().add(btn1);
btn2.setLayoutX(500);
btn2.setLayoutY(630);
root.getChildren().add(btn2);
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();