Zastosowanie wielu ramek JFrames: dobra czy zła praktyka? [Zamknięte]

Mar 04 2012

Tworzę aplikację, która wyświetla obrazy i odtwarza dźwięki z bazy danych. Próbuję zdecydować, czy użyć oddzielnego JFrame, aby dodać obrazy do bazy danych z GUI.

Zastanawiam się tylko, czy używanie wielu okien JFrame jest dobrą praktyką?

Odpowiedzi

456 AndrewThompson Mar 04 2012 at 18:56

Zastanawiam się tylko, czy używanie wielu ramek JFrames jest dobrą praktyką?

Zła (zła, zła) praktyka.

  • Nieprzyjazny dla użytkownika: użytkownik widzi wiele ikon na pasku zadań, oczekując, że zobaczy tylko jedną. Plus skutki uboczne problemów z kodowaniem.
  • Koszmar do kodowania i utrzymywania:
    • Modalne okno dialogowe oferuje łatwą okazję do skupienia uwagi na treść tego okna - Wybierz / fix / anulować to, następnie kontynuować. Wiele ramek nie.
    • Okno dialogowe (lub ruchomy pasek narzędzi) z rodzicem pojawi się na wierzchu, gdy zostanie kliknięty rodzic - musiałbyś to zaimplementować w ramkach, gdyby było to pożądane zachowanie.

Istnieje wiele sposobów wyświetlania wielu elementów w jednym GUI, np .:

  • CardLayout(krótkie demo ). Dobre dla:
    1. Wyświetlanie okien dialogowych przypominających kreatora.
    2. Wyświetlanie list, drzew itp. Dla elementów, które mają skojarzony komponent.
    3. Przełączanie między brakiem komponentu a widocznym komponentem.
  • JInternalFrame/JDesktopPane zwykle używany do MDI .
  • JTabbedPane dla grup komponentów.
  • JSplitPane Sposób wyświetlania dwóch komponentów, których znaczenie między jednym a drugim (rozmiarem) różni się w zależności od tego, co robi użytkownik.
  • JLayeredPane dużo dobrze ... warstwowych komponentów.
  • JToolBarzazwyczaj zawiera grupy działań lub kontrolek. Można go przeciągać po GUI lub całkowicie z niego w zależności od potrzeb użytkownika. Jak wspomniano powyżej, zminimalizuje / przywróci zgodnie z tym, co robi rodzic.
  • Jako elementy w JList(prosty przykład poniżej).
  • Jako węzły w JTree.
  • Zagnieżdżone układy .

Ale jeśli te strategie nie działają w konkretnym przypadku użycia, wypróbuj następujące rozwiązania. Skonfiguruj pojedynczy element główny JFrame, a dla pozostałych elementów swobodnych pojawią się wystąpienia JDialoglub JOptionPanewystąpienia, używając ramki jako elementu nadrzędnego dla okien dialogowych.

Wiele obrazów

W tym przypadku, gdy wiele elementów to obrazy, lepiej byłoby zamiast tego użyć jednego z poniższych:

  1. Pojedynczy JLabel(wyśrodkowany w okienku przewijania) do wyświetlenia dowolnego obrazu, którym użytkownik jest w danej chwili zainteresowany. Jak widać w ImageViewer.
  2. Pojedynczy rząd JList. Jak widać w tej odpowiedzi . Część „jednorzędowa” działa tylko wtedy, gdy wszystkie mają takie same wymiary. Alternatywnie, jeśli jesteś przygotowany do skalowania obrazów w locie i wszystkie mają ten sam współczynnik proporcji (np. 4: 3 lub 16: 9).

205 ryvantage Jul 31 2013 at 10:33

