Witajcie!
Piszę program na zaliczenie, który ma za zadanie rysować odpowiednie kształty na podstawie danych, wczytanych z plików. Napisałem klasę Plotter dziedziczącą po JPanel, która zajmuje się rysowaniem. Stworzyłem także klasę FileManager (również dziedziczącą po JPanel), która zarządza wczytywaniem i przechowywaniem danych. Posiada ona tabelkę, w której znajduje się spis wczytanych plików, oraz przyciski Dodaj i Usuń. Oba panele znajdują się w obiekcie klasy dziedziczącej po JFrame, stanowiącej trzon programu.
Problem zaczyna się w momencie, kiedy chcę wczytać plik za pomocą panelu FileManager i jednocześnie przesłać informację do panelu Plotter, aby zaczął rysować nowe dane. Z poziomu klasy FileManager nie mam dostępu do Plottera, dlatego też zastanawia mnie, w jaki sposób mogę stworzyć obsługę zdarzenia kliknięcia przycisku Dodaj w panelu FileManager tak, aby panelowi Plotter zostały przekazane odpowiednie dane do rysowania.
Z góry dziękuję za odpowiedź, pozdrawiam.
polecam JFileChooser, zawiesza ona wątek z którego zostaje wywołana z metodą showsave/opendialog więc problemu nie ma
btnWybierz.addActionListener(new ActionListener() ;
public void actionPerformed(ActionEvent arg0) ;
int ret = jfc.showSaveDialog(okno);
if(ret == JFileChooser.APPROVE_OPTION)
;
txtGdzieLogowac.setText(jfc.getSelectedFile().toString());
;
;
;);
snipsset z mojego kodu własnego kodu, więcej oczywiście w dokumentacji od oracla
@pecet007
Tak, korzystam z JFileChooser, ale akurat nie o to mi chodzi.
Sytuacja jest taka: JFileChooserem otwieram plik, z którego wczytuję dane do klasy reprezentującej figurę geometryczną. To wszystko jest w obrębie panelu FileManager. Natomiast chcę, aby po wczytaniu pliku filechooserem, obiekt z figurą geometryczną był przesłany do osobnego panelu, który zajmie się rysowaniem tego.
A nie możesz po prostu dodać pola do klasy FileManager zawierającego referencję do Plottera?
class FileManager extends JPanel <
private Plotter plotter;
public FileManager(Plotter plotter) <
this.plotter = plotter;
...
>
...
public jakasMetoda(MyFigure figura) <
...
plotter.malujFigure(figura);
...
>
...
>
(nawiasty trójkątne zamiast klamrowych, bo forum ich nie obsługuje)
Jak wygląda szczyt architektury tego Twojego programu? Któraś z tych klas jest główna czy jest jeszcze inna, która buduje Plotter i FileManager? Czy ten kawałek kodu (o który pytam) nie może stworzyć asocjacji pomiędzy instancją Plottera a instancją FileManagera?
Odpowiadając na Twoje pytanie: taka zależność powinna być zbudowana. Typowe zastosowanie wzorca Observer/EventListener:
http://en.wikipedia.org/wiki/Observer_pattern
java.util.Observer lub java.util.EventListener
BTW. To pytanie nie ma nic wspólnego z GUI. Chodzi o sposoby budowania relacji między klasami, tj. o tzw. wzorce projektowe.
Przekazałem referencję Plottera FileManagerowi i wszystko działa jak trzeba. Proste rozwiązanie, a jakie skuteczne :)
Chciałem zastosować Observera, ale niestety coś za bardzo nie chciało mi to działać, a nie mogłem znaleźć żadnego przykładu z Observerem osadzonym w GUI.
Bardzo Wam dziękuję za pomoc :)
Wersja dla początkujących jest taka, jak pokazał Dexiu. Działa. Jak masz dwie czy pięć klas, to jesteś w stanie się domyśleć o co chodzi.
Jak tych klas masz trzydzieści czy sto albo musisz łatwo opowiedzieć innym co dana klasa robi, to jest złe rozwiązanie. Czy panel rysowania jest zwierzęciem podległym panelowi wyboru pliku? Przekazywanie obiektu do konstruktora sugeruje albo obiekt podrzędny, albo wręcz Wrapper. Nie, raczej są równorzędne, ew. wybór pliku jest podrzędny względem okienka rysowania (jeśli traktować je jako okno główne GUI).
Czy to znaczy, że to co napisał Dexiu jest złe? Nie. Bo we wzorcach projektowych nie chodzi o kod, tylko o organizację klas względem siebie. Zdecydowanie nie sugeruje, że koniecznie powinieneś napisać w jakimś wzorcu projektowym. Ale jeśli kiedyś będziesz mieć coś wspólnego z tworzeniem kodu, lepiej się zapoznaj nimi prędzej niż później. Zdecydowanie ułatwia to i komunikację z innymi programistami i zarządzanie klasami.
Poniżej implementacja w pseudokodzie Java/Python. Do napisania w 3 minuty. Kropki zastępują spacje.
interface DrawListener:
...void draw(drawData)
class Plotter
implements DrawListener:
...void draw(drawData):
......draw this drawData here
class FileManager:
...void registerDrawListener(drawListener):
......myDrawListener = drawListener
...
...void loadFile():
......do everything what needed to load a file
......prepare drawData
......myDrawListener.draw(drawData)