Komunikacja między kontrolerami, JavaFX

Komunikacja między kontrolerami, JavaFX
A1
  • Rejestracja:ponad 7 lat
  • Ostatnio:prawie 4 lata
  • Postów:50
0

Hej, ostatnio zacząłem robić projekt w JavaFX, gdzie muszę zaimplementować listę todo. Jednakże nie wiem jak mógłbym przesyłać dane między oknami. Ogólnie mam główne okno, po czym wciskając przycisk add new task wyskakuje nowe okno, gdzie uzupełniam dane zadania i chciałbym zatwierdzając ten obiekt(klasa przetrzymująca same dane typu tytuł, priorytet itp.) chciałbym wysłać go do pierwszego okna, gdzie pojawiłby się na ListView. Mój kod obecnie wygląda tak:
Główny kontroler"

Kopiuj
public class Controller {
    TaskDescription tmp;

    @FXML
    private ListView<TaskDescription> toDo;

    @FXML
    private ListView<TaskDescription> inProgress;

    @FXML
    private ListView<TaskDescription> doneTasks;

    @FXML
    private Button addTask;

    ObservableList<TaskDescription> list = FXCollections.observableArrayList();

    @FXML
    void addNewTask(ActionEvent event) throws Exception {

        FXMLLoader loader = new FXMLLoader(getClass().getResource("NewTask.fxml"));
        Parent root= (Parent) loader.load();

        Stage stage = new Stage();
        stage.setScene(new Scene(root, 600, 500));
        stage.showAndWait();
        NewTaskController getControl=loader.getController();

        toDo.setItems(list);
    }

a drugi:

Kopiuj
public class NewTaskController {


    TaskDescription tmp;

    @FXML
    private TextField taskTitle;

    @FXML
    private ComboBox<String> choosePriority;

    @FXML
    private String lowTask;

    @FXML
    private String highTask;

    @FXML
    private DatePicker chooseDate;

    @FXML
    private TextArea textArea;

    @FXML
    private Button addTaskButton;

    @FXML
    void addTask(ActionEvent event) {
    tmp.title=taskTitle.getText();
    tmp.priority=choosePriority.getValue();
    tmp.date=chooseDate.getValue();
    tmp.description=textArea.getText();

    addTaskButton.getScene().getWindow().hide();
    }

}
MrMadMatt
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 dni
  • Postów:373
1

Użyj do komunikacji między kontrolerami, EventBusa z Guavy.

A1
Dzięki, spróbuję tak :D
A1
  • Rejestracja:ponad 7 lat
  • Ostatnio:prawie 4 lata
  • Postów:50
0

Niestety nie byłem w stanie ogarnąć Event Busa, więc zrobiłem to innym sposobem, a mianowicie w drugim kontrolerze przycisk uruchamia funkcję pierwszego kontrolera, która przyjmuje ustawiony element, ale żeby ją uruchomić, musi być ona statyczna. Ale wtedy znów moja ObservableList i ListView muszą być statyczne. I tu się pojawia problem, że(prawdopodobnie o to chodzi) jak ListView jest statyczne, to owszem, dodaje do niego elementy(sprawdzałem w debuggerze), jednak w oknie aplikacji w ListView nie pojawiają się te obiekty.

Kopiuj
public class Controller {

    @FXML
    private static  ListView<TaskDescription> toDo=new ListView<>();

    @FXML
    private ListView<TaskDescription> inProgress;

    @FXML
    private ListView<TaskDescription> doneTasks;

    @FXML
    private Button addTask;

    static ObservableList<TaskDescription> list= FXCollections.observableArrayList();

    @FXML
    void addNewTask(ActionEvent event) throws Exception {

        FXMLLoader loader = new FXMLLoader(getClass().getResource("NewTask.fxml"));
        Parent root= (Parent) loader.load();
        Stage stage = new Stage();
        stage.setScene(new Scene(root, 600, 500));
        stage.show();
    }
    static void addToList(TaskDescription tmp)
    {

        TaskDescription newTask=new TaskDescription(tmp);
        list.add(newTask);
        toDo.setItems(list);
        
        System.out.println(list);
    }
}

Funkcja w drugim kontrolerze:

Kopiuj
    @FXML
    void addTask(ActionEvent event) {

        tmp=new TaskDescription(taskTitle.getText(),choosePriority.getValue(),chooseDate.getValue(),textArea.getText());
        System.out.println(tmp);
        Controller.addToList(tmp);
    }

MrMadMatt
Jakbyś mógł to wrzuć kod na jakiegoś GitHuba to mógłbym Ci komunikację na EventBusie zaimplementować w forku.
A1
https://github.com/wsacha/TODO-List , przepraszam za kłopot i makaronowy kod
MrMadMatt
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 dni
  • Postów:373
1

No więc tak, tutaj jest moja wersja z zaimplementowanym EventBusem: https://github.com/matadini/todo-list-4programmers-help
Pozwolisz że będę miał dla Ciebie kilka uwag / porad, jak je już znasz to super a jak nie to może się czegoś dowiesz.

  1. Do budowania projektów używaj jakiegoś Maven'a albo Gradle'a. Nie uzależniasz projektu od IDE i co więcej, taki maven wymusza na Tobie określoną strukturę katalogów więc wiesz gdzie co wrzucać.
  2. Jak będziesz się bawił FX'em to polecałbym aby informację o kontrolerze i powiązanych metodach z kontrolkami, umieszczać w kontrolerze a sam kontroler ustawiać jawnie. Deklarować powiązania jawnie w void initialize() Z mojego doświadczenia wynika (2 lata w JFX :D) że te magiczne mechanizmy sprawiają problemy gdy chce się zrobić coś ambitniejszego np. tak jak u Ciebie, zarejestrować kontroler na EventBusie.
  3. EventBus tylko z Guavy, ten od GreenRobota ma brzydki błąd w obsłudze subskrybentów będących klasami package-scope-private. Guava zawsze na propsie. ;)
  4. Jak masz zestaw: kontroler + fxml, zachowuj konwencję, najlepiej: MainPane.fxml + MainPaneController.java. Nazwy Controller.java + sample.fxml absolutnie nic nie mówią.
  5. Zmienne powinny mieć zakres "maksymalnie wymagany" ta tmp w Controller.java powinna być lokalna aby niepotrzebnie nie zwiększać jej widoczności.

Słowem podsumowania wyrażę dość niepopularną opinię, mianowicie: JavaFX to spoko technologia, warto się nią pobawić, potrzeba w niej trochę wprawy ale pozwala ona nauczyć się wzorca MVC na żywych przykładach.

A1
Jestem Ci niezmiernie wdzięczny za pomoc jak i rady. Zależało mi na zrobieniu tego poprawnie, gdyż moja inżynierka będzie trochę z tym powiązana. Jak się okazało z tym moim kodem też nie było aż tak źle, jednak tu wyszła moja słaba znajomość javaFX, że jeszcze nie doczytałem, a już zacząłem to robić, a okazało się, że właśnie przez brak interfejsu initializable i initialize() nie działało tak, jak powinno. To rozwiąznie z EventBusem też teraz jeszcze dzięki tym komentarzom wydaje się bardziej klarowne. Jeszcze raz dzięki za poświęcony czas i uwagi.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.