Przekazywanie danych pomiędzy różnymi GUI

1

Witam serdecznie,

zaczynam swoją przygodę z Java i GUI. Googlowałem, googlowałem, czytałem, ale nie ogarniam :(
Chcę napisać na razie prosty programik, który będzie działał na zasadzie:

  1. Glowne GUI w ktorym jest pole tekstowe "wynikowe" przedsawiające wartość jakiejś zmiennej (zakładam, że JLabel),
  2. Button, ktorego klikniecię spowoduje otworzenie drugiego okna (JFrame)
  3. Drugie okno, w którym jest pole do wprowadzenia danych oraz drugi button. Wciśnięcie tego "drugiego" buttonu powinno spowodować zamknięcie drugiego okna, oraz akualizację zmiennej i jej prezentacji w oknie 1.

Jakaś podpowiedź? Eksperymentuję z dwoma klasami (w jednej jest jedno okno, w drugiej drugie), z ActionListener'ami - ale nie potrafię przekazać wartości zmiennej pomiędzy oknami :(

pozdrawiam,
jacek

1

Twój problem polega na tym że nie umiesz programować :( i GUI nie ma tu specjalnie wiele do rzeczy. Okienka to jest tylko widok, nic więcej. Logika aplikacji powinna być od niego niezależna. Więc nie przekazujesz nigdy nigdzie żadnego labela! Wykonujesz akcje wczytania danych z tego labela a potem dane przekazujesz do innego okienka. Polecam poczytać co to MVC i MVP bo bez tego będzie ciężko. W przypadku MVP wyglądałoby to tak:

  • Kliknięcie w button powoduje akcje na Prezenterze
  • Prezenter pobiera sobie dane z twojego labela, woła warstwę logiki która cośtam z tymi danymi robi
  • Prezenter finalnie triggeruje wyświetlenie wyniku w jakimś okienku

Jak np. jedna akcja triggeruje bardzo dużo zmian w GUI to robiłem kiedyś coś takiego z użyciem guava event bus. Każda klasa reprezentująca jakiś widok rejestruje się jako event listener i definiuje sobie handlery dla eventów które ją interesują a Prezenter emituje event do busa kiedy wykonywana jest jakaś akcja.

0

Shalom - dzięki za podpowiedz i poniekąd masz racje :) programowalem dobre 10 lat i 15 lat temu - ale w czasach programowania proceduralnego :) teraz niejako odkrywam ‚swiat’ na nowo w Javie :) i ciagle widzę same wady i utrudnienia obiektowego 😂

1

@Jack_1979 ale zauważ że twoje pytanie brzmi mniej więcej tak:

Programuje sobie w konsoli i chciałbym zapisać dane podane przez użytkownika do pliku. Jak mam przekazać konsolę do pliku?

I pewnie na tak postawione pytanie zasugerowałbyś zeby:

  • wczytać dane z konsoli do jakiejś zmiennej kiedy uzytkownik wciśnie enter
  • wysłać te dane do zapisania do pliku

I wyobraź sobie że w twoim przypadku jest identycznie!

  • wczytujesz dane z pola tekstowego do jakiejś zmiennej kiedy użytkownik wciśnie guzik
  • wysyłasz dane do wyświetlenia w okienku

Obiektowość nie ma tu nic do rzeczy.

0

@Shalom:
Dodałbym moją prywatną zasadę: jeśli ci się wydaje, ze dwie klasy zależą od siebie (nawzajem) - rozważ, a może jednak nie zależą od siebie, a od trzeciej?
Tu by była nazwana Modelem w stosunku do dwóch klas Widoku.

@Jack_1979:
Bajasz. Programowanie tzw proceduralne jest w rzeczywistości proceduralno - strukturalne. Procedury też nie gwałcą siebie, ale prawdopodobnie kooperują na wspólnej STRUKTURZE danych.
Więc tego jak zwiesz "proceduralnego" sądzę nauczyłeś się używać źle.

0

@AnyKtokolwiek: myśle, ze jednak nie nauczyłem się zle używać tego ‚proceduralnego’ :) tak jak piszesz - cała filozofia i zabawa to określenie i bazowanie na strukturze danych - globalnej dodam. Abstrahując od zabaw w przekazywanie zmiennych w funkcji/procedurze. Tu na razie napotykam na problem - mam zmienna w klasie X (w praktyce bedzie to bardziej skomplikowana struktura danych - pewnie klasa :) ) która wprowadzam w jednym oknie. W innym oknie definiuje operacje na tych danych. I na razie problemem jest przekazanie danych pomiędzy tymi klasami/oknami. Kiedyś zrobiłbym to bez problemu bazując na zmiennych globalnych. Shalom podał skróty MVP i MVC - poczytam, dzięki. Ty piszesz o Modelu (pewnie danych:) ) czy możesz podać jakieś ‚słowo Klucz’ które by mnie naprowadziło na bibliografię? Pozdrawiam

0

