Here is the scenario, I have a main window and I click on one button it opens a pop up window. In this pop window I have table view that have some data display in it, and it have a one button called select. After select the data from table view, so when I push the select button I want this pop window to close and the data I selected from that to appear in my main window.
So far only thing I can do is extract the data from pop up window, I want it to close aswell with just one click
private void venueDisplay(String title, String message) {
Stage window = new Stage();
//Block events to other windows
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(400);
HBox hBox = new HBox();
hBox.setPadding(new Insets(10,10,10,10));
hBox.setSpacing(10);
hBox.setMaxHeight(20);
hBox.setAlignment(Pos.BOTTOM_CENTER);
hBox.getChildren().add(selectVenueButton);
//Display all the available venues to choose for allocation
VBox layout = new VBox(10);
venueList = new ListView<>();
ObservableList<Venue> observableVenue = FXCollections.observableArrayList(model.getVenues());
venueList.setItems(observableVenue);
layout.getChildren().addAll(venueList, hBox);
//Display window and wait for it to be closed before returning
Scene scene1 = new Scene(layout,300,500);
window.setScene(scene1);
window.showAndWait();
}
public void selectButtonHandler(EventHandler<ActionEvent> handler) {
selectVenueButton.setOnAction(handler);
}
Please consider this Example, you may take the idea and apply it to your program (Explanation in Comments).
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class GetInfoFromPopUpWindow extends Application{
static TextArea textArea = new TextArea(); // to be filled from the pop-up window
#Override
public void start(Stage primaryStage) throws Exception {
// create the main Window and some simple components
// Suppose it contains a TextArea only for simplicity sake
Button open = new Button("Open Popup Window");
//simple container as a root for testing
HBox root = new HBox();
root.getChildren().addAll(textArea, open);
Scene scene = new Scene(root,610,400);
primaryStage.setScene(scene);
primaryStage.setTitle("Main Window");
primaryStage.show();
//Add Action Listener to the open Button
open.setOnAction(e->{ // lambda expression, read more about it in the Documentation
popUpWindow(); // call the method to open a pop-up wondow(see later)
});
}
public static void popUpWindow(){
VBox root = new VBox();
Button fetchInfo = new Button("Finish");
//create a listView and populate it with some info for testing purpose
// suppose the info you get from some database
ListView<String> listView = new ListView<String>();
ObservableList<String> items = FXCollections.observableArrayList (
"First Item", "Second Item", "Third Item", "Fourth Item");
listView.setItems(items);
//to select more than one item
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
//decoration and size are up to your preference
listView.setPrefWidth(100);
listView.setPrefHeight(100);
root.getChildren().addAll(listView, fetchInfo);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 250,150);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setScene(scene);
stage.setTitle("Popup Window");
stage.show();
// Add action listener to fetchInfo Button in this Window
fetchInfo.setOnAction(e->{
// take the info from listView and fill it in the TextArea in the main Window
// just for testing purposes
for (String selectedItem : listView.getSelectionModel().getSelectedItems()){
textArea.appendText(selectedItem + " \n");
}
// when it finishes -> close the window and back to the first one
stage.close();
});
}
public static void main(String[] args) {
launch();
}
}
Test
Main Window Before Clicking Any Button
The Pop-Up Window After Clicking On The Button And Selecting Some Items
After Clicking on Finish Button, It Closes The Pop-Up Window and Then Goes Back To Main Menu With The Information (Selected Items)
I think you can just do:
private Venue venueDisplay(String title, String message) {
// existing code..
window.showAndWait();
return venueList.getSelectionModel().getSelectedItem();
}
and then your selectVenueButton just needs to close the window:
selectVenueButton.setOnAction(e -> window.hide());
you want to perform two operation on click select button
Close popup window :
To achieve this set Event Handler on button as below
selectVenueButton.setOnAction(handler);
In handler you can write logic to close popup window as below :
private EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
Object source = event.getSource();
if (source instanceof Button) {
Button btn = (Button) source;
Stage stage = (Stage) btn.getScene().getWindow();
stage.close();
}
}
};
After click on button you want selected data on main window :
To achieve this declare venue list on Class Level Scope (Member Variables), so you can access outside a class.
in Dialog class :
ListView<Venue> venueList;
Access data in main Window :
CustomDialog dialog = new CustomDialog(); //popup class
dialog.showDialog;
Venue selectedItem = dialog.venueList.getSelectionModel().getSelectedItems();
Related
I've just started using JavaFX and have been trying to add an event that will add text to a textarea and clear a text field when you press the 'send' button. However, I can't seem to check the source of the event in the handle method.
I've tried to search for a solution, but others don't seem to face the same issue - either that or I'm missing something obvious.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ApplicationMain extends Application implements EventHandler<ActionEvent>{
Stage window;
// Main Method
public static void main(String[] args) {
launch(args);
}
// Scene Method
#SuppressWarnings("static-access")
#Override
public void start(Stage primaryStage) {
// Window Stuff
window = primaryStage;
window.setTitle("Chat Application");
// Setup Grid Layout
GridPane grid = new GridPane();
grid.setAlignment(Pos.TOP_LEFT);
grid.setHgap(10);
grid.setStyle("-fx-background-color: #272828;");
// MenuBar
MenuBar menu = new MenuBar();
menu.setPrefWidth(1000);
menu.setPrefHeight(20);
// Creation of File + Help
Menu file = new Menu("File");
Menu help = new Menu("Help");
// Add the Menus to the MenuBar
menu.getMenus().add(file);
menu.getMenus().add(help);
// Add MenuBar to Scene
menu.setVisible(true);
grid.add(menu, 0, 0);
// Text Area Stuff
TextArea area = new TextArea();
area.setPrefWidth(1000);
area.setPrefHeight(700);
area.setEditable(false);
area.setStyle("-fx-control-inner-background: #313233;");
// Add Text Area to Grid
grid.add(area, 0, 1);
// Text Field
TextField enter = new TextField();
enter.setPromptText("Type here...");
enter.setMaxWidth(920);
enter.setMaxHeight(30);
enter.setStyle("-fx-padding: 5px;");
// Button
Button send = new Button("Send!");
// Set the Handler for the Send Button Event
send.setOnAction(this);
// Use of HBox to Space out Text Field & Send Button
HBox row = new HBox();
row.setSpacing(10);
row.setHgrow(enter, Priority.ALWAYS);
row.getChildren().addAll(enter, send);
// Use of VBox to Space out Text Field
VBox box = new VBox();
box.setSpacing(10);
box.setPadding(new Insets(10));
box.getChildren().add(row);
// Add HBox in VBox to Grid
grid.add(box, 0, 2);
// Scene Stuff
Scene scene = new Scene(grid, 1000, 750);
window.setScene(scene);
// Display the Window
window.show();
}
// Event Handler
#Override
public void handle(ActionEvent event) {
if (event.getSource() == send) {
}
}
}
Whenever I try to check if the source was the button 'send', it doesn't show up - as if it's not accessible by the method. I'm unsure of how to fix this.
There is a few things wrong with this code but we can fix it no problemo.
First learn naming conventions and stick to them as #kleopatra says if you google java naming conventions you will be overloaded with many results read a few
Next you shouldn't call a Stage a window there is already another object that has that name so it may confuse others but if its only for you its ok I guess
I wouldn't #SuppressWarnings("static-access") as you have done if you have an error fix it don't ignore it
The send.setOnAction(this); is not the way to handle events remove your implements EventHandler<ActionEvent> you can use the event handler by setting it like this
send.setOnAction(event -> sendToTextArea(enter.getText(), area));
And this is what the method you are calling should look like
private void sendToTextArea(String string, TextArea textArea){
//textArea.setText(string);Use setText if you want to set the whole area to something
textArea.appendText(string+"\n");//Use appendText to append add new line because chat app
}
Eveything else looks good here is what your final product should look like
public class Main extends Application {
private Stage stage;
#Override
public void start(Stage primaryStage) {
// stage Stuff
stage = primaryStage;
stage.setTitle("Chat Application");
// Setup Grid Layout
GridPane grid = new GridPane();
grid.setAlignment(Pos.TOP_LEFT);
grid.setHgap(10);
grid.setStyle("-fx-background-color: #272828;");
// MenuBar
MenuBar menu = new MenuBar();
menu.setPrefWidth(1000);
menu.setPrefHeight(20);
// Creation of File + Help
Menu file = new Menu("File");
Menu help = new Menu("Help");
// Add the Menus to the MenuBar
menu.getMenus().add(file);
menu.getMenus().add(help);
// Add MenuBar to Scene
menu.setVisible(true);
grid.add(menu, 0, 0);
// Text Area Stuff
TextArea area = new TextArea();
area.setPrefWidth(1000);
area.setPrefHeight(700);
area.setEditable(false);
area.setStyle("-fx-control-inner-background: #313233;");
// Add Text Area to Grid
grid.add(area, 0, 1);
// Text Field
TextField enter = new TextField();
enter.setPromptText("Type here...");
enter.setMaxWidth(920);
enter.setMaxHeight(30);
enter.setStyle("-fx-padding: 5px;");
// Button
Button send = new Button("Send!");
// Set the Handler for the Send Button Event
send.setOnAction(event -> sendToTextArea(enter, area));
// Use of HBox to Space out Text Field & Send Button
HBox row = new HBox();
row.setSpacing(10);
row.setHgrow(enter, Priority.ALWAYS);
row.getChildren().addAll(enter, send);
// Use of VBox to Space out Text Field
VBox box = new VBox();
box.setSpacing(10);
box.setPadding(new Insets(10));
box.getChildren().add(row);
// Add HBox in VBox to Grid
grid.add(box, 0, 2);
// Scene Stuff
Scene scene = new Scene(grid, 1000, 750);
stage.setScene(scene);
// Display the stage
stage.show();
}
private void sendToTextArea(TextField textField, TextArea textArea){
//textArea.setText(string);Use setText if you want to set the whole area to something
//textArea.clear();and .clear to clear all text from the TextArea
textArea.appendText(textField.getText()+"\n");//Use appendText to append add new line because chat app
textField.clear();
}
public static void main(String[] args) { launch(args); }
}
Make your TextArea and TextField class variables:
private TextArea area;
private TextField enter;
Change their initialization:
// Text Area Stuff
area = new TextArea();
// Text Field
enter = new TextField();
And your event handler :
// Event Handler
#Override
public void handle(ActionEvent event) {
area.setText(enter.getText());
}
If any of these changes is not clear, do not hesitate to ask.
I want to solve my homework and I don't know how to start; the goal is to make 2 GUI Forms in JavaFX. The 1st is home form that contains Button1, and when the user clicks Button1 : show the 2nd Form and close the 1st.
How to do that ? hope to give me examples.
Thanks for reading and helping.
You can do something like this, but please keep in mind that we learn via practicing and training, try to do your own one after having a look at the idea in this example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TwoForms extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane(); // TLC (Top Layer Container) a root container for all other components, which in your case is the Button
Button button = new Button("Go To Second Form"); // the button
root.getChildren().add(button); // add the button to the root
Scene scene = new Scene(root, 500,500); // create the scene and set the root, width and height
primaryStage.setScene(scene); // set the scene
primaryStage.setTitle("First Form");
primaryStage.show();
// add action listener, I will use the lambda style (which is data and code at the same time, read more about it in Oracle documentation)
button.setOnAction(e->{
//primaryStage.close(); // you can close the first stage from the beginning
// create the structure again for the second GUI
// Note that you CAN use the previous root and scene and just create a new Stage
//(of course you need to remove the button first from the root like this, root.getChildren().remove(0); at index 0)
StackPane root2 = new StackPane();
Label label = new Label("Your are now in the second form");
root2.getChildren().add(label);
Scene secondScene = new Scene(root2, 500,500);
Stage secondStage = new Stage();
secondStage.setScene(secondScene); // set the scene
secondStage.setTitle("Second Form");
secondStage.show();
primaryStage.close(); // close the first stage (Window)
});
}
public static void main(String[] args) {
launch();
}
}
Result
After Clicking on the Button -> Second Window.
I recently picked up javaFx and I am trying to learn in on my own. I have this few clases that were created to mess around with the GUI I am creating, said classes are:
Library, AccHolder, Bibliography.
A library can have many AccHolders and Many Bibliography,
then I have these two classes:
import java.util.ArrayList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application{
Stage window;
Button b1;
AccHolder userInputFromAcc;
public static void main(String[] args){
launch(args);
}
#Override
public void start(Stage primaryStage){
Library lib = new Library();
window = primaryStage;
window.setTitle("Main Window");
b1 = new Button("Press Me!");
b1.setOnAction(
e->{
userInputFromAcc = MainWindow.display("New Card Holder");
lib.addAccount(userInputFromAcc);
lib.printAllAccounts();
});
StackPane layout = new StackPane();
layout.getChildren().add(b1);
Scene scene = new Scene(layout,1300, 650);
window.setScene(scene);
window.show();
}
}
and
import java.util.ArrayList;
import javafx.beans.binding.BooleanBinding;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MainWindow {
private static AccHolder x;
public static AccHolder display(String title){
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
ArrayList<String> list = new ArrayList<>();
GridPane grid1 = new GridPane();
grid1.setPadding(new Insets(10,10,10,10));
grid1.setVgap(8);
grid1.setHgap(10);
//Aplicants's name and text field:
Label apNameLabel = new Label("Aplicant's Name: ");
GridPane.setConstraints(apNameLabel, 0,0);
TextField apNameInput = new TextField();
GridPane.setConstraints(apNameInput, 2,0);
apNameInput.setPromptText("Name");
//Aplicant's age
Label apAgeLabel = new Label("Aplicant's Age: ");
GridPane.setConstraints(apAgeLabel, 0,1);
TextField apAgeInput = new TextField();
GridPane.setConstraints(apAgeInput, 2,1);
apAgeInput.setPromptText("Enter Age ");
//Aplicant's ID card
Label apIDlabel = new Label("Aplicant's ID Card Number: ");
GridPane.setConstraints(apIDlabel, 0,2);
TextField apIDInput = new TextField();
GridPane.setConstraints(apIDInput, 2,2);
apIDInput.setPromptText("Enter ID ");
Button b1 = new Button("Create Account");
GridPane.setConstraints(b1, 0,6);
BooleanBinding bb= new BooleanBinding(){
{
super.bind(apNameInput.textProperty(),
apAgeInput.textProperty(),
apIDInput.textProperty());
}
#Override
protected boolean computeValue() {
return (apNameInput.getText().isEmpty()
|| apAgeInput.getText().isEmpty()
|| apIDInput.getText().isEmpty());
}
};
b1.disableProperty().bind(bb);
b1.setOnAction(e->{
String a,c;
int b = 0;
a = apNameInput.getText();
try{
b = Integer.parseInt(apAgeInput.getText());
} catch(Exception e1){
apAgeInput.setText("");
}
c = apIDInput.getText();
// Save User Input into an array list.
x = new AccHolder(a, b, c);
window.close();
} );
Button b2 = new Button("Close");
GridPane.setConstraints(b2, 1,6);
b2.setOnAction(e-> window.close() );
grid1.getChildren().addAll(apNameLabel, apNameInput, apAgeLabel, apAgeInput, apIDlabel, apIDInput, b1, b2);
Scene scene = new Scene(grid1, 500, 200);
window.setScene(scene);
window.setResizable(false);
window.show();
return x;
}
}
Basically the button in the main opens the second window, that window has the textfields to be filled with the user info, whati intended was to return those values after being collected and create an object of tipe AccHolder in the Main and save it to lib.
I ran into several complications, one of them being that as soon as the first button is pressed the program gives me an error as if the information is not being collected from Window 2 and passed to Window 1.
Notice that I never wanted to create an object in window 2, my main idea was to collect info in its pure form and then pass it to window 1, then create the object in window 1(Main).
I am really new to javaFx and lanmda expressions, therefore I might not be using them effectively. Here is a part of the error that prints out as soon as I press b1 on window 1:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at Library.printAllAccounts(Library.java:45)
at Main.lambda$0(Main.java:30)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)...
etc
Have no clue why is this happening, this is really stalling my learning process.
In MainWindow.display() you do not set the variable x until the button b1 is actually pressed. However, you return the value immediately after showing the window. So the returned value will be null.
You haven't actually posted the code that throws the exception (line 45 of Library), but I assume it tries to call a method on the value passed into the addAccount method (which is null, as explained above).
Instead of calling
window.show();
in MainWindow.display(), call
window.showAndWait();
This will show the window and block execution until it closes.
There may be other errors, but this is most likely what is causing the null pointer exception you observed.
Trying to use event handlers to sync specific button pushes to advance to the next "screen" on an ATM by: hiding the stage, updating the stage with the scene that a button push creates, and then reshowing the stage.
I am curious if this process can only be taken so deep since my button for newCheckingsAccounts isn't doing anything like it should, but I can go backwards on that page and I used the same code more or less to try to keep going forward.
import java.awt.Insets;
import java.util.ArrayList;
import java.util.Scanner;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class TestAccount extends Application {
//creates arrays that will store the accounts
ArrayList<Account> Checking = new ArrayList<Account>();
ArrayList<Integer> Savings = new ArrayList<Integer>();
//declares variables
double interest = 0;
double interestRate = 0;
double balance = 0;
double credit = 0;
double initialBalance = 0;
double feeChargedPerTransaction = 0;
Button btMain = new Button("Go Back to Main Menu");
Button btNewAccount = new Button("Make New Account");
Button btExistingAccount = new Button("Access an Existing Account");
Button btNewCheckings = new Button("Make New Checkings");
Button btNewSavings = new Button("Make New Savings");
#Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Hold two buttons in an HBox
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btGoToAccounts = new Button("Go To Accounts Page");
Button btEnd = new Button("End Program");
hBox.getChildren().add(btGoToAccounts);
hBox.getChildren().add(btEnd);
BorderPane borderPane = new BorderPane();
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
// Create a scene and place it in the stage
Scene scene = new Scene(borderPane, 500, 300);
primaryStage.setTitle("Bank of America"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
// creates and registers handler and specifies action for button to go to accounts page
btGoToAccounts.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
primaryStage.hide();
// Hold three buttons in an HBox
HBox hBox1 = new HBox();
hBox1.setSpacing(10);
hBox1.setAlignment(Pos.CENTER);
hBox1.getChildren().add(btNewAccount);
hBox1.getChildren().add(btExistingAccount);
hBox1.getChildren().add(btMain);
BorderPane borderPane1 = new BorderPane();
borderPane1.setBottom(hBox1);
BorderPane.setAlignment(hBox1, Pos.CENTER);
Scene scene1 = new Scene(borderPane1, 500, 300);
primaryStage.setTitle("Accounts Page"); // Set the stage title
primaryStage.setScene(scene1); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
});
// creates and registers handler and specifies action for button to go to create new accounts page
btNewAccount.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
primaryStage.hide();
// Hold three buttons in an HBox
HBox hBox2 = new HBox();
hBox2.setSpacing(10);
hBox2.setAlignment(Pos.CENTER);
Button btNewCheckings = new Button("Make New Checkings");
Button btNewSavings = new Button("Make New Savings");
hBox2.getChildren().add(btNewCheckings);
hBox2.getChildren().add(btNewSavings);
hBox2.getChildren().add(btMain);
BorderPane borderPane2 = new BorderPane();
borderPane2.setBottom(hBox2);
BorderPane.setAlignment(hBox2, Pos.CENTER);
Scene scene2 = new Scene(borderPane2, 800, 300);
primaryStage.setTitle("New Accounts"); // Set the stage title
primaryStage.setScene(scene2); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
});
// THIS IS THE BUTTON THAT DOESN'T REGISTER AS BEING CLICKED...havent done the newSavingsAccount button either.want it to take me to new scene where i enter in new account info hit submit and then take me back to the main menu ("scene")
btNewCheckings.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
HBox hbox3 = new HBox();
Scene scene3 = new Scene(hbox3, 800, 300);
primaryStage.setTitle("Test"); // Set the stage title
primaryStage.setScene(scene3); // Place the scene in the stage
//the Name text field
final TextField name = new TextField();
name.setPromptText("Enter the desired account name which will be used under the access an existing account screen later");
name.setPrefColumnCount(10);
name.getText();
hbox3.getChildren().add(name);
//Defining the initial balance/fee text fields
final TextField initialBalance = new TextField();
final TextField fee = new TextField();
initialBalance.setPromptText("Enter your desired initial balance as a double.");
fee.setPromptText("Enter the agreed upon fee per transaction as a double.");
initialBalance.setPrefColumnCount(15);
fee.setPrefColumnCount(15);
fee.getText();
hbox3.getChildren().add(fee);
initialBalance.getText();
hbox3.getChildren().add(initialBalance);
//Defining the Submit button
Button accountCreation = new Button("Create the Account");
hbox3.getChildren().add(accountCreation);
//Defining the Clear button
Button clear = new Button("Clear");
hbox3.getChildren().add(clear);
primaryStage.show(); // Display the stage
//Setting an action for the Submit button
accountCreation.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
if ((initialBalance.getText() != null && !initialBalance.getText().isEmpty())) {
CheckingAccount newMember = new CheckingAccount();
newMember.setInitialBalance(Double.parseDouble(initialBalance.toString()));
newMember.setFee((Double.parseDouble(fee.toString())));
Checking.add(newMember);
} else {
System.out.println("no member added");
}
}
});
//Setting an action for the Clear button
clear.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
name.clear();
initialBalance.clear();
}
});
}
});
// creates and registers handler and specifies action for end button to close the stage
btEnd.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
primaryStage.close();
}
});
// creates and registers handler and specifies action for main menu button to go to first scene
btMain.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
primaryStage.hide();
primaryStage.setTitle("Bank of America"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
});
}
/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}
I think removing the overriding of your both buttons in the btNewAccount.setOnAction() should solve your problem:
// creates and registers handler and specifies action for button to go
// to create new accounts page
btNewAccount.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.hide();
// Hold three buttons in an HBox
HBox hBox2 = new HBox();
hBox2.setSpacing(10);
hBox2.setAlignment(Pos.CENTER);
// ############### removed this ###################
//Button btNewCheckings = new Button("Make New Checkings");
//Button btNewSavings = new Button("Make New Savings");
hBox2.getChildren().add(btNewCheckings);
hBox2.getChildren().add(btNewSavings);
hBox2.getChildren().add(btMain);
BorderPane borderPane2 = new BorderPane();
borderPane2.setBottom(hBox2);
BorderPane.setAlignment(hBox2, Pos.CENTER);
Scene scene2 = new Scene(borderPane2, 400, 300);
primaryStage.setTitle("New Accounts"); // Set the stage title
primaryStage.setScene(scene2); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
});
If you want to instantiate in an ActionHandler of a Button, you need to declare it's ActionHandler in the same Block.
The way you did it (ActionHandler in the start method), it will only work, if you use your class atributes (Buttons) which you have initialized at the top.
Hope I could help :)
Edit: Probably a good tip for this project is looking at FXML files with JavaFX. This might help you: http://code.makery.ch/library/javafx-8-tutorial/part1/
So I'm running a little test application to see if this possible and then move it to my main project. The main idea is that the dialog box come from the top of the screen to the center and waits for a response from the the user. If they click no, the program terminates. If they click yes, the dialog box goes from the center to the top screen and is out of sight from the user.
package test;
import java.util.Optional;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.VBox;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.VLineTo;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Test extends Application
{
#Override
public void start(Stage stage) throws Exception
{
VBox root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
Path path = new Path();
path.getElements().add(new MoveTo(300, -25));
path.getElements().add(new VLineTo(200));
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(1500));
pathTransition.setPath(path);
pathTransition.setNode(alert); // This is where the problem lies.
pathTransition.setCycleCount(1);
pathTransition.play();
Scene scene = new Scene(root, 640, 480);
stage.setScene(scene);
stage.show();
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK)
{
Path path2 = new Path();
path2.getElements().add(new MoveTo(300, 200));
path2.getElements().add(new VLineTo(-25));
PathTransition pathTransition2 = new PathTransition();
pathTransition.setDuration(Duration.millis(1500));
pathTransition.setPath(path);
pathTransition.setNode(alert);
pathTransition.setCycleCount(1);
pathTransition.play();
}
else
{
stage.close();
}
}
public static void main(String[] args)
{
launch(args);
}
}
There's a way that you can move the alert dialog, by means of its yProperty(). Instead of a path transition we'll use a timeline to set this property. But since this is a read only property, we havet to use a DoubleProperty within the transition instead and use Alert.setY().
The first part of your question, sliding in the dialog, is easy. The second, sliding out, is more complex, since the dialog is closed inmediately once a button is clicked.
Solution 1. Just sliding in
We need the dialog dimensions and position, and for that we need to show it. This means it will be shown, and inmediately moved to the top of the screen.
So I'll change alert.showAndWait() for alert.show().
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->buttonBar.setDisable(false),
new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
alert.resultProperty().addListener((ob,r,r1)->{
if (r1 == ButtonType.OK){
// alert is closed and hidden in its final position
}
else{
primaryStage.close();
}
});
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
The listener in yProperty() allow us to set the position to the dialog within all the different positions interpolated during the transition.
Solution 2. Slide In and Out
This is a bit of a dirty solution, since involves using a second Alert dialog, given the original one is closed once the buttons are clicked. We'll add this second dialog behind the first one, and use it to create the slide out effect once the first one is closed.
The only side effect you will notice is a fast blink in the phase of showing the second and putting the first one on top of it.
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
Alert alertOut = new Alert(AlertType.CONFIRMATION);
alertOut.setTitle("Confirmation Dialog");
alertOut.setHeaderText("Look, a Confirmation Dialog");
alertOut.setContentText("Are you ok with this?");
alertOut.initModality(Modality.NONE);
((Stage)alertOut.getDialogPane().getScene().getWindow()).setOpacity(0);
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->{
buttonBar.setDisable(false);
// show second dialog
alertOut.show();
// move to front the first one
((Stage)alert.getDialogPane().getScene().
getWindow()).toFront();
}, new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
alert.resultProperty().addListener((ob,r,r1)->{
if (r1 == ButtonType.OK){
// show second dialog
((Stage)alertOut.getDialogPane().getScene().getWindow()).setOpacity(1);
ButtonBar buttonBarOut=(ButtonBar)alertOut.getDialogPane().lookup(".button-bar");
buttonBarOut.setDisable(true);
final DoubleProperty yPropertyOut = new SimpleDoubleProperty(yEnd);
yPropertyOut.addListener((ov,n,n1)->alertOut.setY(n1.doubleValue()));
// Create slide out transition
Timeline timeOut = new Timeline();
timeOut.getKeyFrames().add(
new KeyFrame(Duration.seconds(1.5),
e->alertOut.close(),
new KeyValue(yPropertyOut, yIni,Interpolator.EASE_BOTH)));
timeOut.play();
}
else{
alertOut.close();
primaryStage.close();
}
});
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
EDIT
Solution 2. Improved Slide In and Out
I've found the way to use one single dialog, and provide the slide out effect too.
All it takes is trap the click action on the selected button, consume the event, add the slide out transition there, and hide the dialog on finished.
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Sliding In Alert Dialog");
btn.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Look, a Confirmation Dialog");
alert.setContentText("Are you ok with this?");
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setDisable(true);
alert.initModality(Modality.APPLICATION_MODAL);
alert.show();
// now we can retrive alert bounds:
double yIni=-alert.getHeight();
double yEnd=alert.getY();
// and move alert to the top of the screen
alert.setY(yIni);
buttonBar.getButtons().stream().filter(b->((Button)b).isDefaultButton()).findFirst()
.ifPresent(b->((Button)b).addEventFilter(EventType.ROOT,
e->{
if(e.getEventType().equals(ActionEvent.ACTION)){
e.consume();
final DoubleProperty yPropertyOut = new SimpleDoubleProperty(yEnd);
yPropertyOut.addListener((ov,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeOut = new Timeline();
timeOut.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), t->alert.close(),
new KeyValue(yPropertyOut, yIni,Interpolator.EASE_BOTH)));
timeOut.play();
}
}));
final DoubleProperty yProperty = new SimpleDoubleProperty();
yProperty.addListener((ob,n,n1)->alert.setY(n1.doubleValue()));
Timeline timeIn = new Timeline();
timeIn.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), e->{
buttonBar.setDisable(false);
},new KeyValue(yProperty, yEnd,Interpolator.EASE_BOTH)));
timeIn.play();
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}