-1

i'm making a program that add events in a list but when i add event it doesn't update my list after closing addEvent Window , here is the senario :

1- this is the first window :

enter image description here

2- then i press the (+) button to add event in addEvent window :

here i add "test" item when i press ok to test my code

enter image description here

3- now i press "ok" button and return to the main window :

now nothing change in my list and it doesn't show that "test" item but this "item" already in the list and added successfully.

here is all the code :

  • Main class
    public static void main(String[] args) {

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("main_layout.fxml"));
        Parent root = (Parent) loader.load();   
        primaryStage.setTitle("Goba To Do List");
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();
    }
  • MainController class
    @FXML
    private ListView<String> LeftSideListId; // this names just for testing
    @FXML
    private ListView<String> RightSideListId; // this names just for testing
    @FXML
    private Button AddEvent;

    public void initialize() throws Exception {
        System.out.println("init");

        ObservableList<String>eventsNamesList=FXCollections.observableArrayList(
                "Daily Events","Custom Events","Completed Events");

        LeftSideListId.setItems(eventsNamesList);

        ObservableList<String>eventsList=FXCollections.observableArrayList(
                "item1","item2","item3");

        RightSideListId.setItems(eventsList);

        AddEvent.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                AddButtonPressed();
                }   
        });
    }

    void AddButtonPressed() {

        addEventController.DisplayAddEventWindow();

    }
    public void DisplayAddEventWindow()
     {
         try {
             Stage primaryStage = new Stage();
             primaryStage.setTitle("Add Event");
             Scene scene = new Scene(AddEventScene);
             primaryStage.initModality(Modality.APPLICATION_MODAL);
             primaryStage.setScene(scene);
             primaryStage.setResizable(false);
             primaryStage.show();
         }
         catch(Exception e) 
         {
             e.printStackTrace();
         }
     }

    public void RefreshList() {
        System.out.println("refresh");

        RightSideListId.getItems().add("test");
        System.out.println(RightSideListId.getItems()); // here i get [item1,item2,item3,test]
    }

  • AddEventController class
    @FXML
    private Button BtnOk;
    @FXML
    private Button BtnCancel;

    public void initialize() throws Exception {

         BtnOk.setOnAction(new EventHandler<ActionEvent>() {
             @Override
             public void handle(ActionEvent arg0) {
                 try {
                    BtnOkPressed();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }  
         });
         BtnCancel.setOnAction(new EventHandler<ActionEvent>() {
             @Override
             public void handle(ActionEvent arg0) {
                 BtnCancelPressed();
             }  
         });    
     }

     public void BtnCancelPressed() {
         Stage stg= (Stage)BtnCancel.getScene().getWindow();
         stg.close();

    }

    public void BtnOkPressed() throws Exception {
         Stage stg= (Stage)BtnOk.getScene().getWindow();
         stg.close();
         FXMLLoader loader = new FXMLLoader(getClass().getResource("main_layout.fxml"));
         Parent root = (Parent) loader.load();
         MainController mainController=loader.getController();
         mainController.RefreshList();
    }

so what i did wrong here ?

my list updates normally if i didn't open any windows so it is updating only while in the same window... idk why

Goba
  • 4,305
  • 3
  • 11
  • 15
  • `ListView RightSideListId` is your first problem. It should be something like `ListView RightSideListId`. For the problem you asked, look into `https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx`. If I have time later today, I will do an example. – SedJ601 Jan 06 '20 at 15:16
  • @Sedrick i don't want to add Event object to my list for now , i just want to know why my list is not updating after adding an item to it – Goba Jan 06 '20 at 16:33
  • Your `BtnOkPressed()` code. All it does is close the current window, open a new version of the original window and refresh the new ListView in that window. Not one time does it even attempt to add anything to the ListView in the original window. – SedJ601 Jan 06 '20 at 16:48
  • If you follow James_D's ideas from the link posted above, it will help you solve your issue. You could also pass the information back to the new `main_layout` you create, but you are likely to run into more problems taking that route. – SedJ601 Jan 06 '20 at 16:50
  • https://stackoverflow.com/questions/56653701/fill-listview-with-objects-from-a-another-open-window-in-javafx/56656318#56656318 This link is very similar to what you need to do. Your code will not need the cell factory because you are using `String` and not some `Object`. – SedJ601 Jan 06 '20 at 16:56
  • Here is the link to the other possible solution. https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml – SedJ601 Jan 06 '20 at 16:59
  • 1
    thank you , i will see this links and will reply to you – Goba Jan 06 '20 at 17:11

1 Answers1

3

I created an Example that demos a solution. This solution uses ideas from Jewelsea's answer here. Basically, open a new window and when you close the window return a String or nothing using Optional. This is a quick answer. I still prefer Jame_D's MVC ideas over this answer. This solution is not meant to be perfect. It's only to show a way to solve the problem.

Main

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

/**
 * JavaFX App
 */
public class App extends Application {

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        scene = new Scene(loadFXML("primary"), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

    private static Parent loadFXML(String fxml) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
        return fxmlLoader.load();
    }

    public static void main(String[] args) {
        launch();
    }

}

Primary Controller

import java.io.IOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class PrimaryController implements Initializable{
    @FXML ListView<String> lvMain;
    @FXML Button btnAddNewItem;

    ObservableList<String>eventsList = FXCollections.observableArrayList("item1","item2","item3");

    @Override
    public void initialize(URL url, ResourceBundle rb) {    
        lvMain.setItems(eventsList);

        btnAddNewItem.setOnAction((actionEvent) ->
        {
            try
            {
                FXMLLoader addNewItemLoader = new FXMLLoader(getClass().getResource("secondary.fxml"));
                Stage secondStage = new Stage();
                secondStage.setScene(new Scene(addNewItemLoader.load()));
                SecondaryController addNewItemController = addNewItemLoader.getController();                  
                secondStage.showAndWait();
                Optional<String> result = addNewItemController.getNewItem();
                if (result.isPresent()){
                    System.out.println("Your name: " + result.get());
                    eventsList.add(result.get());
                }
            }
            catch (IOException e)
            {
                System.out.println(e.toString());
            }            
        });        
    }
}

Primary FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" prefHeight="393.0" prefWidth="508.0" spacing="20.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sed.test.javafxfxmltestinggrounds.PrimaryController">
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
   <children>
      <ListView fx:id="lvMain" prefHeight="200.0" prefWidth="200.0" />
      <Button fx:id="btnAddNewItem" mnemonicParsing="false" text="+" />
   </children>
</VBox>

Secondary Controller (Add New Item Window)

import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;

public class SecondaryController implements Initializable{

    @FXML TextArea taSecondary;
    @FXML Button btnOk, btnCancel;

    Optional<String> returnValue;

    @Override
    public void initialize(URL url, ResourceBundle rb) {          
        btnOk.setOnAction((actionEvent) ->
        {
            returnValue = Optional.of(taSecondary.getText());
            ((Stage)(((Button)actionEvent.getSource()).getScene().getWindow())).close();

        });   

        btnCancel.setOnAction((actionEvent) ->
        {
            returnValue = Optional.empty();
            ((Stage)(((Button)actionEvent.getSource()).getScene().getWindow())).close();
        });
    }

    public Optional<String> getNewItem()
    {
        return returnValue;
    }
}

Secondary FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sed.test.javafxfxmltestinggrounds.SecondaryController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
    </padding>
   <children>
      <TextArea fx:id="taSecondary" prefHeight="200.0" prefWidth="200.0" />
      <HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="5.0">
         <children>
            <Button fx:id="btnOk" mnemonicParsing="false" prefWidth="52.0" text="OK" />
            <Button fx:id="btnCancel" mnemonicParsing="false" prefWidth="52.0" text="Cancel" />
         </children>
      </HBox>
   </children>
</VBox>
SedJ601
  • 12,173
  • 3
  • 41
  • 59
  • 1
    thank you so much .. Jewelsea's answer in the link you provided helped me alot and as you said this is the best approach , but i want to know that my problem was all about wrong references or i still misunderstanding something ? – Goba Jan 07 '20 at 04:22