Заполнить ListView объектами из другого открытого окна в JavaFX - PullRequest
1 голос
/ 18 июня 2019

У меня проблема с заполнением ListView в моем главном окне событиями на кнопку для объекта в другом открытом окне.

Я пробовал несколько вещей, но, кажется, никогда не получится, если я не сделаю это для кнопкисобытие в реальном окне, где находится ListView.Я задавался вопросом, было ли это как-то связано с использованием экземпляра контроллера для главного окна, но я новичок в JavaFX, и я действительно не знаю, что я делаю, tbh.

Некоторые дополнительныеинформация:

Информация - это класс, в котором хранятся сведения, к которым мне нужно получить доступ более чем в одном классе контроллеров;
gastConrim - это метод, вызываемый в другом открытом окне (AddEditGastController);
последняя часть - это часть, которая работает (обновляя ее по событию кнопки в главном окне, где расположен ListView), которая будет похожа на кнопку «update ListView», но это немного неудобно, если вам нужно обновитьListView вручную.

public abstract class Infos {

    public static String ID; 

    static Hotelsystem ht = new Hotelsystem();

    public static Hotelsystem getHt(){
        return ht;
    }

    static void alert(String titel, String content) {
        Alert alert = new Alert(AlertType.CONFIRMATION);
        alert.setTitle(titel);
        alert.setHeaderText(null);
        alert.setContentText(content);
        alert.show();
    }

    static boolean idAbfragen(String titel, String content, String alertContent) {
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle(titel);
        dialog.setHeaderText(null);
        dialog.setContentText(content);

        Optional<String> input = dialog.showAndWait();
        if (!input.isPresent() || input.get().trim().isEmpty()) {
            Alert alert = new Alert(AlertType.CONFIRMATION);
            alert.setTitle(titel);
            alert.setHeaderText(null);
            alert.setContentText(alertContent);
            alert.showAndWait();
            return false;
        }
        else {
            ID = input.get();
            return true;
        }
    }

    static ObservableList<Gast> gastData = FXCollections.observableArrayList();

