Tworzę aplikację, która wyświetla obrazy i odtwarza dźwięki z bazy danych. Próbuję zdecydować, czy użyć osobnej ramki JFrame, aby dodać obrazy do bazy danych z GUI.
Zastanawiam się tylko, czy dobrą praktyką jest używanie wielu okien JFrame?
Tworzę aplikację, która wyświetla obrazy i odtwarza dźwięki z bazy danych. Próbuję zdecydować, czy użyć osobnej ramki JFrame, aby dodać obrazy do bazy danych z GUI.
Zastanawiam się tylko, czy dobrą praktyką jest używanie wielu okien JFrame?
Odpowiedzi:
Zastanawiam się tylko, czy dobrą praktyką jest używanie wielu ramek JFrame?
Zła (zła, zła) praktyka.
Istnieje wiele sposobów wyświetlania wielu elementów w jednym GUI, np .:
CardLayout
(krótkie demo. ). Dobre dla:
JInternalFrame
/JDesktopPane
zwykle używany do MDI .JTabbedPane
dla grup komponentów.JSplitPane
Sposób wyświetlania dwóch składników, których znaczenie między jednym a drugim (rozmiarem) różni się w zależności od tego, co robi użytkownik.JLayeredPane
wiele dobrze dobranych komponentów.JToolBar
zazwyczaj zawiera grupy działań lub kontroli. Może być przeciągany wokół GUI lub całkowicie zgodnie z potrzebami użytkownika. Jak wspomniano powyżej, zminimalizuje / przywróci zgodnie z postępowaniem rodzica.JList
(prosty przykład poniżej).JTree
.Ale jeśli te strategie nie działają dla konkretnego przypadku użycia, spróbuj wykonać następujące czynności. Ustanów pojedynczy element główny JFrame
, a następnie wyświetl JDialog
lub JOptionPane
wystąpień dla pozostałych elementów swobodnych, używając ramki jako elementu nadrzędnego dla okien dialogowych.
W tym przypadku, gdy wiele elementów jest obrazami, lepiej byłoby użyć jednego z poniższych:
JLabel
(wyśrodkowany w panelu przewijania) do wyświetlenia dowolnego obrazu, który użytkownik jest zainteresowany w danym momencie. Jak widać w ImageViewer
.JList
. Jak widać w tej odpowiedzi . Część „pojedynczego rzędu” działa tylko wtedy, gdy wszystkie mają takie same wymiary. Alternatywnie, jeśli jesteś przygotowany do skalowania obrazów w locie, a wszystkie mają ten sam współczynnik kształtu (np. 4: 3 lub 16: 9).JFrame
s i nigdy nie rozważałem tych problemów, dziękuję za wyjaśnienie!
Wielokrotne JFrame
podejście jest czymś, co wdrożył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 w miarę dojrzewania mojego doświadczenia i wiedzy jako programisty oraz gdy zacząłem czytać i wchłaniać opinie tak wielu bardziej doświadczonych programistów Java, podjąłem próbę odejścia od wielorakiego JFrame
podejścia (zarówno w bieżących, jak i przyszłych projektach) ) tylko po to, by spotkać się z ... uzyskać ten ... opór od moich klientów! Gdy zacząłem wdrażać modalne okna dialogowe do kontrolowania okien potomnych JInternalFrame
oddzielnych 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, programisty, co oczywiście nie jest częstym scenariuszem.
Wyjaśnię więc korzyści płynące z wielorakiego JFrame
podejścia, a także obalę niektóre z wad przedstawionych przez innych.
JFrame
s, dajesz użytkownikowi końcowemu możliwość rozłożenia i kontrolowania tego, co jest na jego ekranie. Koncepcja wydaje się „otwarta” i niewiążąca. Tracisz to, gdy zbliżasz się do jednego dużego JFrame
i kilku JInternalFrame
s.JFrame
s. Chciałem jednak, aby ekran wprowadzania danych JDialog
był tym, którego rodzicem była przeglądarka danych. Dokonałem zmiany 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, podczas gdy odwoływał się do innej części programu (lub strony internetowej, nie nie pamiętam). Nie ma go na wielu monitorach, więc najpierw potrzebował okna dialogowego wejścia i czegoś innegona drugim miejscu, z całkowicie ukrytą przeglądarką danych. To było niemożliwe z, JDialog
a na pewno byłoby niemożliwe z JInternalFrame
również. Niechętnie zmieniłem to z powrotem na oddzielne JFrames
dla jego zdrowia psychicznego, ale nauczyło mnie to ważnej lekcji.JInternalFrame
niż JFrame
. Z mojego doświadczenia wynika, że JInternalFrames
oferują znacznie mniejszą elastyczność. Opracowałem systematyczny sposób obsługi otwierania i zamykania JFrame
s w moich aplikacjach, który naprawdę działa dobrze. Kontroluję ramkę prawie całkowicie z poziomu samego kodu ramki; tworzenie nowych ramek, SwingWorker
które kontrolują pobieranie danych w wątkach w tle i kod GUI w EDT, przywracanie / przybliżanie ramki, jeśli użytkownik spróbuje otworzyć ją dwukrotnie, itp. Wszystko, co musisz otworzyć, JFrame
to wywołać publiczną metodę statyczną open()
i metodę otwartą w połączeniu zwindowClosing()
wydarzenie obsługuje resztę (czy ramka jest już otwarta? czy nie jest otwarta, ale ładowanie? itd.) Ustawiłem to podejście jako szablon, więc nie jest trudno wdrożyć dla każdej ramki.JFrame
potrzebujesz więcej miejsca niż a JInternalFrame
, nawet jeśli otworzysz 100 JFrame
s, o ile więcej zasobów tak naprawdę byś zużył? Jeśli twoim problemem jest wyciek pamięci z powodu zasobów: wywołanie dispose()
uwalnia wszystkie zasoby używane przez ramkę do zbierania elementów bezużytecznych (i ponownie mówię, że JInternalFrame
powinieneś wywołać dokładnie ten sam problem).Dużo napisałem i czuję, że mógłbym pisać więcej. W każdym razie mam nadzieję, że nie zostaniesz odrzucony po prostu dlatego, że jest to niepopularna opinia. Pytanie jest oczywiście cenne i mam nadzieję, że udzieliłem cennej odpowiedzi, nawet jeśli nie jest to powszechna opinia.
Doskonałym przykładem wielu ramek / pojedynczego dokumentu na ramkę ( SDI ) vs. pojedynczej ramki / wielu dokumentów na ramkę ( MDI ) jest Microsoft Excel. Niektóre zalety MDI:
SDI (interfejs jednego dokumentu, tzn. Każde okno może mieć tylko jeden dokument):
MDI (interfejs wielu dokumentów, tzn. Każde okno może zawierać wiele dokumentów):
JFrame
i dużym rodzicu JTabbedPane
; ale z możliwością otwarcia drugiego okna (lub nawet więcej), w którym układ może być inny, oferując zatem zachowanie hybrydowe, w którym miłośnicy SDI są zadowoleni, a także MDI. We wszystkich przypadkach zawsze uważałem za JInternalFrame
okropny wzór, który daje ci wszystkie niedogodności obu światów. Oferowana przez nich elastyczność jest do bani i pochłaniają dużo cennego miejsca na ekranie bez rzeczywistych celów.
JFrame
ma własną ikonę paska zadań. Czasami jest to dokładnie to, czego chcesz, ale czasem nie jest. W WinAPI jest to łatwe do skonfigurowania, ale w Swing wydaje się, że nie da się tego zrobić.
JDialog
ponad JFrame
.
Chciałbym odeprzeć argument „nieprzyjazny dla użytkownika” przykładem, w który właśnie byłem zaangażowany.
W naszej aplikacji mamy okno główne, 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 pojedynczym oknie.
Jeden z uruchamianych przez nich programów przedstawia listę raportów wygenerowanych przez system, a użytkownik może kliknąć ikonę w każdym wierszu, aby otworzyć okno dialogowe podglądu raportów. Ta przeglądarka pokazuje ekwiwalent pionowej / poziomej strony A4 w raporcie, więc użytkownicy lubią to okno, które jest dość duże, prawie wypełniając ekrany.
Kilka miesięcy temu zaczęliśmy otrzymywać żądania od naszych klientów, aby te okna przeglądarki raportów były modelowe, aby mogły mieć jednocześnie otwartych wiele raportów.
Przez pewien czas opierałem się tej prośbie, ponieważ nie sądziłem, że to dobre rozwiązanie. Jednak zmieniłem zdanie, gdy dowiedziałem się, jak użytkownicy radzą sobie z tym „brakiem” naszego systemu.
Otwierali przeglądarkę, używając funkcji „Zapisz jako”, aby zapisać raport jako plik PDF w określonym katalogu, używając Acrobat Reader do otwarcia pliku PDF, a następnie zrobiliby to samo z następnym raportem. Mają wiele czytników Acrobat działających z różnymi danymi wyjściowymi raportów, które chcieli przejrzeć.
Więc ustąpiłem i uczyniłem widza modelką. Oznacza to, że każda przeglądarka ma ikonę paska zadań.
Kiedy najnowsza wersja została im wydana w zeszłym tygodniu, przytłaczającą odpowiedzią jest to, że UWIELBIAJĄ to. To jedno z naszych najpopularniejszych najnowszych ulepszeń systemu.
Więc mów dalej i powiedz użytkownikom, że to, czego chcą, jest złe, ale ostatecznie nie zrobi ci żadnych przysług.
NIEKTÓRE UWAGI:
ModalityType
zamiast logicznego modal
. Dzięki temu w tych oknach dialogowych pojawia się ikona paska zadań.Zrób jInternalFrame w ramce głównej i uczyń ją niewidoczną. Następnie możesz użyć go do dalszych wydarzeń.
jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
Minęło trochę czasu od ostatniego dotknięcia huśtawki, ale generalnie jest to zła praktyka, aby to zrobić. Niektóre z głównych wad, które przychodzą na myśl:
Jest to droższe: będziesz musiał przydzielić znacznie więcej zasobów, aby narysować JFrame niż inny rodzaj kontenera okien, taki jak Dialog lub JInternalFrame.
Nie jest przyjazny dla użytkownika: Nie jest łatwo nawigować w grupie JFrame sklejonych razem, będzie wyglądać, jakby twoja aplikacja była zbiorem niespójnych i źle zaprojektowanych aplikacji.
Jest łatwy w użyciu JInternalFrame Jest to rodzaj retoryczny, teraz jest o wiele łatwiejszy i inni ludzie mądrzejsi (lub z więcej wolnego czasu) niż my już przemyśleli wzorzec Desktop i JInternalFrame, więc polecam go użyć.
JInternalFrame
? Osobiście nie zgadzam się na użycie JInternalFrame
! CardLayout
jest prawdziwym błogosławieństwem!
JInternalFrame
nie oferuje żadnych korzyści w żadnym z trzech wspomnianych przypadków (1. gdzie dowody JInternalFrame
są lżejsze niż JFrame
? 2. Twoje JInternalFrame
mogą być tak samo zagracone / niechlujne / utknąć razem jak kilka JFrame
s. 3. Jak to jest JInternalFrame
łatwiejsze? ten sam dokładny kod, z wyjątkiem tego, że jeden jest zawarty w a, JDesktopPane
a drugi w naturalnym obszarze ekranu.
JComponent
s, oba mają prawie identyczne struktury, z wyjątkiem tego, że jeden jest renderowany na JDesktop
a drugi nie. Znowu przepraszam, ale wierzę, że spekulujesz na temat „wagi” JFrame
. 2. Moje aplikacje używają SDI, a moi klienci są bardzo zadowoleni. Powiedziałeś jednak „masę okien”, co oczywiście byłoby do bani. Ale chodzi mi o to, że „tona” JInternalFrame
ssałaby równie źle! Jeśli mówisz, że JIF pozwalają ci być niechlujnym projektantem interfejsu użytkownika, to okropne. Zaśmiecony bałagan to zagracony bałagan, zarówno JF, jak i JIF.
Zdecydowanie zła praktyka. Jednym z powodów jest to, że nie jest zbyt „przyjazny dla użytkownika”, ponieważ każdy JFrame
pokazuje nową ikonę paska zadań. Kontrolowanie wielu JFrame
s sprawi, że wyrwiesz włosy.
Osobiście użyłbym JEDNEJ JFrame
dla twojego rodzaju aplikacji. Metody wyświetlania wielu rzeczy zależą od Ciebie, jest ich wiele. Canvas
ES JInternalFrame
, CardLayout
nawet JPanel
s ewentualnie.
Wiele obiektów JFrame = Ból, kłopoty i problemy.
Myślę, że używanie wielu Jframe
s nie jest dobrym pomysłem.
Zamiast tego możemy użyć JPanel
więcej niż jednego lub więcej JPanel
w tym samym JFrame
.
Możemy również przełączać się między tymi JPanel
. Daje nam to swobodę wyświetlania więcej niż rzeczy na stronie JFrame
.
Dla każdego z nich JPanel
możemy zaprojektować różne rzeczy, a wszystko to JPanel
może być wyświetlane pojedynczo JFrame
.
Aby przełączać się między tym JPanel
, a korzystanie JMenuBar
z JMenuItems
dla każdego JPanel
lub „JButton for each
JPanel`.
Więcej niż jeden JFrame
nie jest dobrą praktyką, ale nie ma nic złego, jeśli chcemy więcej niż jednego JFrame
.
Ale lepiej jest zmienić jeden JFrame
dla naszych różnych potrzeb niż mieć wiele JFrame
s.
Jeśli ramki będą tego samego rozmiaru, dlaczego nie utworzyć ramki i przekazać ją jako odniesienie do niej.
Po przejściu ramki możesz zdecydować, jak ją wypełnić. To tak, jakby mieć metodę obliczania średniej z zestawu liczb. Czy tworzysz tę metodę w kółko?
Nie jest to dobra praktyka, ale nawet jeśli chcesz jej użyć, możesz użyć wzorca singletonu jako dobrego. Używałem wzorców singletonów w większości moich projektów, które są dobre.