Wielokrotne JFramepodejście jest czymś, co zaimplementowałem, odkąd zacząłem programować aplikacje Swing. W większości zrobiłem to na początku, ponieważ nie wiedziałem nic lepszego. Jednak , gdy dojrzewałem w swoim doświadczeniu i wiedzy jako programista oraz gdy zacząłem czytać i przyswajać opinie wielu bardziej doświadczonych programistów Java w Internecie, podjąłem próbę odejścia od JFramepodejścia wielokrotnego (zarówno w bieżących, jak i przyszłych ) tylko po to, by spotkać się z ... uzyskać ten ... opór moich klientów! Gdy zacząłem wdrażać modalne okna dialogowe do sterowania oknami „podrzędnymi” i oknami JInternalFramedla poszczególnych komponentów, moi klienci zaczęli narzekać! Byłem dość zaskoczony, ponieważ robiłem to, co uważałem za najlepszą praktykę! Ale, jak mówią: „Szczęśliwa żona to szczęśliwe życie”. To samo dotyczy twoich klientów. Oczywiście jestem wykonawcą, więc moi użytkownicy końcowi mają bezpośredni dostęp do mnie, dewelopera, co oczywiście nie jest częstym scenariuszem.

Więc zamierzam wyjaśnić zalety JFramepodejścia wielorakiego , a także obalić niektóre z wad, które przedstawili inni.

  1. Najwyższa elastyczność układu - umożliwiając oddzielne układyJFrame , dajesz użytkownikowi końcowemu możliwość rozłożenia i kontrolowania tego, co jest na jego ekranie. Koncepcja wydaje się „otwarta” i nieograniczona. Tracisz to, gdy idziesz w kierunku jednego dużego JFramei kilku JInternalFrames.
  2. Działa dobrze w przypadku bardzo modułowych aplikacji - w moim przypadku większość moich aplikacji ma 3-5 dużych „modułów”, które tak naprawdę nie mają ze sobą nic wspólnego. Na przykład jeden moduł może być pulpitem sprzedażowym, a drugi może być pulpitem księgowym. Nie rozmawiają ze sobą ani nic. Jednak dyrektor może chcieć otworzyć oba, a oddzielne ramki na pasku zadań ułatwiają mu życie.
  3. Ułatwia użytkownikom końcowym odwoływanie się do materiałów zewnętrznych - Kiedyś miałem taką sytuację: moja aplikacja miała „przeglądarkę danych”, w której można było kliknąć „Dodaj nowy” i otworzyła się ekran wprowadzania danych. Początkowo obaj byli JFrames. Jednak chciałem, aby ekran wprowadzania danych JDialogbył tym, którego rodzicem był przeglądarka danych. Wprowadziłem zmianę i natychmiast otrzymałem telefon od użytkownika końcowego, który w dużej mierze polegał na tym, że mógł zminimalizować lub zamknąć przeglądarkę i pozostawić otwarty edytor, gdy odwoływał się do innej części programu (lub strony internetowej, nie nie pamiętam). To nie na multi-monitorem, więc musiał oknie wprowadzania być pierwszym i coś jeszcze być drugi, przy czym dane widza całkowicie ukryte. To było niemożliwe w przypadku a, JDialoga na pewno byłoby niemożliwe również w przypadku JInternalFramea. Niechętnie zmieniłem to z powrotem na oddzielenie się JFramesdla jego zdrowia psychicznego, ale nauczyło mnie to ważnej lekcji.
  4. Mit: Trudny do zakodowania - z mojego doświadczenia wynika, że ​​nie jest to prawdą. Nie rozumiem, dlaczego byłoby łatwiej stworzyć plik JInternalFrameniż JFrame. W rzeczywistości, z mojego doświadczenia, JInternalFramesoferują znacznie mniejszą elastyczność. Opracowałem systematyczny sposób obsługi otwierania i zamykania JFramew moich aplikacjach, który naprawdę działa dobrze. Kontroluję ramkę prawie całkowicie z poziomu samego kodu ramki; utworzenie nowej ramki, SwingWorkerktóra kontroluje pobieranie danych z wątków w tle i kodu GUI na EDT, przywracanie / przenoszenie na wierzch ramki, jeśli użytkownik spróbuje ją dwukrotnie otworzyć itp. Wszystko, czego potrzebujesz, aby otworzyć moje JFrameto wywołaj publiczną metodę statyczną, open()a metoda open, w połączeniu ze windowClosing()zdarzeniem, obsługuje resztę (czy ramka jest już otwarta? czy nie jest otwarta, ale ładuje? itd.). .
  5. Myth / Unproven: Resource Heavy - chciałbym zobaczyć kilka faktów stojących za tym spekulatywnym stwierdzeniem. Chociaż, być może, możesz powiedzieć, że a JFramepotrzebuje więcej miejsca niż a JInternalFrame, nawet jeśli otworzysz 100 JFramesekund, ile więcej zasobów naprawdę byś zużywał? Jeśli twoim problemem są wycieki pamięci z powodu zasobów: wywołanie dispose()zwalnia wszystkie zasoby używane przez ramkę do czyszczenia pamięci (i znowu mówię, a JInternalFramepowinno wywoływać dokładnie to samo).