    public static void updateGast() {
        gastData.setAll(ht.getGastList());
    }

}
@FXML
void gastConfirm(ActionEvent event) throws IOException {


    FXMLLoader fxmlLoader= new FXMLLoader(getClass().getResource("../gui/mainWindowGast.fxml"));
    Parent root = (Parent) fxmlLoader.load();
    MWControllerGast controller = (MWControllerGast) fxmlLoader.getController();


    double rabatt = 0.0;
    if (gastNameInput.getText().trim().isEmpty() || anredeToggle.getSelectedToggle() == null || gastGB.getValue() == null || gastTfInput.getText().trim().isEmpty() ||
            gastStrasseInput.getText().trim().isEmpty() || gastStadtInput.getText().trim().isEmpty() || gastLandInput.getText().trim().isEmpty()) {
            Infos.alert("Fehler", "Es fehlen Informationen.");
    }
    else {
        if (gastStatus.isSelected()) {
            if (!gastRabattInput.getText().trim().isEmpty()) {
                String rabattInput = gastRabattInput.getText();
                if (rabattInput.contains(","))
                    rabattInput.replace(",", ".");
                rabatt = Double.parseDouble(rabattInput);
                Infos.getHt().getHinzufuegen().vipHinzufuegen(gastNameInput.getText(), gastAnredeRadio1.getText(), gastGB.getValue(), gastTfInput.getText(), gastStrasseInput.getText(), gastStadtInput.getText(), gastLandInput.getText(), rabatt);
            }
            Infos.ht.getHinzufuegen().vipHinzufuegen(gastNameInput.getText(), gastAnredeRadio1.getText(), gastGB.getValue(), gastTfInput.getText(), gastStrasseInput.getText(), gastStadtInput.getText(), gastLandInput.getText(), rabatt);

        } else
            Infos.ht.getHinzufuegen().gastHinzufügen(gastNameInput.getText(), gastAnredeRadio1.getText(), gastGB.getValue(), gastTfInput.getText(), gastStrasseInput.getText(), gastStadtInput.getText(), gastLandInput.getText());

        System.out.println(rabatt);
        gastNameInput.clear();
        gastAnredeRadio1.setSelected(false);
        gastAnredeRadio2.setSelected(false);
        gastGB.setValue(null);
        gastTfInput.clear();
        gastStrasseInput.clear();
        gastStadtInput.clear();
        gastLandInput.clear();
        gastStatus.setSelected(false);
        gastRabattInput.clear();


        Infos.updateGast();

        controller.gastTable.getItems().setAll(Infos.gastData);


    }

@FXML
ListView<Gast> gastTable;

public ListView<Gast> getGastTable() {
    return gastTable;
}

@FXML
void sortieren(ActionEvent event) {

    Infos.updateGast();

    gastTable.getItems().setAll(Infos.gastData);
}

Ожидаемый результат: обновлять ListView в gastConfirm всякий раз, когда я добавляю новый объект.

Фактический результат: ничего не происходит.По крайней мере, ничего не вижу в консоли или пользовательском интерфейсеОн просто не добавляет объект в ListView.

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Вам нужно посмотреть на ответ Джеймса D здесь .Я создал разбавленную версию ответа Джеймса.Комментарии в коде.

Main

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication124 extends Application
{
    @Override
    public void start(Stage primaryStage)
    {        
        try 
        {
            //Load both Stages while passing the model to each.
            FXMLLoader listLoader = new FXMLLoader(getClass().getResource("ListFXML.fxml"));
            Scene scene = new Scene(listLoader.load());
            ListController listController = listLoader.getController();            
            primaryStage.setScene(scene);
            primaryStage.setTitle("Hello World!");

            FXMLLoader editorLoader = new FXMLLoader(getClass().getResource("EditorFXML.fxml"));
            Stage secondStage = new Stage();
            secondStage.setScene(new Scene(editorLoader.load()));
            EditorController editorController = editorLoader.getController();            

            DataModel model = new DataModel();
            listController.initModel(model);
            editorController.initModel(model);

            primaryStage.show();
            secondStage.show();
        } 
        catch (IOException ex)
        {
            System.out.println(ex.toString());
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }
}

Список контроллеров

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;

/**
 * FXML Controller class
 *
 * @author blj0011
 */
public class ListController implements Initializable {
    @FXML ListView<TestObject> listView;

    DataModel model;


    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

    //Use to set model
    public void initModel(DataModel model) {
        if (this.model != null) {
            throw new IllegalStateException("Model can only be initialized once");
        }
        this.model = model ;

        //Set ListView cell factory.
        listView.setCellFactory((ListView<TestObject> param) -> {
            ListCell<TestObject> cell = new ListCell<TestObject>() {

                @Override
                protected void updateItem(TestObject item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null) {
                        setText(item.getName());
                    } else {
                        setText("");
                    }
                }
            };
            return cell;
        });
        listView.setItems(model.getTestObjectsList());//Set List items
    }
}

Список FXML

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

<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane id="AnchorPane" prefHeight="498.0" prefWidth="755.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="javaapplication12.ListController">
   <children>
      <ListView fx:id="listView" layoutX="234.0" layoutY="53.0" prefHeight="393.0" prefWidth="288.0" />
   </children>
</AnchorPane>

Контроллер редактора

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;

/**
 * FXML Controller class
 *
 * @author blj0011
 */
public class EditorController implements Initializable {
    @FXML Button btn;
    @FXML TextField tf;

    DataModel model;

    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO


    }    

    //use to set model
    public void initModel(DataModel model) {
        if (this.model != null) {
            throw new IllegalStateException("Model can only be initialized once");
        }
        this.model = model ;

        //set button action
        btn.setOnAction((event) -> {
            TestObject testObject = new TestObject(tf.getText().isBlank() ? "Dummy Object" : tf.getText());
            model.getTestObjectsList().add(testObject);
        });
    }

}

Редактор FXML

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="javaapplication12.EditorController">
   <children>
      <TextField fx:id="tf" layoutX="226.0" layoutY="94.0" />
      <Button fx:id="btn" layoutX="274.0" layoutY="175.0" mnemonicParsing="false" text="Button" />
   </children>
</AnchorPane>

Модель

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
 *
 * @author blj0011
 */
public class DataModel {
    private final ObservableList<TestObject> testObjects = FXCollections.observableArrayList();

    public ObservableList<TestObject> getTestObjectsList() {
        return testObjects ;
    }
}

TestObject

/**
 *
 * @author blj0011
 */
class TestObject {
    private String name;

    public TestObject(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "TestObject{" + "name=" + name + '}';
    }
}
0 голосов
/ 18 июня 2019

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

FXMLLoader fxmlLoader= new FXMLLoader(getClass().getResource("../gui/mainWindowGast.fxml"));
Parent root = (Parent) fxmlLoader.load();
MWControllerGast controller = (MWControllerGast) fxmlLoader.getController();

Вы загружаете новый контроллер, но не используете ни контроллер, ни загруженный вами корень, чтобы фактически отображать представление в любом месте. Не уверен, что вы делаете это в другом месте (на самом деле вы не можете, потому что это локальная переменная), так как я не вижу весь ваш код, но явно что-то там не так. Я пропускаю что-то вроде:

someParent.add(root);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...