JavaFX 13: просмотр списка не обновляет элементы после открытия и закрытия нового окна - PullRequest
0 голосов
/ 06 января 2020

Я делаю программу, которая добавляет события в список, но когда я добавляю событие, он не обновляет мой список после закрытия окна addEvent, вот сенарио:

1 - это первое окно :

enter image description here

2 - затем я нажимаю кнопку (+), чтобы добавить событие в окне addEvent:

здесь я добавляю тест "пункт, когда я нажимаю ОК, чтобы проверить мой код

enter image description here

3 - теперь я нажимаю кнопку" ОК "и возвращаюсь в главное окно:

теперь в моем списке ничего не меняется, и это не показывает, что «тестовый» элемент, но этот «элемент» уже в списке и успешно добавлен.

вот весь код:

  • Основной класс
    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
    @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
    @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();
    }

так что я тут не так сделал?

мой список обновляется нормально, если я не открывал windows, поэтому он обновляется только в том же окне ... idk, почему

1 Ответ

3 голосов
/ 07 января 2020

Я создал Пример, который демонстрирует решение. Это решение использует идеи из ответа Jewelsea здесь . По сути, откройте новое окно, и когда вы закроете окно, верните строку или ничего, используя Optional. Это быстрый ответ. Я все еще предпочитаю идеи Jame_D MVC этому ответу. Это решение не должно быть идеальным. Это только чтобы показать способ решения проблемы.

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();
    }

}

Основной контроллер

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());
            }            
        });        
    }
}

Первичный F XML

<?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>

Вторичный контроллер (окно добавления нового элемента)

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;
    }
}

Вторичный F XML

<?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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...