Dużo napisałem i czuję, że mógłbym pisać więcej. Tak czy inaczej, mam nadzieję, że nie zostanę w głosowaniu negatywnym tylko dlatego, że jest to niepopularna opinia. Pytanie jest bez wątpienia wartościowe i mam nadzieję, że udzieliłem wartościowej odpowiedzi, nawet jeśli nie jest to powszechna opinia.

Doskonałym przykładem wielu ramek / jednego dokumentu na ramkę ( SDI ) w porównaniu z jedną ramką / wieloma dokumentami na ramkę ( MDI ) jest Microsoft Excel. Niektóre korzyści z MDI:

  • możliwe jest posiadanie kilku okien w nieprostokątnym kształcie - dzięki czemu nie zasłaniają one pulpitu ani innego okna przed innym procesem (np. przeglądarką internetową)
  • istnieje możliwość otwarcia okna z innego procesu w jednym oknie Excela podczas pisania w drugim oknie Excela - za pomocą MDI próba pisania w jednym z okien wewnętrznych spowoduje skupienie się na całym oknie Excela, a tym samym ukrycie okna z innego procesu
  • możliwe jest umieszczanie różnych dokumentów na różnych ekranach, co jest szczególnie przydatne, gdy ekrany nie mają tej samej rozdzielczości

SDI (Single-Document Interface, czyli każde okno może mieć tylko jeden dokument):

MDI (interfejs wielu dokumentów, tj. Każde okno może mieć wiele dokumentów):

53 DuncanKinnear Aug 30 2013 at 10:36

Chciałbym odeprzeć argument „nie przyjazny dla użytkownika” za pomocą przykładu, z którym właśnie się zapoznałem.

W naszej aplikacji mamy główne okno, w którym użytkownicy uruchamiają różne „programy” jako osobne zakładki. W miarę możliwości staraliśmy się zachować naszą aplikację w tym jednym oknie.

Jeden z uruchamianych przez nie „programów” przedstawia listę raportów wygenerowanych przez system, a użytkownik może kliknąć ikonę w każdym wierszu, aby otworzyć okno dialogowe przeglądarki raportów. Ta przeglądarka pokazuje odpowiednik pionowej / poziomej strony (stron) A4 raportu, więc użytkownikom podoba się to, że okno jest dość duże i prawie wypełnia ich ekrany.

Kilka miesięcy temu zaczęliśmy otrzymywać prośby od naszych klientów, aby te okna przeglądarki raportów były niemodalne, aby mogli mieć jednocześnie otwartych wiele raportów.

Przez pewien czas sprzeciwiałem się tej prośbie, ponieważ nie uważałem, że to dobre rozwiązanie. Jednak zmieniłem zdanie, gdy dowiedziałem się, jak użytkownicy radzą sobie z tą „wadą” naszego systemu.

Otwierali przeglądarkę, używając funkcji „Zapisz jako”, aby zapisać raport jako plik PDF w określonym katalogu, używając programu Acrobat Reader do otwierania pliku PDF, a następnie robili to samo z następnym raportem. Mieliby wielu czytników Acrobat działających z różnymi wyjściami raportów, które chcieliby obejrzeć.

Więc ustąpiłem i sprawiłem, że widz był niemodalny. Oznacza to, że każda przeglądarka ma ikonę na pasku zadań.

Kiedy w zeszłym tygodniu ukazała się im najnowsza wersja, przytłaczającą odpowiedzią z ich strony jest to, że ją UWIELBIAJĄ. To jedno z naszych najpopularniejszych ostatnich ulepszeń systemu.

Więc śmiało mówisz swoim użytkownikom, że to, czego chcą, jest złe, ale ostatecznie nie przyniesie ci to żadnych korzyści.

