I have a application that works with FXML files. Each time i want to load in another FXML file, i get a new instance of my Controller class. But i dont want that. How can i prevent this?
For instance: I just logged in on my login.fxml file and now the login.fxml file needs to close and the manageBanks.fxml file needs to show. What i programmed is that it looks at the current AnchorPane that is not NULL and gets the window from that pane, so i can close that stage. Then i load in the new .fxml file in my controller. But every time i load in a new .fxml file, the application creates a new instance of the controller. But i have an instance of my Client class in the Controller class (that is set in the constructor), and i dont want that instance to be renewed each time. I just want one instance of my Client class that the controller can speak to.
Here is my Controller class. At the bottom of this class are my methods to initialize the new stages:
public class Controller {
public TextField tbIban;
public TextField tbFirstName;
public TextField tbLastName;
public TextField tbPostalCode;
public TextField tbHouseNumber;
public TextField tbEmail;
public TextField tbBankName;
public TextField tbShortcut;
public TextField tbEuroIn;
public TextField tbCentIn;
public TextField tbCentOut;
public TextField tbEuroOut;
public TextField tbEuroAmount;
public TextField tbCentAmount;
public TextField tbNameReceiver;
public TextField tbIbanReceiver;
public TextArea tbDescription;
public PasswordField tbPassword;
public PasswordField tbRepeatPassword;
public Label lbName;
public Label lbIban;
public Label lbAmount;
public TableView tabelTransactions;
public TableView tabelAddresses;
public TableView tabelBanks;
public DatePicker dtpDateOfBirth;
public CheckBox cbAddToAddressBook;
public ComboBox cmbbank;
public AnchorPane screenEditAccount;
public AnchorPane screenAddressBook;
public AnchorPane screenAddressBookTransaction;
public AnchorPane screenBankAccount;
public AnchorPane screenCreateBank;
public AnchorPane screenCreateBankAccount;
public AnchorPane screenLimits;
public AnchorPane screenLogin;
public AnchorPane screenManageBanks;
public AnchorPane screenNewTransaction;
private Client client;
public Controller() {
try {
client = new Client();
System.out.println("Client: Client created");
} catch (RemoteException e) {
System.out.println("Client: Cannot create Client");
System.out.println("Client: RemoteException: " + e.getMessage());
System.exit(0);
}
}
public void login() {
String iban = tbIban.getText();
String password = tbPassword.getText();
try {
if (client.login(iban, password)){
if (iban.equals("admin")) {
changeScreenTo(Screens.MANAGEBANKS);
} else {
changeScreenTo(Screens.BANKACCOUNT);
}
} else {
showErrorMessage("Wrong username or password.");
}
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
}
public void logoutClient() {
try {
client.logout();
changeScreenTo(Screens.LOGIN);
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
}
public void logoutAdmin() {
try {
client.logout();
changeScreenTo(Screens.LOGIN);
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
}
public void cancelToLogin() {
changeScreenTo(Screens.LOGIN);
}
public void createBank() {
String name = tbBankName.getText();
String shortcut = tbShortcut.getText();
try {
if (client.createBank(name, shortcut)){
changeScreenTo(Screens.MANAGEBANKS);
} else {
showErrorMessage("Bank name or shortcut already excist.");
}
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
}
public void deleteBank() {
String bank = String.valueOf(tabelBanks.getSelectionModel().getSelectedItem());
String[] bankParts = bank.split(";");
String bankName = bankParts[0];
client.deleteBank(bankName);
}
public void createBankAccount() {
String password = tbPassword.getText();
String passwordRepeat = tbRepeatPassword.getText();
String firstName = tbFirstName.getText();
String lastName = tbLastName.getText();
String postalCode = tbPostalCode.getText();
int houseNumber = Integer.parseInt(tbHouseNumber.getText());
Date dateOfBirth = Date.from(dtpDateOfBirth.getValue().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
String email = tbEmail.getText();
String bankName = cmbbank.getValue().toString();
if (password.equals(passwordRepeat) && !password.equals("")){
if (!firstName.equals("") && !lastName.equals("") && !postalCode.equals("") && houseNumber != 0 && dateOfBirth.before(new Date()) && !email.equals("") && !bankName.equals("")){
try {
if (client.createBankAccount(bankName, password, firstName, lastName, postalCode, houseNumber, dateOfBirth, email)){
changeScreenTo(Screens.BANKACCOUNT);
} else {
showErrorMessage("Something went wrong with creating your account.");
}
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
} else {
showErrorMessage("Personal details are not valid or there is no bank selected.");
}
} else {
showErrorMessage("Password can not be empty or is not the same as repeated password.");
}
}
public void editBankAccount() {
String password = tbPassword.getText();
String passwordRepeat = tbRepeatPassword.getText();
String firstName = tbFirstName.getText();
String lastName = tbLastName.getText();
String postalCode = tbPostalCode.getText();
int houseNumber = Integer.parseInt(tbHouseNumber.getText());
Date dateOfBirth = Date.from(dtpDateOfBirth.getValue().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
String email = tbEmail.getText();
if (password.equals(passwordRepeat) && !password.equals("")){
if (!firstName.equals("") && !lastName.equals("") && !postalCode.equals("") && houseNumber != 0 && dateOfBirth.before(new Date()) && !email.equals("")){
try {
client.editBankAccount(password, firstName, lastName, postalCode, houseNumber, dateOfBirth, email);
changeScreenTo(Screens.BANKACCOUNT);
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
} else {
showErrorMessage("Personal details are not valid.");
}
} else {
showErrorMessage("Password can not be empty or is not the same as repeated password.");
}
}
public void deleteBankAccount() {
try {
client.deleteBankAccount();
changeScreenTo(Screens.LOGIN);
} catch (RemoteException e) {
showErrorMessage(e.getMessage());
}
}
public void cancelToBankAccount() {
changeScreenTo(Screens.BANKACCOUNT);
}
public void editBankAccountsLimits() {
double limitIn = Double.parseDouble(tbEuroIn.getText() + "," + tbCentIn.getText());
double limitOut = Double.parseDouble(tbEuroOut.getText() + "," + tbCentOut.getText());
if (limitIn > 0 && limitOut > 0){
client.editBankAccountsLimits(limitIn, limitOut);
changeScreenTo(Screens.BANKACCOUNT);
} else {
showErrorMessage("Limits can not be 0.");
}
}
public void deleteBankAccountsAddress() {
Address address = (Address) tabelAddresses.getSelectionModel().getSelectedItem();
client.deleteBankAccountsAddress(address);
}
public void makeBankAccountsTransaction() {
double amount = Double.parseDouble(tbEuroAmount.getText() + "," + tbCentAmount.getText());
String nameReceiver = tbNameReceiver.getText();
String ibanReceiver = tbIbanReceiver.getText();
String description = tbDescription.getText();
boolean addToAddress = cbAddToAddressBook.isSelected();
if (amount > 0 && !nameReceiver.equals("") && !ibanReceiver.equals("")){
client.makeBankAccountsTransaction(amount, nameReceiver, ibanReceiver, description, addToAddress);
changeScreenTo(Screens.BANKACCOUNT);
} else {
showErrorMessage("Amount and receiver details can not be empty.");
}
}
public void chooseAddress() {
Address address = (Address) tabelAddresses.getSelectionModel().getSelectedItem();
tbNameReceiver.setText(address.getName());
tbIbanReceiver.setText(address.getIban());
changeScreenTo(Screens.NEWTRANSACTION);
}
public void makeBankAccountsRequest() {
double amount = Double.parseDouble(tbEuroAmount.getText() + "," + tbCentAmount.getText());
String nameReceiver = tbNameReceiver.getText();
String ibanReceiver = tbIbanReceiver.getText();
String description = tbDescription.getText();
boolean addToAddress = cbAddToAddressBook.isSelected();
if (amount > 0 && !nameReceiver.equals("") && !ibanReceiver.equals("")){
client.makeBankAccountsRequest(amount, nameReceiver, ibanReceiver, description, addToAddress);
changeScreenTo(Screens.BANKACCOUNT);
} else {
showErrorMessage("Amount and receiver details can not be empty.");
}
}
public void openCreateAccount() {
changeScreenTo(Screens.CREATEBANKACCOUNT);
}
public void openAccount() {
changeScreenTo(Screens.ACCOUNT);
}
public void openLimits() {
changeScreenTo(Screens.LIMITS);
}
public void openAddressBook() {
changeScreenTo(Screens.ADDRESSBOOK);
}
public void openAddressBookTransaction() {
changeScreenTo(Screens.ADDRESSBOOKTRANSACTION);
}
public void openTransaction() {
changeScreenTo(Screens.NEWTRANSACTION);
}
public void openCreateBank() {
changeScreenTo(Screens.CREATEBANK);
}
private void initAccountScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/account.fxml"));
stage.setTitle("Account");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.BANKACCOUNT));
stage.show();
}
private void initAddressBookScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/addressBook.fxml"));
stage.setTitle("Address Book");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.BANKACCOUNT));
stage.show();
}
private void initAddressBookTransactionScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/addressBookTransaction.fxml"));
stage.setTitle("Address Book");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.NEWTRANSACTION));
stage.show();
}
private void initBankAccountScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/bankAccount.fxml"));
stage.setTitle("Bank Account");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> logoutClient());
stage.show();
}
private void initCreateBankScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/createBank.fxml"));
stage.setTitle("Create Bank");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.MANAGEBANKS));
stage.show();
}
private void initCreateBankAccountScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/createBankAccount.fxml"));
stage.setTitle("Create Bank Account");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.LOGIN));
stage.show();
}
private void initLimitsScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/limits.fxml"));
stage.setTitle("Limits");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.BANKACCOUNT));
stage.show();
}
private void initLoginScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/login.fxml"));
stage.setTitle("Login");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> System.exit(0));
stage.show();
}
private void initManageBanksScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/manageBanks.fxml"));
stage.setTitle("Manage Banks");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> logoutAdmin());
stage.show();
}
private void initnewTransactionScreen() throws IOException {
Stage stage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("Screens/newTransaction.fxml"));
stage.setTitle("New Transaction");
stage.setResizable(false);
stage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
stage.setScene(new Scene(root));
stage.setOnCloseRequest(event -> changeScreenTo(Screens.BANKACCOUNT));
stage.show();
}
private void showErrorMessage(String message){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("ERROR!");
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
private void changeScreenTo(Screens screen) {
if (screenEditAccount != null) {
Stage currentStage = (Stage) screenEditAccount.getScene().getWindow();
currentStage.close();
} else if (screenAddressBook != null) {
Stage currentStage = (Stage) screenAddressBook.getScene().getWindow();
currentStage.close();
} else if (screenAddressBookTransaction != null) {
Stage currentStage = (Stage) screenAddressBookTransaction.getScene().getWindow();
currentStage.close();
} else if (screenBankAccount != null) {
Stage currentStage = (Stage) screenBankAccount.getScene().getWindow();
currentStage.close();
} else if (screenCreateBank != null) {
Stage currentStage = (Stage) screenCreateBank.getScene().getWindow();
currentStage.close();
} else if (screenCreateBankAccount != null) {
Stage currentStage = (Stage) screenCreateBankAccount.getScene().getWindow();
currentStage.close();
} else if (screenLimits != null) {
Stage currentStage = (Stage) screenLimits.getScene().getWindow();
currentStage.close();
} else if (screenLogin != null) {
Stage currentStage = (Stage) screenLogin.getScene().getWindow();
currentStage.close();
} else if (screenManageBanks != null) {
Stage currentStage = (Stage) screenManageBanks.getScene().getWindow();
currentStage.close();
} else if (screenNewTransaction != null) {
Stage currentStage = (Stage) screenNewTransaction.getScene().getWindow();
currentStage.close();
}
try {
switch (screen) {
case ACCOUNT:
initAccountScreen();
break;
case ADDRESSBOOK:
initAddressBookScreen();
break;
case ADDRESSBOOKTRANSACTION:
initAddressBookTransactionScreen();
break;
case BANKACCOUNT:
initBankAccountScreen();
break;
case CREATEBANK:
initCreateBankScreen();
break;
case CREATEBANKACCOUNT:
initCreateBankAccountScreen();
break;
case LIMITS:
initLimitsScreen();
break;
case LOGIN:
initLoginScreen();
break;
case MANAGEBANKS:
initManageBanksScreen();
break;
case NEWTRANSACTION:
initnewTransactionScreen();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
And here is my Main class:
public class ClientMain extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Screens/login.fxml"));
primaryStage.setTitle("Login");
primaryStage.setResizable(false);
primaryStage.getIcons().add(new Image("file:assets/ideal_logo.jpg"));
primaryStage.setScene(new Scene(root));
primaryStage.setOnCloseRequest(event -> System.exit(0));
primaryStage.show();
}
}
Every time you load an FXML file, you get new instances of the UI elements defined in the FXML file. For example, your FXML file apparently has a large collection of <TextField> elements; for each of those <TextField> elements you get a new TextField instance created each time you load the FXML.
Since the controller typically has references to the UI elements defined in the FXML file, and/or has event handlers specific to those elements, a controller instance is specific to the instance of a UI loaded from a specific call to FXMLLoader.load().
As a consequence, it really makes no sense at all to share a single controller instance among multiple UIs loaded from multiple calls to FXMLLoader.load(). You should have a different controller instance for each, which is the default behavior.
Related
New to javafx in learning stage.I am trying to Update the data from the database but when the call the
getConnection method the list is updated but the Treeitem is not updated in the view.
On the first screen it shows the available Db's but after creating new the tree table view is not updating even after calling the getConnection();
marked the place where needed solution with "//-----------------Calling Here for Updation"
Tried
1.Used Refresh();
2.tried to clear the view;
PaneClass.java
public class PanesClass extends Application {
ObservableList<Connections> cList = FXCollections.observableArrayList();
DbConnection dbConnection = new DbConnection();
TreeItem rootItem = new TreeItem();
TreeTableView activeConnections = new TreeTableView();
AnchorPane firstPane = new AnchorPane();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
NewConnection newConnection = new NewConnection();
SplitPane root = new SplitPane();
AnchorPane secondPane = new AnchorPane();
HBox buttonBox = new HBox();
BorderPane topBar = new BorderPane();
Button nConnection = new Button("+");
buttonBox.getChildren().addAll(nConnection);
topBar.setTop(buttonBox);
TreeTableColumn<String, Connections> cNameColoumn = new TreeTableColumn<>("Name");
cNameColoumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
TreeTableColumn<String, Connections> cStatusColoumn = new TreeTableColumn<>("Status");
cStatusColoumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("status"));
activeConnections.getColumns().addAll(cNameColoumn, cStatusColoumn);
activeConnections.setLayoutX(20);
activeConnections.setLayoutY(40);
firstPane.getChildren().addAll(topBar, activeConnections);
root.getItems().addAll(firstPane, secondPane);
Scene sc = new Scene(root, 600, 480);
primaryStage.setScene(sc);
primaryStage.show();
activeConnections.setShowRoot(false);
getconnection();
nConnection.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
try {
newConnection.getConnection(activeConnections);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
});
}
void getconnection() throws ClassNotFoundException, SQLException {
rootItem.getChildren().clear();
cList.clear();
cList = dbConnection.getDatabase();
for (Connections temp : cList) {
rootItem.getChildren().add(new TreeItem<Connections>(temp));
System.out.println(temp);
}
activeConnections.setRoot(rootItem);
activeConnections.refresh();
}
}
NewConnection.java
public class NewConnection {
Connections connection = null;
ObservableList<Connections> cList = FXCollections.observableArrayList();
PanesClass panesClass = new PanesClass();
TreeItem<Connections> cItem = null;
TreeItem rootItem = new TreeItem();
public void getConnection(TreeTableView<Connections> activeConnections) throws ClassNotFoundException, SQLException {
DbConnection dbConnection=new DbConnection();
Stage secondaryStage = new Stage();
VBox root = new VBox();
GridPane cDetails = new GridPane();
HBox actionButtons = new HBox();
Button connect = new Button("Connect");
Button save = new Button("Save");
Button cancel = new Button("Cancel");
actionButtons.getChildren().addAll(connect, save, cancel);
//cList=dbConnection.getDatabase();
actionButtons.setSpacing(10);
Label name = new Label("Username : ");
cDetails.add(name, 0, 0);
TextField uName = new TextField();
cDetails.setHgrow(uName, Priority.ALWAYS);
cDetails.add(uName, 1, 0);
cDetails.setVgap(10);
root.getChildren().addAll(cDetails, actionButtons);
Scene sc = new Scene(root, 500, 200);
secondaryStage.setScene(sc);
secondaryStage.initModality(Modality.APPLICATION_MODAL);
secondaryStage.show();
save.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
try {
dbConnection.setNewDatabase(uName.getText());
panesClass.getconnection();//-----------------*Calling Here for Updation*
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
secondaryStage.close();
event.consume();
}
});
}
}
Connections.java
public class Connections {
private String name;
private String password;
private String url;
public Connections() {
super();
}
public Connections(String name, String password, String url) {
super();
this.name = name;
this.password = password;
this.url = url;
}
public Connections(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
#Override
public String toString() {
return "Connections [name=" + name + ", password=" + password + ", url=" + url + "]";
}
}
I get the error "java.lang.ClassCastException". I'm trying to make a calculator and with JAVAFX (with SceneBuilder - if that's necessary), and I can't trace where I did wrong on the code.
I'm trying to make a new window appear when the button "HISTORY" is clicked and it should show all the previous operations performed.
java.lang.ClassCastException: application.controller.MainWindowController cannot be cast to application.controller.HistoWindowController
MainWindowController is:
public class MainWindowController {
private Main main;
#FXML
TextField input1;
#FXML
TextField input2;
#FXML
Label showAnswer;
public void setMain(Main main){
this.main = main;
}
public void showAnswerSTR(String str) {
showAnswer.setText("Answer: " + str);;
}
#FXML
public void showHistory() {
main.HistoryViewer();
}
#FXML
public void addNumbers(){
Float inputA = Float.parseFloat(input1.getText());
Float inputB = Float.parseFloat(input2.getText());
Addition x = new Addition();
String ans = x.operation(inputA, inputB);
showAnswerSTR(ans);
}
#FXML
public void subtractNumbers(){
Float inputA = Float.parseFloat(input1.getText());
Float inputB = Float.parseFloat(input2.getText());
Subtraction x = new Subtraction();
String ans = x.operation(inputA, inputB);
showAnswerSTR(ans);
}
#FXML
public void multiplyNumbers(){
Float inputA = Float.parseFloat(input1.getText());
Float inputB = Float.parseFloat(input2.getText());
Multiplication x = new Multiplication();
String ans = x.operation(inputA, inputB);
showAnswerSTR(ans);
}
#FXML
public void divideNumbers(){
Float inputA = Float.parseFloat(input1.getText());
Float inputB = Float.parseFloat(input2.getText());
Division x = new Division();
String ans = x.operation(inputA, inputB);
showAnswerSTR(ans);
}
}
HistoWindowController is:
public class HistoWindowController {
#FXML
VBox HistoryViewer;
public void showHistory(){
StringTokenizer str = new StringTokenizer(getHistory(),";");
while(str.hasMoreTokens()){
HistoryViewer.getChildren().add(new Label(str.nextToken().toString()));
}
}
private String history = "H I S T O R Y;";
public void addHistory(String history) {
this.history += history + ";";
}
public String getHistory() {
return history;
}
/*public String historyReader() {
StringTokenizer str = new StringTokenizer(getHistory(),";");
String temp = "";
if(str.hasMoreTokens()) {
temp += str.nextToken();
temp += "\n";
}
return temp;
}*/
}
Main is:
public class Main extends Application {
private Stage primaryStage;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/mainView.fxml"));
AnchorPane mainFXML = (AnchorPane) loader.load();
Scene scene = new Scene(mainFXML);
primaryStage.setScene(scene);
primaryStage.show();
MainWindowController mainWindow = loader.getController();
mainWindow.setMain(this);
} catch(Exception e) {
e.printStackTrace();
}
}
public void HistoryViewer(){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/HistoryView.fxml"));
AnchorPane histoView = (AnchorPane) loader.load();
Scene scene = new Scene(histoView);
primaryStage.setScene(scene);
primaryStage.show();
HistoWindowController histoControl = loader.getController();
histoControl.showHistory();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Thanks in advance
I guess this is the line where it happens (check the stacktrace): HistoWindowController histoControl = loader.getController();
the value of the fx:controller attribute in HistoryView.fxml is MainWindowController
Thanks #fabian
This question already has answers here:
Passing Parameters JavaFX FXML
(10 answers)
Closed 5 years ago.
I'm currently trying to build a Client-Server application with a login and logout function. In LoginViewController I'm creating a client-object. I want to be able to use this very object in ClientViewController, e.g. for logout. How can I pass this object from LoginViewController to ClientViewController? Since the login was successfull I dont want to instantiate a new object, I want to use the object which passed the login and is currently active on the server-side.
How can this be achieved?
Main.java
public class Main extends Application {
private static Stage primaryStage;
private static BorderPane mainLayout;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
showLoginView();
}
public static void showLoginView() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("LoginView.fxml"));
mainLayout = loader.load();
Scene scene = new Scene(mainLayout, 540, 400);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
public static void showClientView() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("ClientView.fxml"));
mainLayout = loader.load();
Scene scene = new Scene(mainLayout, 900, 600);
primaryStage.setScene(scene);
primaryStage.setResizable(true);
primaryStage.show();
}
}
LoginViewController.java
public class LoginViewController implements Initializable {
#FXML
private Main main;
#FXML
private TextField username;
#FXML
private PasswordField password;
#FXML
private Button login;
#FXML
private Button register;
private Client client;
private Login userLogin;
private String loginStatus;
#FXML
private Label loginInfo;
#Override
public void initialize(URL location, ResourceBundle resources) {
loginInfo.setVisible(false);
}
#FXML
public void login() throws IOException {
loginStatus = "timeout";
loginInfo.setVisible(false);
client = new Client("127.0.0.1", 3250, this); // Client object created
userLogin = new Login(username.getText(), password.getText());
client.setOnConnected(() -> client.sendToServer(userLogin));
client.start();
int waitForLoginStatusCounter = 0;
while(loginStatus.equals("timeout")) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
waitForLoginStatusCounter++;
if(waitForLoginStatusCounter >= 20) {
break;
}
}
if(loginStatus.equals("success")) {
main.showClientView();
}
else if(loginStatus.equals("failed")) {
loginInfo.setVisible(true);
loginInfo.setText("Login failed: Wrong username or password");
}
else {
loginInfo.setVisible(true);
loginInfo.setText("Timeout: Check connection");
}
}
public String getLoginStatus() {
return loginStatus;
}
public void setLoginStatus(String loginStatus) {
this.loginStatus = loginStatus;
}
}
ClientViewController.java
public class ClientViewController implements Initializable {
#FXML
private Main main;
#FXML
private TreeView<String> treeview;
#FXML
private Button logout;
private Client client;
private String username;
private Logout userLogout;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
public void logout() throws IOException {
userLogout = new Logout(username);
client.sendToServer(userLogout); // Null at this point
main.showLoginView();
}
}
Client.java (sends and receives objects from server)
public class Client extends Thread {
private String ip;
private int port;
private Socket socket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Runnable onConnected;
private LoginViewController lvc;
private RegisterViewController rvc;
public void setOnConnected(Runnable onConnected) {
this.onConnected = onConnected;
}
public Client(String ip, int port, LoginViewController lvc) {
this.ip = ip;
this.port = port;
this.lvc = lvc;
}
public Client(String ip, int port, RegisterViewController rvc) {
this.ip = ip;
this.port = port;
this.rvc = rvc;
}
public void run() {
try {
socket = new Socket(ip, port);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
if(onConnected != null) {
onConnected.run();
}
while (true) {
try {
Object obj = ois.readObject();
if (obj instanceof Login) {
String loginStatus = ((Login) obj).getLoginStatus();
lvc.setLoginStatus(loginStatus);
}
else if(obj instanceof Register) {
String registerStatus = ((Register) obj).getRegisterStatus();
rvc.setRegisterStatus(registerStatus);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendToServer(Object obj) {
try {
oos.writeObject(obj);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Problem solved after implementing the following code:
LoginViewController.java
if(loginStatus.equals("success")) {
main.showClientView(client); // Passing the client-object to showClientView method
}
Main.java
public static void showClientView(Client client) throws IOException { // Taking the client-object as an argument from LoginViewController
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("ClientView.fxml"));
mainLayout = loader.load();
ClientViewController cvc = loader.getController(); // This did the "trick"
cvc.setClient(client); // Passing the client-object to the ClientViewController
Scene scene = new Scene(mainLayout, 900, 600);
primaryStage.setScene(scene);
primaryStage.setResizable(true);
primaryStage.show();
}
ClientViewController.java
public void setClient(Client client) { // Setting the client-object in ClientViewController
this.client = client;
}
I have created this app with many other classes and it seems to run okay. However, when I finish the quiz, I cant add a button to restart the quiz? I have tried Jbutton and Jframe but I have no idea how to do it? Is there a simple code to add?
package sample;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
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.*;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javafx.event.ActionEvent;
import javafx.stage.Stage;
import javax.xml.bind.JAXBException;
public class Controller implements Initializable{
static int count = 1;
static int score=0;
static int multiplayerCounter = 1;
static int scoreOfComputer = 0;
static int scoreOfHuman = 0;
static String level;
static XmlToObject ob = new XmlToObject();
static List<String[]> questionsList = ob.readQuestionsAndAnswers("easy");
static boolean isCheatSet;
static boolean isSkipSet;
static String username;
public static String getLevel() {
return level;
}
public static void setLevel(String level) {
Controller.level = level;
}
#FXML
public RadioButton rdEasy;
#FXML
public RadioButton rdHard;
#FXML
public TextField txtAnswer;
#FXML
private Label lblMessage;
#FXML
private TextField txtUsername;
#FXML
private PasswordField txtPassword;
#FXML
private ListView lstHistoryScore;
#FXML
private Button btnNext;
#FXML
private Button btnCheat;
#FXML
private Button btnSkip;
#FXML
private Button btnStart;
#FXML
private Label headerCaption;
#FXML
private Label quizCaption;
#FXML
public Label question;
#FXML
public RadioButton optionOne;
#FXML
public RadioButton optionTwo;
#FXML
public Button btnPass;
#FXML
public RadioButton rdSinglePlayer;
#FXML
public ToggleGroup answerGroup;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
private void btnLoginAction(ActionEvent actionEvent) throws IOException {
List<String[]> loginList = ob.readUserLogins();
for(String[] s:loginList ){
if(txtUsername.getText().equals(s[0]) && txtPassword.getText().equals(s[1])){
lblMessage.setText("Success");
((Node) (actionEvent.getSource() )).getScene().getWindow().hide();
Parent parent = FXMLLoader.load(getClass().getResource("/sample/Start.fxml"));
username = txtUsername.getText();
Stage stage = new Stage();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.show();
}else{
lblMessage.setText("Invalid username or password");
}
}
}
public void btnNextAction(ActionEvent actionEvent) throws IOException, JAXBException {
Stage stage = (Stage) ((Node)actionEvent.getSource()).getScene().getWindow();
int index = count - 1;
String[] criteria = questionsList.get(index);
if(getLevel().equals("hard")){
if (criteria[2].toLowerCase().equals(txtAnswer.getText().toLowerCase()) && !isCheatSet && !isSkipSet) {
score++;
}
if(count == 10) {
quizCaption.setText("Over");
question.setText("Your Score: " + score);
txtAnswer.setVisible(false);
btnNext.setVisible(false);
btnCheat.setVisible(false);
btnSkip.setVisible(false);
lstHistoryScore.setVisible(true);
lstHistoryScore.setItems(new XmlToObject().readXml());
ObjectToXML obx = new ObjectToXML();
obx.saveToXml(score);
}else {
txtAnswer.setText("");
String[] cr = questionsList.get(count);
quizCaption.setText("Quiz " + (count + 1));
question.setText(cr[1]);
isCheatSet = false;
isSkipSet = false;
count++;
}
}else {
RadioButton selectedRadio = (RadioButton) answerGroup.getSelectedToggle();
optionOne.setSelected(false);
optionTwo.setSelected(false);
if(!isSkipSet) {
if (getAnswer(criteria[4], selectedRadio.getText()) && !isCheatSet) {
score++;
}
}
if(count == 10) {
quizCaption.setText("Over");
question.setText("Your Score: " + score);
optionOne.setVisible(false);
optionTwo.setVisible(false);
btnNext.setVisible(false);
btnCheat.setVisible(false);
btnSkip.setVisible(false);
lstHistoryScore.setVisible(true);
lstHistoryScore.setItems(new XmlToObject().readXml());
ObjectToXML obx = new ObjectToXML();
obx.saveToXml(score);
}else {
String[] cr = questionsList.get(count);
quizCaption.setText("Quiz " + (count + 1));
question.setText(cr[1]);
optionOne.setText(cr[2]);
optionTwo.setText(cr[3]);
isCheatSet = false;
isSkipSet = false;
count++;
}
}
}
public void btnCheatAction(ActionEvent actionEvent) throws IOException, JAXBException {
isCheatSet = true;
int index = count -1;
if(getLevel().equals("hard")){
txtAnswer.setText(getCheatAnswerForHardLevel(index));
}else {
if(getCheatAnswer(index) == 1){
optionOne.setSelected(true);
}else {
optionTwo.setSelected(true);
}
}
Task<Void> sleeper = new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
return null;
}
};
sleeper.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
try {
btnNextAction(actionEvent);
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
});
new Thread(sleeper).start();
}
public void btnSkipAction(ActionEvent actionEvent) throws IOException, JAXBException {
isSkipSet = true;
btnNextAction(actionEvent);
}
public void setName(String name) {
quizCaption.setText(name);
}
public void btnStartAction(ActionEvent actionEvent) throws IOException, JAXBException {
if(rdSinglePlayer.isSelected()){
((Node) (actionEvent.getSource())).getScene().getWindow().hide();
if(rdHard.isSelected()) {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/SinglePlayerHardLevel.fxml"));
questionsList = ob.readQuestionsAndAnswers("hard");
String[] criteria = questionsList.get(0);
setLevel("hard");
loader.getNamespace().put("caption", ("Quiz"+ criteria[0]) );
loader.getNamespace().put("quiz", criteria[1]);
Parent root = loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}else {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/SinglePlayerEasyLevel.fxml"));
String[] criteria = questionsList.get(0);
loader.getNamespace().put("caption", ("Quiz" + criteria[0]));
loader.getNamespace().put("quiz", criteria[1]);
loader.getNamespace().put("one", criteria[2]);
loader.getNamespace().put("two", criteria[3]);
Parent root = loader.load();
setLevel("easy");
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}else{
((Node) (actionEvent.getSource())).getScene().getWindow().hide();
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/Multiplayer.fxml"));
String[] criteria = questionsList.get(0);
loader.getNamespace().put("player", "Human");
loader.getNamespace().put("caption", ("Quiz" + criteria[0]));
loader.getNamespace().put("quiz", criteria[1]);
loader.getNamespace().put("one", criteria[2]);
loader.getNamespace().put("two", criteria[3]);
Parent root = loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
public void btnPassAction(ActionEvent actionEvent) {
RadioButton selectedRadio = (RadioButton) answerGroup.getSelectedToggle();
optionOne.setSelected(false);
optionTwo.setSelected(false);
int index = multiplayerCounter - 1;
if (multiplayerCounter == 10) {
question.setText("Computer score: " + scoreOfComputer);
quizCaption.setText("Your Score: " + scoreOfHuman);
optionOne.setVisible(false);
optionTwo.setVisible(false);
btnPass.setVisible(false);
}else {
String[] criteria = questionsList.get(index);
if (multiplayerCounter % 2 == 0) {
headerCaption.setText("Human");
optionOne.setDisable(false);
optionTwo.setDisable(false);
if (getAnswer(criteria[4], selectedRadio.getText())) {
scoreOfComputer++;
}
} else {
headerCaption.setText("Computer");
int ans = findRandomAnswer(Math.random());
if (ans == 1) {
optionOne.setSelected(true);
optionTwo.setDisable(true);
} else {
optionTwo.setSelected(true);
optionOne.setDisable(true);
}
if (getAnswer(criteria[4], selectedRadio.getText())) {
scoreOfHuman++;
}
}
String[] cr = questionsList.get(multiplayerCounter);
quizCaption.setText("Quiz " + cr[0]);
question.setText(cr[1]);
optionOne.setText(cr[2]);
optionTwo.setText(cr[3]);
multiplayerCounter++;
}
}
public boolean getAnswer(String answer, String quizOption){
if(answer.equals(quizOption)){
return true;
}else{
return false;
}
}
public int findRandomAnswer(double rand){
if(rand <= 0.7){
return 1;
}else{
return 2;
}
}
public int getCheatAnswer(int quizNumber){
String[] criteria = questionsList.get(quizNumber);
if(criteria[4].equals(criteria[2])){
return 1;
}else{
return 2;
}
}
public String getCheatAnswerForHardLevel(int quizNumber){
String[] criteria = questionsList.get(quizNumber);
return criteria[2];
}
public void rdSelectSinglePlayer(ActionEvent actionEvent) {
rdEasy.setVisible(true);
rdHard.setVisible(true);
btnStart.setDisable(false);
}
public void rdSelectMultiPlayer(ActionEvent actionEvent) {
rdEasy.setVisible(false);
rdHard.setVisible(false);
btnStart.setDisable(false);
}
}
I am trying to add a button that allows the user to select a folder of wav files which are then added to a ListControl where they can be selected for playback. I originally created a String variable which contained path to folder but would like now to allow the user choose a folder which is then loaded into ListControl. At the moment when user chooses folder the files do not add to ListControl. Here is what I have so far. Any tips or hints would be appreciated. Thanks in advance.
public class Molly2b extends Application {
private List<File> list = new ArrayList<File>();
private void init(final Stage primaryStage) {
Group root = new Group();
primaryStage.setScene(new Scene(root));
HBox hBox2 = new HBox();
hBox2.setSpacing(20);
hBox2.setTranslateY(30);
hBox2.getChildren().add(createChart());
final DirectoryChooser fileChooser = new DirectoryChooser();
final Button chooseDirButton = new Button("Choose Directory");
chooseDirButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
final DirectoryChooser dirChooser = new DirectoryChooser();
final File selectedDirectory = dirChooser.showDialog(primaryStage);
if (selectedDirectory != null) {
selectedDirectory.getAbsolutePath();
addFilesFromDir(selectedDirectory);
}
}
});
VBox vBox = new VBox(50);
vBox.getChildren().addAll(hBox2);
final ObservableList<File> listObserv = FXCollections.<File>observableList(list);
ListView<File> listView = new ListView<File>(listObserv);
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listView.getSelectionModel().selectedItemProperty().addListener(
new ChangeListener<File>() {
public void changed(ObservableValue<? extends File> ov,
File old_val, File new_val) {
playAudio(new_val);
}
});
BorderPane bp = new BorderPane();
bp.setLeft(listView);
bp.setRight(vBox);
bp.setTop(chooseDirButton);
root.getChildren().add(bp);
}
public void addFilesFromDir(File dir){
if (dir.isDirectory()){
File[] loopsList = dir.listFiles();
for (File f:loopsList){
String s = f.getName();
if (s.endsWith(".wav")){
list.add(f);
}
}
}
}
public void playAudio(File file){
try{
AudioInputStream ais = AudioSystem.getAudioInputStream(file);
AudioFormat audioFormat = ais.getFormat();
DataLine.Info dataLineInfo = new DataLine.Info(Clip.class,audioFormat);
Clip clip = (Clip) AudioSystem.getLine(dataLineInfo);
clip.open(ais);
clip.setLoopPoints(0,-1);
clip.loop(0);
} catch (LineUnavailableException ex){
} catch (UnsupportedAudioFileException ef){
} catch (IOException e){
}
}
#Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
You mean something like FileChooser or DirectoryChooser?
http://docs.oracle.com/javafx/2/ui_controls/file-chooser.htm
Seems you have changed the question.
public class Molly2b extends Application {
private URI path;
private FileChooser fileChooser;// = new FileChooser();
private ObservableList<File> listype;//
private ListView<String> listView;
private ListCell<String> listCell;
private void init(final Stage primaryStage) {
Group root = new Group();
HBox hBox2 = new HBox();
hBox2.setSpacing(20);
hBox2.setTranslateY(30);
listView = new ListView<>();
listCell = new ListCell<>();
final Button chooseDirButton = new Button("Choose Directory");
//listView.setCellFactory(TextFieldListCell.forListView());
chooseDirButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
fileChooser = new FileChooser();
listype = FXCollections.observableList();
fileChooser.showOpenMultipleDialog(primaryStage)
if (listype != null) {
for (int i = 0; i < listype.size(); i++) {
path = listype.get(i).toURI();
String filename = listype.get(i).getName();
listCell.setItem(filename);
final ObservableList olist = FXCollections
.observableArrayList();
olist.addListener(new InvalidationListener() {
#Override
public void invalidated(Observable o) {
listView.getItems();
}
});
olist.addListener(new ListChangeListener() {
#Override
public void onChanged(ListChangeListener.Change
change) {
change.getList();
listView.setItems(olist);
}
});
olist.setAll(listView.getItems());
olist.add(filename);
}
}
}
});
VBox vBox = new VBox(50);
vBox.getChildren().addAll(hBox2);
//listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listView.getSelectionModel().selectedIndexProperty().addListener(
new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> ov,
Number oldValue, Number newValue) {
ov.getValue();
if(newValue.intValue == 0) {
listView.getItems().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable o) {
listCell.getIndex();
}
});
path = listype.get(newValue.intValue()).toURI();
}
try {
String newpath = path.toString();
playAudio(newpath);
} catch (IOException |
LineUnavailableException | UnsupportedAudioFileException e) {
}
}
});
BorderPane bp = new BorderPane();
bp.setLeft(listView);
bp.setRight(vBox);
bp.setTop(chooseDirButton);
root.getChildren().add(bp);
primaryStage.setScene(new Scene(root));
}
public void playAudio(String path) throws UnsupportedAudioFileException,
IOException, LineUnavailableException {
Media media = new Media(path);
final MediaPlayer player = new MediaPlayer(media);
player.play();
}
#Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
Works as it should. Only thing that could need changing is that it can play 2 songs at the same time.
The problem is that you never add the files to the ListView but you add them only to the List.
You have to call listView.getItems().add(f); if you want them added to the ListView.