Hasło do wyszukania: "java swing pass object between windows"

Wynik:
https://stackoverflow.com/questions/7017063/passing-values-between-jframes

Hasło do wyszukania: "java swing dialog window object"

Wynik:
https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html

0

W głównej klasie "oknie 1" utwórz metodę do ustawiania tekstu jLabel. Z innej klasy nie ma do niego bezpośredniego dostępu.

public void ustawTekst(String text) {
this.jLabel1.setText(text);
}

W klasie drugiej "oknie 2" utwórz konstruktor, który przyjmuje referencję do okna 1 i podczas jej tworzenia przekaż go.

Okno1 parent = null;
Okno2 (Okno1 parent) {
this.parent = parent;
}

Okno2 okno2 = new Okno2(this);

Po wciśnięciu przycisku jButton pobierz dane z komponentu w "oknie 2" i przekaż go do utworzonej w klasie 1 "oknie 1" metody

String text = this.jTextField.getText();
parent.ustawTekst(text);

To tylko przykład. Rozwiązań jest wiele. Ale jest to bardzo wygodne w różnych sytuacjach.
W kodzie, który napisałem mogą być błędy, ponieważ piszę to "z palca"

Pozdrawiam.

0

@vpiotr: @caprio: dzięki ślicznie

0

Dziękuję wszystkim za dotychczasowe uwagi/opieprz/sugestie/itp.
Spośród rozwiązań które powyżej zostały wskazane, wykorzystałem (na miarę umięjętości :)) model/strukturę MVC.
Niemniej, chciałbym jeszcze zapytać Fachowców :)

W miarę możliwości upraszczając:

  1. Mam okno, powiedzmy Okno1, którego rolą jest wizualizacja danych oraz button, który otwiera okno2 (ktorego celem jest wprowadzenie danych),
  2. Okno2 zawiera pole do wprowadzenia danych, które to dane powinny pojawić się w Oknie1, po zamknięciu okna (co istotne, update danych w oknie 1 powinien miec miesce od razy po zamknięciu okna2),
  3. całość danych jest "ogarniana" przez niezależną klasę danych,
  4. i teraz "clue"... kontrolery... to, co mi się "wykluło" wygląda jak niżej:
    a) kontroler, który ogarnia Okno1 i model danych - takie, zgodnie w bibliografią - klasyczne - to mi działa (chyba nawet dobrze :) ),
    b) kontroler, który ogarnia Okno2, ale "propaguje" dane do okna 1 i korzysta z modelu - w praktyce wyszla mi klasa, która ma trzy "zmienne" wejściowe - model, okno1 (gui 1), okno 2 (gui 2)

I moje pytanie - czy, kolokwialnie mówiąc, walę armatą do muchy? czy faktnie takie rozwiązanie/architektura wymaga kontrolera, który ma 3 zmienne/referencje na wejściu - model oraz dwa GUI

pozdrawiam

0

Jeśli chcesz robić to w takim modelu ze kontroler zarówno wyciąga dane jak i pcha dane to niestety innej możliwości nie widzę za bardzo ;) Pytanie czy faktycznie ma to sens. Są inne możliwości:

  1. Pisałem wyżej o możliwosci użycia event busa do propagowania danych do okienek. W efekcie kontroler nie musi znać żadnego okienka w ogóle. Ma tylko dostęp do event busa i wkłada do niego eventy, np. LoadDataFromOkno2 który zawiera w sobie zawartość danych które były w tym oknie wprowadzone. Wszystkie okienka rejestruja się w busie na interesujace je eventy i voila. To rozwiązuje problem kiedy jakieś zdarzenie powoduje bardzo dużo zmian w GUI. W kontrolerze wysyłasz jeden event i tyle, a kto jest nim zainteresowany to się na niego rejestruje i ogarnia.
  2. Okno2 może wysyłać do kontrolera event z odpowiednią informacją, więc niejako to Okno2 zna kontroler, a nie odwrotnie. Szczególnie ze pewnie i tak musi go znać, bo jakoś "triggeruje" załadowanie danych do Okno1. Podobnie jak wyżej, może też w ogóle nie znać kontrolera i analogicznie wysyłać event Okno2Closed z danymi powiazanymi z tym eventem. W takiej sytuacji w ogóle zarówno okienka jak i kontrolery wiedzą jedynie o event busie i o niczym więcej.

Zauważ ze nie ma to specjalnie wpływu na "strukturę" MVC/MVP, nadal masz widoki, nadal masz model/logikę domenową i nadal masz kontrolery, które w odpowiedzi na jakieś akcje wykonuja operacje na modelu i wrzucają wyniki do widoków, ale implementacyjnie robi się dużo łatwiejsze.
Minus to oczywiście "czytelność", bo data-flow przestaje być łatwy do prześledzenia, bo zamiast bezpośrednich wywołań metod masz "niewidzialny" przepływ eventów. Coś za coś.

1 użytkowników online, w tym zalogowanych: 0, gości: 1