NIEKTÓRE UWAGI:

  • Wydaje się, że najlepszą praktyką jest używanie JDialog dla tych niemodalnych okien
  • Użyj konstruktorów, które używają nowego, ModalityTypea nie modalargumentu logicznego . To właśnie nadaje tym oknom dialogowym ikonę na pasku zadań.
  • W przypadku niemodalnych okien dialogowych należy przekazać konstruktorowi zerowego rodzica, ale zlokalizować je względem okna „nadrzędnego”.
  • Wersja 6 Javy w systemie Windows ma błąd, który oznacza, że ​​główne okno może stać się „zawsze na wierzchu” bez konieczności informowania o tym. Zaktualizuj do wersji 7, aby to naprawić
20 VirendraSinghRathore Oct 17 2012 at 12:25

Zrób ramkę jInternalFrame w ramce głównej i uczyń ją niewidoczną. Następnie możesz go użyć do dalszych wydarzeń.

jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
19 Necronet Mar 05 2013 at 07:55

Minęło trochę czasu od ostatniego dotknięcia swinga, ale ogólnie jest to zła praktyka. Niektóre z głównych wad, które przychodzą na myśl:

  • Jest droższy: będziesz musiał przeznaczyć znacznie więcej zasobów, aby narysować JFrame niż inny rodzaj kontenera okiennego, taki jak Dialog lub JInternalFrame.

  • Niezbyt przyjazny dla użytkownika: nie jest łatwo przejść do zlepionych razem JFrame, będzie wyglądać, jakby twoja aplikacja była zbiorem aplikacji niespójnych i źle zaprojektowanych.

  • Jest łatwy w użyciu JInternalFrame Jest to trochę retoryczne, teraz jest o wiele łatwiejsze i inne osoby mądrzejsze (lub z większą ilością wolnego czasu) niż my myśleliśmy o wzorcu Desktop i JInternalFrame, więc polecam go użyć.

10 MattDawsey Jan 10 2013 at 17:37

Zdecydowanie zła praktyka. Jednym z powodów jest to, że nie jest on zbyt „przyjazny dla użytkownika”, ponieważ każdy JFramewyświetla nową ikonę na pasku zadań. Kontrolowanie wielu JFrames spowoduje, że będziesz wyrywać włosy.

Osobiście użyłbym JEDNEGO JFramedo twojego rodzaju aplikacji. Metody wyświetlania wielu rzeczy zależą od Ciebie, jest ich wiele. CanvasES JInternalFrame, CardLayoutnawet JPanels ewentualnie.

Wiele obiektów JFrame = ból, kłopoty i problemy.

8 Lijo Dec 18 2013 at 14:03

Myślę, że używanie wielu Jframes nie jest dobrym pomysłem.

Zamiast tego możemy użyć JPanelwięcej niż jednego lub więcej JPanelw tym samym JFrame.

Możemy również przełączać się między tymi JPanelplikami. Daje nam więc swobodę wyświetlania więcej niż rzeczy w formacie JFrame.

Dla każdego JPanelmożemy zaprojektować różne rzeczy i wszystko to JPanelmoże być pokazane na JFramejednej na raz.

Aby przełączać się między tym JPanel, a korzystanie JMenuBarz JMenuItemsdla każdego JPanellub „JButton for eachJPanel`.

Więcej niż jeden JFramenie jest dobrą praktyką, ale nie ma nic złego, jeśli chcemy więcej niż jeden JFrame.

Ale lepiej jest zmienić jeden JFramedla naszych różnych potrzeb, niż mieć wiele JFrame.

5 KeithSpriggs Sep 04 2013 at 05:25

Jeśli ramki mają mieć ten sam rozmiar, dlaczego nie utworzyć ramki i zamiast tego przekazać ją jako odniesienie do niej.

Po przejściu ramki możesz zdecydować, jak ją wypełnić. Byłoby to jak metoda obliczania średniej ze zbioru liczb. Czy stworzyłbyś tę metodę w kółko?

5 arunjoseph Dec 14 2013 at 20:20

Nie jest to dobra praktyka, ale nawet jeśli chcesz jej użyć, możesz użyć wzorca singleton jako dobrego. W większości moich projektów korzystałem z pojedynczych wzorów, co jest dobre.