Proces tworzenia prostego programu GUI w Javie. Tworzenie GUI w Javie Tworzenie aplikacji GUI w Javie

Interfejs graficzny w Javie przeszedł bardzo ciernistą ścieżkę rozwoju i formowania. Przez długi czas zarzucano mu powolność, zachłanność zasobów systemowych i ograniczoną funkcjonalność.

Java AWT

Pierwsza próba stworzenia firmy Sun graficzny interfejs użytkownika istniała biblioteka dla Javy A.W.T.(Abstract Window Toolkit) - zestaw narzędzi do pracy z różnymi środowiskami okiennymi. Firma Sun stworzyła warstwę Java, która wywołuje metody z bibliotek napisanych w języku C. Metody bibliotek AWT tworzą i wykorzystują graficzne komponenty środowiska operacyjnego. Z jednej strony jest to dobre, ponieważ program Java jest podobny do innych programów w tym samym systemie operacyjnym. Ale gdy uruchomisz go na innej platformie, mogą pojawić się różnice w rozmiarach komponentów i czcionek, które zepsują wygląd programu.

Aby zapewnić wieloplatformowość A.W.T. Interfejsy wywołań komponentów zostały ujednolicone, w wyniku czego ich funkcjonalność została nieco zmniejszona. A zestaw komponentów okazał się dość mały. Na przykład AWT nie ma tabel, a przyciski nie obsługują wyświetlania ikon. Jeszcze pakiet Java.awt jest zawarty w Javie od pierwszego wydania i może być używany do tworzenia GUI.

Zatem komponenty A.W.T. Nie wykonują żadnej „pracy”. To po prostu „opakowanie Java” dla elementów sterujących system operacyjny, na którym pracują. Wszystkie żądania kierowane do tych komponentów są przekierowywane do systemu operacyjnego, który wykonuje całą pracę.

Wykorzystane zasoby A.W.T. próbuje zwolnić automatycznie. Zwiększa to nieco złożoność architektury i wpływa na wydajność. Trochę trudno będzie napisać coś poważnego przy użyciu AWT. Obecnie jest używany tylko w przypadku apletów.

Podstawowe pojęcia SWINGU

Po A.W.T. Firma Sun opracowała bibliotekę komponentów graficznych Huśtać się, napisany w całości w Javie. Do renderowania wykorzystuje się technologię 2D, co niesie ze sobą kilka korzyści. Zestaw standardowych komponentów znacznie przewyższa AWT pod względem różnorodności i funkcjonalności. Swing ułatwia tworzenie nowych komponentów poprzez dziedziczenie z istniejących i obsługuje różne style i skórki.

Twórcy nowej biblioteki interfejsu użytkownika Huśtać się Nie „wymyślili koła na nowo” i wybrali AWT jako podstawę swojej biblioteki. Oczywiście nie rozmawialiśmy o użyciu konkretnych, ciężkich komponentów AWT (reprezentowanych przez klasy Button, Label i tym podobne). Tylko lekkie komponenty zapewniały wymagany stopień elastyczności i sterowności. Diagram dziedziczenia pokazuje związek pomiędzy AWT i Swing.

Najważniejsza różnica Huśtać się z AWT polega na tym, że komponenty Swinga nie są w ogóle połączone z systemem operacyjnym i dlatego są znacznie stabilniejsze i szybsze. Komponenty te nazywane są w Javie lekkimi elementami i zrozumienie podstawowych zasad ich działania znacznie ułatwi wyjaśnienie działania Swinga.

Kontenery obrotowe na najwyższym poziomie

Aby utworzyć aplikację GUI, musisz użyć specjalnych komponentów biblioteki Swing, zwanych kontenerami najwyższego poziomu. Są to okna systemu operacyjnego zawierające elementy interfejsu użytkownika. Kontenery najwyższego poziomu obejmują okna JFrame i JWindow, okno dialogowe JDialog i aplet JApplet (który nie jest oknem, ale ma również na celu wyświetlanie interfejsu w przeglądarce, która uruchamia ten aplet). Kontenery najwyższego poziomu firmy Swing to komponenty ciężkie i stanowią wyjątek od ogólnej reguły. Wszystkie pozostałe elementy Swinga są lekkie.

Prosty Huśtać się przykład tworzenia interfejsu okiennego JFrama.

Importuj java.awt.Dimension; importuj javax.swing.JFrame; importuj javax.swing.JLabel; klasa publiczna JFrameTest ( public static void createGUI() ( Ramka JFrame = nowa JFrame("Ramka testowa"); ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Etykieta JLabel = new JLabel("Etykieta testowa"); ramka.getContentPane(). add(label); ramka.setPreferredSize (nowy wymiar (200, 100)); ramka.setVisible (true); publiczna statyczna pusta główna (argumenty ciągu) (JFrame.setDefaultLookAndFeelDecorated (true); javax. swing.SwingUtilities.invokeLater (nowy Runnable() ( public void run() ( createGUI(); ) ))

Konstruktor JFrame() bez parametrów tworzy puste okno. Konstruktor JFrame (tytuł ciągu) tworzy puste okno z tytułem tytułu. Aby stworzyć najprostszy program przy pustym oknie musisz użyć następujących metod:

  • setSize(int szerokość, int wysokość) - określenie rozmiaru okna;
  • setDefaultCloseOperation(int operacja) - określenie akcji po zakończeniu programu;
  • setVisible(boolean widoczne) - powoduje, że okno jest widoczne.

Jeśli nie zdefiniujesz wymiarów okna, będzie ono miało zerową wysokość, niezależnie od tego, co się w nim znajduje. Wymiary okna obejmują nie tylko obszar „roboczy”, ale także krawędzie i pasek tytułu.

Metoda setDefaultCloseOperation określa akcję, która ma zostać wykonana po „zakończeniu programu”. W tym celu należy jako parametr operacji przekazać stałą EXIT_ON_CLOSE opisaną w klasie JFrame.

Domyślnie okno jest tworzone jako niewidoczne. Aby wyświetlić okno na ekranie, wywoływana jest metoda setVisible z parametrem true. Wywołane z parametrem false okno stanie się niewidoczne.

Interfejs graficzny huśtawka w Javie przykład tworzenia okna JFrama przedstawiono na poniższym rysunku.

Aby połączyć bibliotekę Huśtać się aplikacja musi zaimportować bibliotekę javax.swing.

Za każdym razem, gdy tworzony jest kontener najwyższego poziomu, czy to zwykłe okno, okno dialogowe, czy aplet, a panel główny JRootPane. Kontenery najwyższego poziomu Swinga zapewniają, że inne komponenty nie mogą wydostać się poza JRootPane.

Paleta korzeniowa JRootPane dodaje do kontenerów właściwość „głębokość”, zapewniając możliwość nie tylko umieszczania komponentów jeden nad drugim, ale także, w razie potrzeby, zmiany ich położenia, zwiększania lub zmniejszania głębokości komponentów. Ta funkcja jest niezbędna podczas tworzenia aplikacji wielodokumentowej. Huśtać się, w którym okna reprezentują lekkie komponenty umieszczone jeden na drugim, a także menu rozwijane (kontekstowe) i podpowiedzi.

Poniższy rysunek wyraźnie pokazuje strukturę panelu głównego JRootPane.

Panel główny JRootPane to kontener odziedziczony z klasy bazowej Swing JComponent. W tym kontenerze za rozmieszczenie komponentów odpowiada specjalny menadżer układu, zaimplementowany w wewnętrznej klasie RootPaneLayout. Ten menedżer układu jest odpowiedzialny za to, aby wszystkie elementy panelu głównego zostały umieszczone tak, jak powinny: panel warstwowy zajmuje całą przestrzeń okna; jego warstwa FRAME_CONTENT_LAYER zawiera pasek menu i panel treści, a przede wszystkim przezroczysty panel.

Wszystkie elementy panelu głównego JRootPane można uzyskać lub zmienić. Aby to zrobić, ma zestaw metod get/set. Programowo JRootPane można uzyskać za pomocą metody getRootPane().

Oprócz kontenerów najwyższego poziomu, panel główny wykorzystywany jest w wewnętrznych oknach JInternalFrame tworzonych w aplikacjach wielodokumentowych i znajdujących się na „pulpicie” JDesktopPane. Dzięki temu można zapomnieć o tym, że te okna to zwykłe lekkie elementy i pracować z nimi jak z prawdziwymi kontenerami z najwyższej półki.

JLayeredPane

U podstawy panelu głównego (kontenera) znajduje się tzw. panel wielowarstwowy JLayeredPane, zajmując całą dostępną przestrzeń kontenera. To w tym panelu znajdują się wszystkie pozostałe części panelu głównego, w tym wszystkie elementy interfejsu użytkownika.

JLayeredPane używany do dodawania właściwości głębokości do kontenera. Oznacza to, że panel wielowarstwowy pozwala uporządkować trzeci wymiar w kontenerze, wzdłuż którego rozmieszczone są warstwy komponentu. W zwykłym kontenerze położenie komponentu określa prostokąt, który pokazuje, jaką część kontenera zajmuje komponent. Dodając komponent do panelu warstwowego, należy określić nie tylko prostokąt, który będzie zajmował komponent, ale także warstwę, w której będzie się znajdował. Warstwa płyty warstwowej jest identyfikowana liczbą całkowitą. Im wyższa liczba określająca warstwę, tym wyżej jest ona położona.

Pierwszy komponent dodany do kontenera ma wyższą rangę niż komponenty dodane później. Najczęściej programista nie zajmuje się położeniem komponentów. Podczas dodawania komponentów ich położenie zmienia się automatycznie. Panel wielowarstwowy pozwala jednak na dynamiczną zmianę położenia komponentów już po ich dodaniu do kontenera.

Niektóre komponenty szeroko wykorzystują możliwości paneli laminowanych Huśtać się. Są one szczególnie ważne w przypadku aplikacji obsługujących wiele dokumentów, etykiet narzędzi i menu. Wiele dokumentów Huśtać się aplikacje korzystają ze specjalnego kontenera JDesktopPane(„pulpit”), odziedziczony z JLayeredPane, w którym mieszczą się wewnętrzne okna typu Swing. Najważniejsze funkcje aplikacji obsługującej wiele dokumentów – umieszczanie „aktywnego” okna na innych, minimalizowanie okien, przeciąganie ich – zapewniają mechanizmy panelu warstwowego. Główną zaletą stosowania warstwowego panelu podpowiedzi i menu jest to, że działają one szybciej. Zamiast tworzyć nowe, wytrzymałe okno dla każdej podpowiedzi lub menu znajdującego się nad komponentem, który zażądał wyświetlenia podpowiedzi lub menu, Huśtać się tworzy szybki i lekki komponent. Ten komponent jest umieszczony wystarczająco wysoko w panelu warstwowym, nad stosem wszystkich innych komponentów i służy do wyświetlania podpowiedzi lub menu.

Panel wielowarstwowy pozwala na organizowanie nieograniczonej liczby warstw. Struktura JLayeredPane zawiera kilka standardowych warstw, z których korzystają wszystkie komponenty Swinga, co zapewnia poprawną pracę wszystkich mechanizmów panelu wielowarstwowego. Standardowe warstwy JLayeredPane pokazano na poniższym rysunku.

Warstwa domyślna służy do przechowywania wszystkich normalnych komponentów dodawanych do kontenera. W warstwie tej znajdują się wewnętrzne okna aplikacji obsługujących wiele dokumentów.

Warstwa Paleta przeznaczona jest do przechowywania okien z zestawem narzędzi, które zazwyczaj nakładają się na inne elementy interfejsu. Możesz utworzyć takie okna za pomocą JDesktopPane, który umieszcza je na tej warstwie.

Warstwa modalna była przeznaczona do obsługi lekkich modalnych okien dialogowych. Jednak takie okna dialogowe nie są jeszcze zaimplementowane, więc ta warstwa nie jest obecnie używana w Swingu.

Najczęściej używana warstwa do umieszczania wyskakujących menu i podpowiedzi.

Najwyższa warstwa. Zaprojektowany do operacji przeciągania i upuszczania i upuść), co powinno być wyraźnie widoczne w interfejsie programu.

Mały przykład JLayeredPane z panelem warstwowym pokazuje, jak dodawać komponenty do różnych warstw i jak warstwy są ułożone jedna na drugiej:

Importuj javax.swing.*; importuj java.awt.*; // klasa do rysowania dwóch typów figur z klasą tekstową Rysunek rozszerza JComponent ( private static final long serialVersionUID = 1L; private Kolor koloru; prywatny typ int; prywatny tekst ciągu; // parametry: kolor i typ figury Rysunek(Kolor koloru, typ int, tekst typu String) ( this.color = color; this.type = type; this.text = tekst; setOpaque(false); ) public void paintComponent(Graphics g ) ( // rysowanie figury g.setColor(color); przełącznik (typ) ( przypadek 0: g.fillOval(0, 0, 90, 90); przerwa; przypadek 1: g.fillRect(0, 0, 130 , 80 ); break; ) g.setColor(Color.yellow); g.drawString(text, 10, 35); super("Przykładowy test warstwowy"); // wyjście przy zamykaniu okna setDefaultCloseOperation(EXIT_ON_CLOSE); panel warstwowy JLayeredPane lp = getLayeredPane(); // tworzenie trzech figur Rysunek rysunek1 = nowy Rysunek(Color.red , 0, "Wyskakujące okienko z rysunkiem"); Rysunek rysunek2 = nowy Rysunek(Color.blue, 0, "Rysunek 1") ; Rysunek figure3 = nowy Rysunek(Color.cyan, 1, "Rysunek 2"); // określenie położenia figur w oknie figure1.setBounds (10, 40, 120, 120); rysunek2.setBounds(60, 120, 160, 180); rysunek3.setBounds(90, 55, 250, 180); // dodawanie kształtów do różnych warstw lp.add(figure1, JLayeredPane.POPUP_LAYER); lp.add(figura2, JLayeredPane.PALETTE_LAYER); lp.add(rysunek3, JLayeredPane.PALETTE_LAYER); // zmiana położenia jednej z cyfr lp.setPosition(figure3, 0); // określenie rozmiaru i otwarcie okna setSize(280, 250); setVisible(true); ) public static void main(String args) ( JFrame.setDefaultLookAndFeelDecorated(true); nowy JLayeredPaneTest(); ) )

Przykład tworzy małe okno JFrama i do panelu warstwowego dodano kilka komponentów Figury. Aby uzyskać panel warstwowy w dowolnym kontenerze Swing najwyższego poziomu, wystarczy wywołać metodę getLayeredPane().

Klasa pomocnicza Figura dziedziczy właściwości bazowej klasy JComponent i umożliwia rysowanie dwóch typów kształtów (okręgów i prostokątów) w różnych kolorach. Parametry rysowania figur ustawia się w konstruktorze klasy.

Podczas definiowania interfejsu tworzone są trzy kształty o różnych kolorach (dwa koła i prostokąt). Okrąg zostanie umieszczony w warstwie POPUP_LAYER, a prostokąty w warstwie PALETTE_LAYER. Umieszczając komponenty, określasz ich bezwzględne współrzędne ekranu, ponieważ normalne menedżery układów nie działają w panelu warstwowym.

Ostatecznie zmienia się położenie jednego z prostokątów tak, aby był on pierwszym w warstwie, choć pierwotnie był dodany jako drugi. Po uruchomieniu aplikacji zobaczysz, że panel warstwowy działa i starannie układa komponenty zgodnie z ich warstwami i położeniem.

W konwencjonalnych zastosowaniach płyta warstwowa rzadko jest wykorzystywana bezpośrednio, w której spełnia swoje funkcje w sposób niewidoczny. Czasami jednak pomaga stworzyć niesamowite efekty i niezwykłe interfejsy, pozwalając na przykład na umieszczenie animacji lub wideo na zwykłych komponentach, bez konieczności nadludzkiego wysiłku i trików ze strony dewelopera.

Panel treści

Panel zawartości ContentPane to kolejna część panelu głównego, w której znajdują się komponenty interfejsu użytkownika programu. Panel treści zajmuje większość przestrzeni warstwowego panelu (z wyjątkiem przestrzeni zajmowanej przez pasek menu). Aby zapobiec zasłanianiu przez panel treści elementów dodawanych później do okna, panel warstwowy umieszcza go w specjalnej, bardzo niskiej warstwie o nazwie FRAME_CONTENT_LAYER, o numerze -30000.

Dostęp do panelu treści można uzyskać za pomocą metody getContentPane() klasa JFrame. Korzystając z metody add(Component Component) możesz dodać do niego dowolny element sterujący. Zastępować Panel treści Za pomocą tej metody można zastosować dowolny inny panel typu JPanel setContentPane()

Przykład dodania przycisku do panelu treści:

JButton nowyButton = nowy JButton(); getContentPane().add(nowyPrzycisk);

W rezultacie otrzymujemy okienko z przyciskiem. Przycisk zajmuje całą dostępną powierzchnię okna. Efekt ten nie jest przydatny we wszystkich programach, dlatego konieczne jest zastosowanie różnych sposobów ułożenia elementów na panelu.

Panel treści można całkowicie wymienić. Rozważ następujące Huśtać się przykład wykorzystania panelu treści Panel treści.

Importuj javax.swing.*; klasa publiczna ContentPaneReplace rozszerza JFrame ( private static final long serialVersionUID = 1L; public ContentPaneReplace() ( super("Test ContentPane"); setDefaultCloseOperation(EXIT_ON_CLOSE); // Utwórz panel z dwoma przyciskami JPanel content = new JPanel(); content. add (new JButton("Rodzina")); content.add(new JButton("Szkoła")); // Zastąpienie panelu treści setContentPane(contents); // Określenie rozmiaru okna setSize(200, 100); true); publiczny statyczny void main(args String) ( JFrame.setDefaultLookAndFeelDecorated(true); new ContentPaneAdd(); ) )

Przykład tworzy małe okno i panel z dwoma przyciskami, czyli wtedy setContentPane() zastępuje panel zawartości okna. Zamiast prostszego dodania zastosowano więc zamianę - wywołanie metody add(). Interfejs okna pokazano na poniższym zrzucie ekranu.

Panel treści Panel treści samo w sobie nie jest niczym specjalnym. Trzeba tylko pamiętać, że składniki są do niego specjalnie dodawane.

Przezroczysty JOptionPane

Przezroczysty panel JOptionPane umieszczony jako panel główny nad wszystkimi elementami panelu wielowarstwowego. Umieszczenie JOptionPane jest kontrolowane przez panel główny, który umieszcza przezroczysty panel nad panelem warstwowym, tak że całkowicie zakrywa cały obszar okna, łącznie z obszarem zajmowanym przez pasek menu.

JOptionPane Jest rzadko używany w aplikacjach, dlatego domyślnie panel główny czyni go niewidocznym, co zmniejsza obciążenie systemu rysunkowego. Jedną rzeczą, o której należy pamiętać, jest to, że jeśli uczynisz przezroczysty panel widocznym, musisz upewnić się, że jest przezroczysty (jego właściwość opaque jest ustawiona na false), ponieważ w przeciwnym razie zasłoni wszystkie inne elementy panelu głównego i resztę interfejs będzie niewidoczny.

W jakich przypadkach można zastosować panel przezroczysty? JOptionPane? Za jego pomocą można zidentyfikować funkcje aplikacji, których wdrożenie od podstaw wymagałoby dużego wysiłku. Przezroczysty panel można dostosować do automatycznego testowania interfejsu użytkownika. Syntetyzowane w nim zdarzenia pozwalają śledzić pośrednie wyniki debugowania. Czasami takie podejście jest znacznie bardziej skuteczne niż testowanie ręczne.

Przezroczysty panel JOptionPane można użyć do stworzenia fajnej animacji, która unosi się nad wszystkimi komponentami, w tym na pasku menu, lub do przechwytywania zdarzeń, jeśli niektóre z nich wymagają przetworzenia przed wysłaniem do głównej części interfejsu użytkownika.

Przykład użycia przezroczystego panelu Swing JOptionPane:

// Stosowanie przezroczysty panel JOptionPane import java.awt.Dimension; importuj java.awt.Font; importuj java.awt.event.WindowEvent; importuj java.awt.event.WindowListener; importuj javax.swing.JDialog; importuj javax.swing.JFrame; importuj javax.swing.JLabel; importuj javax.swing.JOptionPane; importuj javax.swing.UIManager; klasa publiczna JOptionPaneTest rozszerza JFrame ( prywatna statyczna końcowa długa serialVersionUID = 1L; publiczna statyczna końcowa czcionka = nowa czcionka("Verdana", Font.PLAIN, 11); publiczna statyczna void createGUI() ( ramka JFrame = nowa JFrame("Test JOptionPane "); ramka.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); ramka.addWindowListener(new WindowListener() ( public void windowActivated(zdarzenie WindowsEvent) () public void windowClosed(zdarzenie WindowsEvent) () public void windowDeactivated(zdarzenie WindowsEvent) () public void windowDeiconified(zdarzenie WindowEvent) () public void windowIconified(zdarzenie WindowsEvent) () public void windowOpened(zdarzenie WindowEvent) () public void windowClosing(zdarzenie WindowEvent) ( Opcje obiektu = ( "Tak", "Nie!" ); int rc = JOptionPane.showOptionDialog(event.getWindow(), "Zamknąć okno?", "Potwierdzenie", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, opcje, opcje); if (rc == 0) ( event.getWindow().setVisible (fałsz); System.exit(0); JLabel label = new JLabel("Użyj przezroczystego panelu przy zamykaniu okna"); ramka.getContentPane().add(label); ramka.setPreferredSize(nowy wymiar(350, 80)); ramka.pack(); ramka.setLocationRelativeTo(null); ramka.setVisible(true); ) public static void main(Args String) ( javax.swing.SwingUtilities.invokeLater(new Runnable() ( public void run() ( UIManager.put("Button.font", FONT); UIManager.put("Label.font ", CZCIONKA); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); createGUI(); ) )); ) )

Jeśli przekażesz stałą do metody setDefaultCloseOperation JFrame.EXIT_ON_CLOSE, to po zamknięciu okna aplikacja przestanie działać. W przykładzie do tej metody przekazywana jest stała JFrame.DO_NOTHING_ON_CLOSE aby nic się nie działo, gdy okno jest zamknięte. Aplikacja w przykładzie jest zamykana w metodzie za pomocą odbiornika JFrame WindowListener oknoZamykanie. W momencie zamknięcia okna wywoływana jest metoda windowClosing z parametrem zdarzenia WindowEvent, co w przezroczystym Swing JOptionPane otwiera okno dialogowe potwierdzenia.

Poniższy zrzut ekranu przedstawia dwa okna aplikacji. Górne okno główne. Po zamknięciu tego okna otworzy się okno dialogowe z potwierdzeniem niższej intencji.

Pasek menu JMenuBar

Jedną z ważnych cech korzystania z JRootPane w Swingu jest konieczność umieszczenia paska menu w oknie JMenuBar. Nie można zbudować poważnej aplikacji bez menu umożliwiającego dostęp do funkcji programu. Biblioteka Swing zapewnia doskonałe możliwości tworzenia przyjaznych dla użytkownika menu JMenuBar, które są również lekkimi komponentami.

Pasek menu JMenuBar jest umieszczony w wielowarstwowym panelu w specjalnej warstwie FRAME_CONTENT_LAYER i zajmuje niewielką przestrzeń w górnej części okna. Długość paska menu jest równa rozmiarowi okna. Szerokość paska menu zależy od zawartych w nim komponentów.

Panel główny zapewnia panel treści i pasek menu JMenuBar nie pokrywały się. Jeśli pasek menu nie jest wymagany, panel główny wykorzystuje całą przestrzeń, aby pomieścić panel treści.

Przykłady swingu

Można pobrać kody źródłowe przykładów omówionych w tekście strony.

W tym krótkim artykule chcę opisać proces tworzenia małego programu obsługującego GUI w tym języku Jawa. Zakłada się, że czytelnik zna podstawy języka Jawa.

Jakich narzędzi potrzebujemy:

  • Wirtualna maszyna Java (OpenJDK lub Oracle JDK)
  • Intellij IDEA (lub inne IDE Java)

Po instalacji niezbędne oprogramowanie, otwarty Intellij IDEA i twórz nowy projekt: Plik -> Nowy projekt…

Nazwałem projekt guiBase. Jak widać na zrzucie ekranu, folder źródło nie zawiera niczego, dlatego tworzymy w niej naszą główną klasę zawierającą tę funkcję główny.

Klasa publiczna Main ( public static void main(String args) ( System.out.println("Witam, Govzalla!"); ) )

Możesz zobaczyć zawartość głównej klasy powyżej. Możemy teraz stworzyć projekt ( Zbuduj projekt ) i uruchom go ( Uruchomić ). W twoim terminalu IDE zobaczysz wiadomość „Witam, Govzallo!”. Ale jak sam zrozumiałeś, nie obsługuje GUI.

Na tym etapie mamy już działający program, ale bez obsługi GUI. A teraz w tym samym folderze źródło stwórzmy Formularz graficzny: Nowy -> Formularz GUI

Otwórz utworzony formularz GUI, kliknij JPanel i ustaw w polu jego identyfikator Nazwa pola, Zapytałam płyta.

Następnie przeciągnij go na formularz po prawej stronie Pole JText, Pole hasła J I JPrzycisk:

Pozostaje tylko dodać kod i powiązać z nim nasz formularz. Kiedy dodaliśmy formularz Główne okno, klasa została utworzona automatycznie Główne okno, ta klasa jest klasą utworzonego formularza, tj. Ta klasa będzie obsługiwać wszystkie zdarzenia tej formy.

Chociaż nasza klasa okna zawiera niezbędne elementy, nawet teraz nie ma to nic wspólnego z GUI, więc rozszerzmy ją o JFrama i odziedziczyć całą podstawową i niezbędną funkcjonalność GUI .

Aktualnie mamy formularz Główne okno i klasa Główne okno przedłużony z JFrama. Teraz musimy zdefiniować wszystkie dodane elementy GUI jako zawartość klasy Główne okno this.getContentPane().add(panel); Po czym zawartość pliku MainWindow.java zostanie zmieniona w następujący sposób:

Importuj javax.swing.*; klasa publiczna MainWindow rozszerza JFrame ( prywatne JTextField pole tekstowe1; prywatne JPasswordField hasłoField1; prywatny przycisk JButton1; prywatny panel JPanel; publiczny MainWindow() ( this.getContentPane().add(panel); ) )

Jeśli spróbujesz uruchomić kod, ponownie zobaczysz ten sam komunikat „Witaj, Govzalla!”. Faktem jest, że stworzyliśmy dla niej klasę i formularz, ale nie stworzyliśmy instancji tej klasy.

Czas zmienić plik Main.java i dodać tam kod tworzący nasze GUI:

Importuj plik java.awt.*; public class Main ( public static void main(String args) ( // Utwórz instancję klasy MainWindow MainWindow mainWindow = new MainWindow(); // Spakuj wszystkie elementy z naszego formularza mainWindow.pack(); // Zmień rozmiar okna mainWindow.setSize( new Dimension(200, 200)); // Wyświetl utworzone okno mainWindow.setVisible(true) )

Uruchamianie kodu

Klikając przycisk Przycisk, zauważysz, że program w ogóle nie odpowiada. Rzecz w tym, że nie dodaliśmy jeszcze słuchacza ( Słuchacz) na wydarzenia ( Wydarzenia) przycisk Przycisk.

Detektor zdarzeń ( Słuchacz zdarzeń) JPrzycisk musi to być adapter do implantacji Słuchacz akcji, więc dodajmy następujący kod do treści klasy Główne okno:

Klasa prywatna MyButtonListener implementuje ActionListener ( @Override public void actionPerformed(ActionEvent actionEvent) ( ) )

metoda Przedsięwzięcie wykonane() przetworzy wszystkie zdarzenia przycisku 1, ale najpierw musisz powiedzieć przyciskowi 1, jaką klasę będzie przetwarzał, więc dodaj następujący kod do konstruktora klasy MainWIndow: this.button1.addActionListener(new MyButtonListener()); Aby zapobiec bezsensowności naszego modułu obsługi, dodaj do metody następujący kod Przedsięwzięcie wykonane():

@Override public void actionPerformed(ActionEvent actionEvent) ( if (textField1.getText().equals(passwordField1.getText())) ( JOptionPane.showMessageDialog(null, "Success"); ) else ( JOptionPane.showMessageDialog(null, "Niepowodzenie" „ ”);

Teraz program będzie poprawnie reagował na zdarzenia, ale oczywiście nie na wszystkie zdarzenia. Na przykład, jeśli spróbujesz wyłączyć program, klikając krzyżyk, okno zniknie, ale program będzie nadal działał, ponieważ Nie dodano obsługi zdarzeń okna głównego.

Opis prezentacji Tworzenie interfejsu graficznego w bibliotekach graficznych Java dla slajdów

Biblioteki graficzne Java Java zawiera następujące pakiety do tworzenia interfejsów graficznych: Abstract Windows Toolkit (AWT) - dostarczany z JDK, każdy komponent AWT ma swój własny komponent wizualny (peer) dla konkretnego systemu operacyjnego, przenośność zapewnia pakiet Java. och. rówieśnik; ograniczony zestaw elementów graficznych; Wygląd zależy od systemu operacyjnego. Standard Widget Toolkit (SWT) - dostarczany osobno dla konkretnych systemów operacyjnych, zawarty w środowisku Eclipce, współdziała z systemem operacyjnym za pomocą interfejsów równorzędnych, w przeciwieństwie do AWT, zakres komponentów został rozszerzony. Swing – dostarczany z JDK, rozszerza klasy AWT, nie zależy od komponentów równorzędnego systemu operacyjnego. Java 3 D – grafika trójwymiarowa.

Ciężkie i lekkie komponenty Ciężkie komponenty – Renderowane przez system operacyjny – Większość komponentów AWT Lekkie komponenty – Renderowane przez kod Java – Wszystkie komponenty Swing, z wyjątkiem okien najwyższego poziomu (okna aplikacji) Ciężkie komponenty są zawsze rysowane na lekkich

Architektura Model-Widok-Kontroler (MVC) Wzorzec projektowy MVC obejmuje rozdzielenie danych aplikacji, interfejsu użytkownika i logiki sterującej na trzy oddzielne komponenty — model, widok i kontroler — dzięki czemu każdy komponent można modyfikować niezależnie. Model przechowuje dane komponentu i ułatwia zmianę lub pobieranie tych danych bez konieczności uzyskiwania dostępu do samego komponentu. Widok wyświetla dane na ekranie w celu zaprezentowania ich użytkownikowi. Kontroler określa, jak widok i dane modelu powinny reagować w odpowiedzi na dane wprowadzone przez użytkownika.

Zalety MVC Do jednego modelu można dołączyć wiele widoków bez wpływu na implementację modelu. Na przykład niektóre dane mogą być prezentowane jednocześnie w postaci arkusza kalkulacyjnego, histogramu i wykresu kołowego. Bez wpływu na realizację widoków możesz zmieniać reakcje na działania użytkownika (kliknięcie przycisku, wprowadzenie danych); w tym celu wystarczy użyć innego kontrolera. Wielu programistów specjalizuje się tylko w jednym z obszarów: albo w tworzeniu interfejsu graficznego, albo w tworzeniu logiki biznesowej. Można zatem zapewnić, że programiści tworzący logikę biznesową (model) nie będą w ogóle świadomi, jaka reprezentacja zostanie wykorzystana.

Interakcje pomiędzy modelem, widokiem i kontrolerem Model klasyczny Ścisłe połączenie pomiędzy kontrolerem i modelem oraz kontrolerem i widokiem. Widok jest powiązany z pojedynczym kontrolerem, a każdy kontroler z jednym widokiem. Widok i kontroler mają bezpośrednie połączenie z modelem.

MVC Przykładowy model klasy publicznej ( private int int. Array = (1, 2, 3, 4, 5); public String get. String. Array() ( return "int. Array=" + Arrays. to. String(int. Array); ) public void set Int. Array(int indeks, int wartość) ( \ this. int. Array = wartość; ) ) kontroler klasy publicznej ( Model modelu = nowy Model (); Zobacz widok= nowy widok(); Kontroler() ( aktualizacja. Widok(); ) zestaw pusty. Szyk. Wartość(indeks, int wartość) ( model. set. Int. Array(indeks, wartość); update. View(); ) void update. View() ( view. show. Array(model. get. String. Array()); ) ) public class View ( public void show. Array(String array. String)( System. out. println("View"); System. out. println(tablica. String); Użytkownik klasy publicznej (public statc void main(String argumentów) Kontroler kontrolera= nowy kontroler(); kontroler. ustawić. Szyk. Wartość(1, 4); ) )

Model Swing upraszcza implementację. Model nie wie, z którym proxy interfejsu użytkownika współpracuje i który komponent go używa. Ustawia wygląd i zachowanie wszystkich komponentów biblioteki. Jest powiązany z modelem tylko poprzez klasę komponentu. Kontroler widoku przetwarza zdarzenia użytkownika i rysuje komponenty na ekranie. Przyciski, listy, tabele, pola tekstowe...

Elementy interfejsu Przycisk - przycisk; JSprawdź. Pole — przycisk pola wyboru; JCombo. Pole – lista rozwijana; JLabel - etykieta, napis; JList - lista; JHasło. Pole — pole tekstowe dla ukrytych danych wejściowych; JProgress. Pasek - komponent służący do wyświetlania liczby w określonym zakresie; JRadio. Przycisk — przyciski opcji, zwykle używane ze składnikiem Button. Grupa; JSlider – komponent pozwalający na wybranie wartości z zadanego zakresu; JTable - tabela; JTekst. Pole - jednowierszowe pole tekstowe; JTekst. Obszar - wielowierszowe pole tekstowe; JDrzewo - drzewo.

Kontenery interfejsu Części interfejsu użytkownika zawierające inne komponenty Kontenery najwyższego poziomu: Frame, JFrame - okno aplikacji; JDialog - okno dialogowe aplikacji; JKolor. Chooser - okno dialogowe wyboru koloru; JFile. Chooser - okno dialogowe wyboru plików i katalogów; Plik. Okno dialogowe - okno dialogowe wyboru plików i katalogów (komponent awt). Proste kontenery: JPanel - prosty panel do grupowania elementów, w tym paneli zagnieżdżonych; JTool. Pasek - pasek narzędzi (zazwyczaj przyciski); JPrzewiń. Panel - panel przewijania umożliwiający przewijanie zawartości elementu podrzędnego; JDesktop. Pane to kontener do tworzenia wirtualnego pulpitu lub aplikacji w oparciu o MDI (interfejs wielu dokumentów); JRedaktor. Panel, JText. Pane - kontenery do wyświetlania złożonego dokumentu w formacie HTML lub RTF; JTab. Panel - kontener do zarządzania zakładkami;

Tworzenie okna importu Java. och. *; klasa też. Prosty. Ramka rozciąga się Frame( public statc void main(String args)( Frame fr = new Too. Simple. Frame(); fr. set. Size(400, 150); // rozmiar okna fr. set. Visible(true); // / renderowanie okna ) // przycisk zamykania nie działa ) Swing

Okno z niestandardową ikoną importu javax. huśtać się. *; Rama klasy publicznej. Zamknięcie rozszerza JFrame ( public Frame. Closing() ( super("Window Title"); // operacja przy zamykaniu zestawu okna. Default. Close. Operaton(EXIT_ON_CLOSE); // przy zamykaniu okna - wyjście // ikona dla zestaw okien. Ikona. Obraz(get. Toolkit(). get. Image("ikona. gif")); / ikony / ikona. png // zestaw wyświetlania (300, 100); set. Visible(true); // wizualizacja okna ) public statc void main(String args) ( nowa ramka. Zamknięcie(); ) ) Swing

Standardowe okna dialogowe Typ okna dialogowego Opis NFORMATION_MESSAGE Okno dialogowe wyświetla informacje ogólne za pomocą ikony takiej jak ta WARNING_MESSAGE Okno dialogowe wyświetla informacje ostrzegawcze za pomocą ikony takiej jak ta QUESTION_MESSAGE Okno dialogowe pytań do wprowadzania informacji ERROR_MESSAGE Okno dialogowe wyświetla informacje o błędach za pomocą ikony takiej jak ta PLAIN_MESSAGE Wskazuje, że okno dialogowe nie jest jednym z powyższych typów. Wyświetlane na ekranie bez standardowej ikony. Okna dialogowe mogą być modalne lub niemodalne Okna dialogowe mogą być modalne (koncentrować się na oknie do momentu naciśnięcia przycisku) lub niemodalne

Okna wejściowe i komunikaty importują Java. och. *; importuj javax. huśtać się. *; public class Soluton ( public static void main(Args String) ( JOpton. Pane. show. Message. Dialog(null , "Hello, World"); String s = JOpton. Pane. show. Wejście. Dialog("Wpisz swoje imię i nazwisko" ) ) Huśtać się

Standardowe linki Java 1. Linker graniczny. Układ (umieszczenie biegunowe). 2. Kompozytor przepływu. Układ (umieszczenie sekwencyjne). 3. Linker. Siatka. Układ (układ tabeli). 4. Łącznik wiosenny. Układ (rozmieszczenie względne). 5. Kompozytor pudełek. Układ (umieszczenie bloku).

Układ biegunowy (Border. Layout Composer) Wartość obramowania. Układ. PÓŁNOC lub ciąg „Północ” - element znajduje się wzdłuż górnej (północnej) krawędzi okna i rozciąga się na całej jego szerokości. Zwykle w ten sposób umieszczony jest pasek narzędzi. Znaczenie granicy. Układ. POŁUDNIE lub ciąg „Południe” - komponent znajduje się wzdłuż dolnej (południowej) granicy i rozciąga się na całą szerokość okna. Ta pozycja jest idealna dla paska stanu. Znaczenie granicy. Układ. ZACHÓD lub ciąg „Zachód” - element znajduje się wzdłuż lewej (zachodniej) granicy okna i rozciąga się na całą jego wysokość, przy czym uwzględniane są wymiary elementów północnego i południowego (mają one pierwszeństwo). Znaczenie granicy. Układ. WSCHÓD lub ciąg „Wschód” - komponent znajduje się wzdłuż prawej (wschodniej) krawędzi okna. Poza tym jego układ jest podobny do elementu zachodniego. Znaczenie granicy. Układ. CENTRUM lub napis „Centrum” - komponent umieszczany jest na środku okna, zajmując jak najwięcej miejsca.

Przykład użycia kompozytora Border. Import układu javax. huśtać się. *; importuj Javę. och. *; Granica klasy publicznej. Układ. Przykład rozszerza JFrame (public Border. Layout. Sample() ( super("Border. Layout. Sample"); set. Size(400, 300); set. Default. Close. Operaton(EXIT_ON_CLOSE); // pobierz zawartość klasy panel JFrame Container c = get. Content. Pane(); // Domyślnie Swing używa menedżera układu Border. // dodaje komponenty do panelu za pomocą stałych łańcuchowych c add(new JButton("Północ"), "Północ" ); c. add(new JButton("South"), "South"); // lub stałe z klasy Border. Layout // Element JLabel do wyświetlania tekstu c. add(new JLabel("West"), Border. Layout. WEST) ; c. add(new JLabel("East"), Border. Layout. EAST); // jeśli w ogóle nie określisz parametru, komponent zostanie automatycznie dodany do centrum c JButton("Centrum")); do ustawienia ekranu Widoczne(true); publiczna statystyka void main(String args) (nowe obramowanie. Układ. Próbka(); ) ) Swing

Układ sekwencyjny (układ układu przepływu) Układ rozkłada komponenty od lewej do prawej, od góry do dołu (domyślnie w Jpanels). importuj javax. huśtać się. *; importuj Javę. och. *; Przepływ klasy publicznej. Układ. Przykład rozszerza JFrame (public Flow. Layout. Sample() ( super("Flow. Layout 1"); set. Size(400, 200); set. Default. Close. Operaton(EXIT_ON_CLOSE); // pobierz panel treści Kontener c = get. Content. Pane(); // ustaw komponenty, które mają być wyrównane w środku c. Layout(Flow. Layout. CENTER)); c. add(new JButton("Dwa" )); // wyświetl zestaw argumentów okna. String (nowy przepływ. Układ. Przykład(); ) ) import java. och. *; importuj javax. huśtać się. *; klasa publiczna Soluton ( public static void main(String args) ( JOpton. Pane. show. Message. Dialog(null , "Hello, World"); ) ) Swing

Układ tabelaryczny (Układ siatki. Układ) wszystkie komponenty mają ten sam rozmiar. Dostępna przestrzeń jest podzielona na równą liczbę komórek, z których każda zawiera komponent; wszystkie komponenty są zawsze wyświetlane na ekranie, niezależnie od tego, jak duża lub mała jest dostępna przestrzeń. importuj Javę. och. *; importuj javax. huśtać się. *; importuj Javę. utl. *; klasaSiatka. Test rozszerza JFrame ( Grid. Test(String s)( super(s); Kontener c = get. Content. Pane(); // 4 wiersze 4 kolumny odległość między wierszami i kolumnami w pikselach c. set. Layout(new Grid. Układ(4, 4, 5, 5)); String. Tokenizer st = nowy String. Tokenizer("7 8 9 / 4 5 6 * 1 2 3 - 0. = +"); nowy przycisk(st. następny. Token())); zestaw widoczny(true); Test("Siatka. Menedżer układu");

Ułożenie tabelaryczne nada przyciskom ten sam rozmiar, a ułożenie sekwencyjne zapobiegnie ich „rozmyciu” i jednocześnie wyrówna je do prawej krawędzi, którą importuję java. och. *; importuj javax. huśtać się. *; Polecenie klasy publicznej. Przyciski rozszerza JFrame ( Polecenie publiczne. Przyciski() ( super("Polecenie. Przyciski"); set. Rozmiar (350, 250); set. Locaton (150, 100); set. Domyślne. Zamknij. Operaton (EXIT_ON_CLOSE); / / utwórz panel z układem tabeli, aby wyrównać rozmiary przycisków JPanel grid = new JPanel(new Grid. Layout(1, 2, 5, 0)); // 1 rząd, 2 kolumny, 5 px w poziomie, 0 w pionie . // dodaj siatkę komponentów (new JButton("OK")) add(new JButton("Anuluj")); // umieść wynikowy element w kolejnej pozycji, wyrównanej do prawego przepływu JPanel = nowy JPanel( new Flow. Layout(Flow. Layout. PRAWY)); // pobierz panel treści Kontener c = get. SOUTH); // wyświetl zestaw okien statc void main(String args) (nowe polecenie. Przyciski(); ) ) Huśtaj się

Układ bloków (Box. Układ układu) Menedżer układu bloków układa komponenty w kontenerze w blokach: kolumnę (wzdłuż osi Y) lub pasek (wzdłuż osi X), a każdy pojedynczy komponent można wyśrodkować, w lewo lub po prawej stronie, a także u góry lub u dołu.

Przykładowy układ blokowy importuj Java. och. *; importuj javax. huśtać się. *; klasa publiczna Box 1 rozszerza JFrame ( public Box 1() ( super("Box 1 - Y"); set. Size(400, 200); set. Default. Close. Operaton(EXIT_ON_CLOSE); // pobierz panel zawartości Kontener c = pobierz zawartość. Pane(); // ustaw układ osi Y Boxy = nowy układ. c. add(new JButton("Jeden") JButton("Three")); (true); klasa statyczna Box 2 rozszerza JFrame (public Box 2() ( super("Box 2 - X"); // ustawia rozmiar i położenie zestawu okien. Size(400 , 200); set. Locaton (100, 100); set. Default. Zamknij Operaton (EXIT_ON_CLOSE); // pobierz panel zawartości Kontener. (c, Box. Układ. X_AXIS); c. add("Jeden"); .add(nowy JButton("Trzy") // wyświetl zestaw okien. Widoczne (prawda); ) ) public statc void main(String args) ( new Box 1(); new Box 2(); ) ) Swing 5 W tym przykładzie tworzone są dwa okna. Jeden z nich realizuje układ blokowy wzdłuż osi Y, drugi realizuje układ blokowy wzdłuż osi X.

Dawidow Anton Waleriewicz
Student TSU, Rosja, Togliatti
Doradca naukowy: Erofeeva E.A.

Interfejs użytkownika w Javie przeszedł bardzo ciernistą ścieżkę powstawania i rozwoju. Od dawna oskarżano go o chciwość zasobów systemowych, niską wydajność i ograniczoną funkcjonalność. Pojawienie się platformy .NET z szybszymi komponentami graficznymi jeszcze bardziej osłabiło pozycję Java. Ale taka konkurencja tylko pobudziła Programiści Java do rozwoju i udoskonalania bibliotek graficznych. W tym artykule zobaczymy, co z tego wynikło.

Zestaw narzędzi do abstrakcyjnego okna

Zestaw narzędzi Abstract Window Toolkit (w skrócie AWT) został po raz pierwszy wydany w 1995 roku przez firmę Sun Microsystems. Była to pierwsza próba stworzenia GUI dla Javy. AWT pełnił rolę warstwy wywołującej metody z bibliotek napisanych w C. A te z kolei wykorzystywały komponenty graficzne systemu operacyjnego. Z jednej strony tak zbudowany program był zewnętrznie podobny do wszystkich innych programów w używanym systemie operacyjnym, ale z drugiej strony ten sam program może wyglądać zupełnie inaczej na różnych systemach operacyjnych, co komplikuje rozwój. Ponadto ze względu na wieloplatformowość konieczne było ujednolicenie interfejsów wywoływania komponentów, co doprowadziło do nieco ograniczonej funkcjonalności. Zestaw komponentów jest również dość skromny. Na przykład nie ma tabel i ikon nie można umieszczać w przyciskach. AWT próbuje automatycznie zwolnić używane zasoby. Wpływa to na wydajność i zwiększa złożoność architektury. AWT jest łatwy do nauczenia, ale napisanie czegoś złożonego stanowi wyzwanie. Obecnie AWT jest używany głównie do apletów. Oracle zachęca obecnie programistów do przejścia na platformę Swing, ponieważ jest ona bezpieczniejsza.

Rys. 1 – Przykładowy program napisany przy użyciu AWT w środowisku Windows

Po AWT Sun wypuścił Swing w 1998 roku. Jest napisany w całości w Javie i wykorzystuje do renderowania 2D. Swing ma znacznie więcej różnych komponentów niż AWT. Tworzenie samych komponentów stało się znacznie łatwiejsze dzięki dziedziczeniu ich z istniejących. Wprowadzono także możliwość korzystania z różnych stylów i skórek. Jednak prędkość wczesnych wersji Swinga była dość niska, a błędy w pisaniu programu mogły nawet doprowadzić do zawieszenia systemu operacyjnego.

Jednak ze względu na łatwość nauki i obszerną dokumentację Swing stał się najpopularniejszym GUI w Javie. Powstało wiele rozszerzeń, takich jak SwingX i JGoodies, które jeszcze bardziej ułatwiają tworzenie złożonych wizualnie aplikacji. Wszystkie nowoczesne środowiska programistyczne Java obejmują edytor graficzny Huśtać się. Mimo że obecnie dostępnych jest więcej nowoczesnych frameworków, najpopularniejszym pozostaje Swing.


Rys.2 – Przykładowy program napisany w Swingu

Standardowy zestaw narzędzi do widgetów

SWT został wydany przez IBM w czasie, gdy Swing był jeszcze powolny, a głównie w celu promowania środowiska programistycznego Eclipse. Podobnie jak AWT, SWT wykorzystuje komponenty systemu operacyjnego, ale dla różnych platform używane są różne interfejsy interoperacyjności. Dlatego dla każdego systemu operacyjnego należy dostarczyć osobną bibliotekę JAR. Pozwala to na pełniejsze wykorzystanie funkcji odpowiednich dla różnych systemów operacyjnych. Brakujące komponenty zostały zrealizowane przy użyciu modelu 2D. Jednak SWT okazał się trudniejszy do opanowania niż Swing. Dodatkowo programista musi sam zaimplementować udostępnienie zasobów przez aplikację.

Rys.3 – Przykładowy program napisany w Swingu

JavaFX został wydany w 2008 roku przez firmę Oracle. Jest pozycjonowana jako platforma do tworzenia bogatych aplikacji internetowych. Do renderowania wykorzystywany jest potok graficzny, co znacznie przyspiesza działanie aplikacji. Istnieje duży zestaw wbudowanych komponentów. Istnieją również oddzielne komponenty do kreślenia. Zaimplementowano obsługę treści multimedialnych, animacji, a nawet wielu dotknięć. Wygląd komponentów jest dostosowywany za pomocą stylów CSS. Dodatkowo zestaw narzędzi JavaFX zawiera możliwość stworzenia natywnego instalatora dla najpopularniejszych platform: exe lub msi dla Windows, deb lub RPM dla Linuksa, dmg dla Mac. Szczegółowa dokumentacja znajduje się na stronie internetowej Oracle i duża liczba gotowe przykłady.

Zatem po opisaniu głównych cech i wad powyższych graficznych interfejsów użytkownika możemy zdecydować, do jakich zadań lepiej się nadają. Zestaw narzędzi Abstract Window jest bardziej odpowiedni do tworzenia apletów. Początkującym możemy polecić Swinga ze względu na to, że w Internecie można znaleźć ogromną ilość dokumentacji do niego, także w języku rosyjskim. JavaFX doskonale nadaje się do tworzenia bogatych aplikacji internetowych.

Lista wykorzystanych źródeł

    Ryzhenko A. V. Programowanie obiektowe: Kompleks edukacyjno-metodyczny w dyscyplinie dla specjalności 010501 - „Matematyka stosowana i informatyka”. – 2007.

    Khabibullin I. Sh. Java 7 (wyd. 4). – BHV-Petersburg, 2012.

    Clarke J., Connors J., Bruno E. J. JavaFX: Tworzenie bogatych aplikacji internetowych. – Edukacja Pearsona, 2009.

    Northover S., Wilson M. Swt: standardowy zestaw narzędzi do widgetów, tom 1. – Addison Wesley Professional, 2004.

Interfejs użytkownika w Javie przeszedł bardzo ciernistą ścieżkę powstawania i rozwoju. Przez długi czas zarzucano mu powolną pracę, zachłanność zasobów systemowych i ograniczoną funkcjonalność. Pojawienie się platformy .NET z szybszymi komponentami graficznymi jeszcze bardziej osłabiło pozycję Java. Ale każda chmura ma dobre strony - cały ten ruch tylko zachęcił programistów Java do rozwijania i ulepszania bibliotek graficznych. Zobaczmy, co z tego wyniknie.

Zestaw narzędzi do abstrakcyjnego okna

AWT było pierwszą próbą firmy Sun dotyczącą stworzenia GUI dla języka Java. Wybrali łatwą drogę i po prostu stworzyli warstwę Java, która wywołuje metody z bibliotek napisanych w C. Metody biblioteczne tworzą i wykorzystują graficzne komponenty środowiska operacyjnego. Z jednej strony jest to dobre, ponieważ program Java jest podobny do innych programów w tym systemie operacyjnym. Ale z drugiej strony nie ma gwarancji, że różnice w rozmiarach komponentów i czcionkach nie zepsują wyglądu programu podczas uruchamiania go na innej platformie. Dodatkowo, aby zapewnić wieloplatformową funkcjonalność, konieczne było ujednolicenie interfejsów wywołujących komponenty, dlatego ich funkcjonalność została nieco zmniejszona. A zestaw komponentów okazał się dość mały. Na przykład AWT nie ma tabel, a przyciski nie obsługują wyświetlania ikon.

AWT próbuje automatycznie zwolnić używane zasoby. Zwiększa to nieco złożoność architektury i wpływa na wydajność. AWT jest dość łatwy do nauczenia, ale napisanie czegoś złożonego będzie nieco trudne. Obecnie jest używany tylko w przypadku apletów.

Zalety:

  • część JDK;
  • szybkość pracy;
  • elementy graficzne są podobne do standardowych.

Wady:

  • zastosowanie komponentów natywnych nakłada ograniczenia na wykorzystanie ich właściwości. Niektóre komponenty mogą w ogóle nie działać na platformach nienatywnych;
  • niektóre właściwości, takie jak ikony i podpowiedzi, są całkowicie nieobecne w AWT;
  • Istnieje bardzo niewiele standardowych komponentów AWT; programista musi zaimplementować wiele niestandardowych;
  • program wygląda inaczej różne platformy(może być krzywy).

wniosek:

Obecnie AWT jest używany niezwykle rzadko - głównie w starych projektach i apletach. Oracle ma ukryte tutoriale i zachęca do przejścia na Swing na wszelkie możliwe sposoby. Jest to zrozumiałe; bezpośredni dostęp do komponentów osi może stać się poważną luką w zabezpieczeniach.

Huśtać się


Po AWT firma Sun opracowała zestaw komponentów graficznych o nazwie Swing. Komponenty Swing są w całości napisane w Javie. Do renderowania wykorzystuje się technologię 2D, co niesie ze sobą kilka korzyści. Zestaw standardowych komponentów znacznie przewyższa AWT pod względem różnorodności i funkcjonalności. Tworzenie nowych komponentów, dziedziczenie z istniejących i rysowanie, czego dusza zapragnie, stało się łatwe. Możliwe stało się wsparcie dla różnych stylów i skórek. Jednak szybkość pierwszych wersji Swinga pozostawiała wiele do życzenia. Nieprawidłowo napisany program może całkowicie zawiesić system Windows.

Jednak dzięki łatwości obsługi, bogatej dokumentacji i elastycznym komponentom Swing stał się prawdopodobnie najpopularniejszym frameworkiem graficznym w Javie. Na jego podstawie pojawiło się wiele rozszerzeń, takich jak SwingX, JGoodies, które znacznie upraszczają tworzenie skomplikowanych interfejsów użytkownika. Prawie wszystkie popularne środowiska programowania Java zawierają edytory graficzne dla formularzy Swing. Dlatego zrozumienie i rozpoczęcie korzystania ze Swinga nie będzie trudne.

Zalety:

  • część JDK, nie ma potrzeby instalowania dodatkowych bibliotek;
  • na forach jest o wiele więcej książek o Swingu i odpowiedzi. Wszystkie problemy, zwłaszcza dla początkujących, są doskonale znane Google;
  • wbudowany edytor formularzy w prawie wszystkich środowiskach programistycznych;
  • istnieje wiele rozszerzeń opartych na swingu, takich jak SwingX;
  • wsparcie dla różnych stylów (Wygląd i styl).

Wady:

  • okno z wieloma komponentami zaczyna zwalniać;
  • Praca z menedżerami układu może być koszmarem w przypadku złożonych interfejsów.

Wniosek:

Swing żył, Swing żyje, Swing będzie żył. Chociaż Oracle stara się promować JavaFX, Swing pozostaje obecnie najpopularniejszym frameworkiem do tworzenia interfejsów użytkownika w Javie.

Standardowy zestaw narzędzi do widgetów


Jak
wygląda
SWT

SWT został opracowany przez IBM w czasie, gdy Swing był jeszcze powolny i powstał głównie w celu promowania środowiska programistycznego Eclipse. SWT, podobnie jak AWT, wykorzystuje komponenty systemu operacyjnego, ale ma własne interfejsy interakcji dla każdej platformy. Więc dla każdego nowy system będziesz musiał dostarczyć osobną bibliotekę JAR z odpowiednią wersją SWT. Umożliwiło to pełniejsze wykorzystanie istniejącej funkcjonalności komponentów na każdej osi. Brakujące funkcje i komponenty zostały zaimplementowane przy użyciu 2D, podobnie jak w Swingu. SWT ma wielu zwolenników, ale z ręką na sercu nie można nie zgodzić się, że nie wszystko okazało się tak proste, jak byśmy chcieli. Początkujący będzie musiał spędzić znacznie więcej czasu na nauce SWT niż na zapoznawaniu się ze Swingiem. Dodatkowo SWT nakłada na programistę zadanie uwolnienia zasobów i dlatego przy pisaniu kodu musi zachować szczególną ostrożność, aby przypadkowy wyjątek nie doprowadził do wycieków pamięci.

Zalety:

  • wykorzystuje komponenty systemu operacyjnego - większa prędkość;
  • Eclipse zapewnia edytor wizualny formularze;
  • obszerna dokumentacja i wiele przykładów;
  • Istnieje możliwość zastosowania komponentów AWT i Swing.

Wady:

  • dla każdej platformy należy dostarczyć osobną bibliotekę;
  • musisz stale monitorować wykorzystanie zasobów i uwalniać je w odpowiednim czasie;
  • złożona architektura, która po daremnych próbach wdrożenia niestandardowego interfejsu wywołuje myśli samobójcze.

Wniosek:

Oczywiste jest, że IBM próbował. Okazało się jednak, że było to bardzo amatorskie...

JavaFX


JavaFX można bez przesady nazwać przełomem. Do renderowania wykorzystywany jest potok graficzny, co znacznie przyspiesza działanie aplikacji. Zestaw wbudowanych komponentów jest obszerny, istnieją nawet osobne komponenty do rysowania wykresów. Zaimplementowano obsługę treści multimedialnych, wielu efektów wyświetlania, animacji, a nawet wielodotyku. Wygląd wszystkich komponentów można łatwo zmienić za pomocą stylów CSS. A najlepsze jest to, że JavaFX zawiera zestaw narzędzi, które pozwalają stworzyć natywny instalator dla najpopularniejszych platform: exe lub msi dla Windows, deb lub RPM dla Linuksa, dmg dla Mac. Szczegółową dokumentację i ogromną liczbę gotowych przykładów znajdziesz na stronie Oracle. Dzięki temu programowanie w JavaFX jest łatwe i przyjemne.

Zalety:

  • szybka praca dzięki potokowi graficznemu;
  • wiele różnych komponentów;
  • wsparcie stylu;
  • narzędzia do tworzenia instalatora programu;
  • Aplikację można uruchomić jako aplikację desktopową oraz w przeglądarce jako część strony.

Wady:

  • framework jest wciąż rozwijany, więc zdarzają się awarie i pewne usterki;
  • JavaFX nie jest jeszcze powszechnie stosowany.

Wniosek:

Dobra robota, Orliku. Ramy pozostawiają same pozytywne wrażenia. Nie jest to trudne do zrozumienia; metody i interfejsy wyglądają logicznie. Chcę go używać jeszcze raz!

Biblioteki wizualne w praktyce

SWT: widget pogody

Aby zademonstrować możliwości najpopularniejszych bibliotek graficznych i podstawowe zasady pracy z nimi, stworzymy kilka małych widżetów wyświetlających różne informacje.

A zacznijmy od chyba najpopularniejszego widgetu – wyświetlającego aktualną pogodę, do realizacji którego wybierzemy SWT.

Każdy program SWT rozpoczyna się od utworzenia obiektu wyświetlanego. Służy jako rodzaj kontekstu aplikacji, który zawiera niezbędne metody dostępu do zasobów systemowych i zapewnia pętlę zdarzeń. Następnym krokiem jest utworzenie równie ważnego obiektu Shell. Shell to zwykłe okno systemu operacyjnego. Wyświetlacz jest przekazywany do konstruktora powłoki w celu utworzenia okna najwyższego poziomu.

Wyświetl wyświetlacz = nowy wyświetlacz(); powłoka = nowa powłoka (wyświetlanie, SWT.NO_TRIM);

Ponieważ tworzymy widget, nie musimy wyświetlać standardowej ramki okna i przycisków sterujących; w tym celu określiliśmy flagę NO_TRIM. Jako tło użyjemy obrazu - prostokąta z zaokrąglonymi narożnikami. W zasadzie okno SWT może przybrać dowolną formę. Aby osiągnąć taki efekt wykorzystujemy klasę Region. Wystarczy dodać do tej klasy wszystkie widoczne punkty z obrazka tła, pomijając te przezroczyste.

Przesyłanie obrazu:

Obraz obrazu = nowy obraz (display, „images/bg.png#26759185”);

W obrazach o różnych formatach przezroczystość jest ustawiana inaczej, dlatego informacje o obszarach przezroczystych również nie są pobierane w ten sam sposób. Utwórz obszar tła i dodaj tam wszystkie widoczne punkty:

Region region = nowy Region(); ImageData imageData = image.getImageData(); if (imageData.alphaData != null) ( Piksel prostokąta = nowy prostokąt(0, 0, 1, 1); for (int y = 0; y< imageData.height; y++) { for (int x = 0; x < imageData.width; x++) { if (imageData.getAlpha(x, y) == 255) { pixel.x = imageData.x + x; pixel.y = imageData.y + y; region.add(pixel); } } } } else { ImageData mask = imageData.getTransparencyMask(); Rectangle pixel = new Rectangle(0, 0, 1, 1); for (int y = 0; y < mask.height; y++) { for (int x = 0; x < mask.width; x++) { if (mask.getPixel(x, y) != 0) { pixel.x = imageData.x + x; pixel.y = imageData.y + y; region.add(pixel); } } } }

Ustaw kształt okna:

Shell.setRegion(region);

Teraz musimy utworzyć detektor zdarzeń dla okna. Będziemy zainteresowani zdarzeniami rysowania okna, zdarzeniami myszy i zdarzeniami naciśnięcia klawisza, aby okno mogło być przesuwane po ekranie.

Listener Listener = new Listener() ( int startX, startY; public void handleEvent(Event e) ( if (e.type == SWT.KeyDown && e.character == SWT.ESC) ( Shell.dispose(); ) if (e.type == SWT.MouseDown && e.button == 1) ( startX = e.x; startY = e.y; ) if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0 ) ( Punkt p = Shell.toDisplay(e.x, e.y); p.x -= startX; p.y -= startY; Shell.setLocation(p); ) if (e.type == SWT.Paint) ( np. obraz, imageData.x, imageData.y);

Zatem naciśnięcie klawisza Esc spowoduje zamknięcie okna. Kiedy naciśniesz lewy przycisk myszy na obszarze okna, zapamiętaj współrzędne kliknięcia. Poruszając myszką z wciśniętym lewym klawiszem, przesuwamy okno na ekranie zgodnie z ruchem. Kiedy nastąpi zdarzenie przerysowania, rysujemy obraz tła przy użyciu kontekstu grafiki GC.

Przypiszmy słuchacza do odpowiednich zdarzeń okna:

Shell.addListener(SWT.KeyDown, słuchacz); Shell.addListener(SWT.MouseDown, słuchacz); powłoki.addListener(SWT.MouseMove, słuchacz); powłoki.addListener(SWT.Paint, słuchacz);

Ustaw rozmiar okna równy rozmiarowi obrazu:

Shell.setSize(imageData.x + imageData.width, imageData.y + imageData.height);

Otwórz okno i uruchom pętlę zdarzeń:

Powłoka.open(); while (!Shell.isDisposed ()) ( if (!display.readAndDispatch ()) display.sleep (); )

Nie zapomnij na koniec zwolnić wykorzystanych zasobów:

region.utylizacja(); image.dispose(); display.dispose();

Uruchamiając program na tym etapie otrzymamy prostokąt, który można przesuwać myszką i zamykać klawiszem Esc.

Czas dodać trochę treści. Aktualną pogodę wyświetlimy w formie ikony stanu (słońce, deszcz, śnieg...), odczyty temperatury i czas ostatniej aktualizacji.

Aby rozmieścić komponenty graficzne w oknie w we właściwej formie używane są menedżery układu. Menedżer układu zajmuje się nie tylko rozmieszczeniem komponentów, ale także zmianą ich rozmiaru w miarę zmiany rozmiaru okna. W naszym widżecie użyjemy GridLayout. Menedżer ten umieszcza komponenty w komórkach wyimaginowanej tabeli. Tworzymy GridBagLayout z dwiema kolumnami o różnych szerokościach kolumn (fałszywa flaga w konstruktorze), ustawiamy go jako menedżera układu okna:

Układ GridLayout = nowy Układ GridLayout(2, fałsz); powłoki.setLayout(układ);

W przypadku obrazu stanu używamy komponentu Label. Obiekt okna przekazujemy jako obiekt nadrzędny. Drugi parametr może zostać użyty do ustawienia stylu komponentu. Dla każdego komponentu zestaw możliwych flag stylu jest inny; można je znaleźć w dokumentacji lub bezpośrednio w kodzie źródłowym komponentu.

//rysuj obraz stanu Label imageLabel = new Label(shell, SWT.NONE); imageLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, prawda, prawda, 1, 1));

Flagi w klasie GridData oznaczają, że etykieta zostanie umieszczona w lewym górnym rogu, będzie rozciągać się w poziomie i w pionie (flagi ustawione na true), gdy będzie wolne miejsce i zajmie jeden wiersz i jedną kolumnę tabeli układu.

Nie w SWT przezroczyste tło komponentów, a za obrazem stanu będzie białe tło, którego oczywiście nie chciałbyś. Stwórzmy więc obiekt Color z kolorem tła okna:

Kolor bgColor = nowy kolor (wyświetlacz, 0x2b, 0x2b, 0x2b);

Na koniec programu obiekt ten również należy usunąć, wywołując metodę utylizacji. Ustawiamy kolor tła oraz obraz stanu, który można wczytać z pliku w taki sam sposób jak wczytywaliśmy obraz tła na początku:

ImageLabel.setBackground(bgColor); Status obrazu Obraz = nowy obraz (display, „images/1.png#26759185”); imageLabel.setImage(statusImage);

Dodajmy teraz Etykietę z aktualną temperaturą i umieśćmy ją w prawej górnej części okna:

Temperatura etykietyLabel = nowa etykieta(powłoka, SWT.NONE); temperaturaLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));

Ustawmy jakąś temperaturę:

TemperaturaLabel.setText("+1 \u2103");

Do rejestrowania temperatury w stopniach Celsjusza używany jest numer Unicode odpowiadający znakowi ze znakami serwisowymi \u.

Domyślna czcionka etykiet tekstowych jest za mała. Stwórzmy więc nowy, większy:

FontData fD = temperaturaLabel.getFont().getFontData(); fD.setHeight(30); fD.setStyle(SWT.BOLD); Czcionka newFont = nowa czcionka(display, fD); temperaturaLabel.setFont(nowaFont); Czcionka, podobnie jak inne obiekty zasobów, musi zostać zwolniona. W tym celu użyjemy detektora zdarzeń niszczenia etykiet:

TemperaturaLabel.addDisposeListener(new DisposeListener() ( public void widgetDisposed(DisposeEvent e) ( newFont.dispose(); ) ));

Na koniec dodajmy etykietę opisującą warunki pogodowe:

Opis etykietyLabel = nowa etykieta(powłoka, SWT.WRAP); opisLabel.setLayoutData(nowe GridData(SWT.FILL, SWT.CENTER, prawda, prawda, 2, 1)); opisLabel.setText("Częściowo pochmurno, słaby deszcz"); opisLabel.setBackground(bgColor); opisLabel.setForeground(display.getSystemColor(SWT.COLOR_WHITE));

Tekst może być dość długi, dlatego tworząc etykietę podajemy flagę WRAP, dzięki czemu tekst zostanie automatycznie podzielony na kilka linii w przypadku braku miejsca. Umieśćmy komponent na środku i pozwólmy mu wypełnić całą poziomą przestrzeń. Zwracamy również uwagę, że komponent zajmuje dwie kolumny tabeli układu. Uruchamiamy i pobieramy okno z obrazu „Widżet pogody”.

Teraz możesz podłączyć usługę pogodową, utworzyć timer do automatycznej aktualizacji - i widget jest gotowy.

Swing: zawsze najświeższe informacje

Napiszemy w Swingu widget wyświetlający kanały RSS. Zaczynamy, tak jak ostatnim razem, od stworzenia okna. Klasa implementująca funkcjonalność standardowego okna w Swingu nazywa się JFrame. Domyślnie zamknięcie okna aplikacji w Swingu nie powoduje zatrzymania programu, dlatego lepiej określić, jak okno powinno zachowywać się po zamknięciu:

Ramka JFrame = nowa JFrame(); ramka.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

Do prezentacji aktualności najlepiej nadaje się stół. Swing jest zbudowany na wzorcu Model-View-Controller (MVC). W architekturze MVC model dostarcza dane, widok odpowiada za wyświetlanie danych (np. tekstu, pól wejściowych), a kontroler zapewnia interakcję pomiędzy modelem a widokiem. Tabela dobrze ilustruje to podejście. Do reprezentowania danych używana jest klasa implementująca interfejs TableModel.

Aby przechowywać informacje o dostępnych aktualnościach, utwórzmy klasę FeedMessage z polami na tytuł artykułu i datę publikacji:

Klasa publiczna FeedMessage ( public String title; public Data publikacjiDate; )

Aby uprościć i przyspieszyć rozwój, nasz model danych dziedziczymy z klasy AbstractTableModel, która oferuje gotową implementację niemal wszystkich metod interfejsu TableModel.

Klasa publiczna RssFeedTableModel rozszerza AbstractTableModel ( private List wpisy = nowa lista tablic<>(); public void updateData(List wpisy) ( this.entries = wpisy; fireTableDataChanged(); ) public int getRowCount() ( return wpisy.size(); ) public int getColumnCount() ( return 2; ) public Object getValueAt(int rowIndex, int kolumnaIndex) ( przełącznik (columnIndex) ( przypadek 0: zwróć wpisy.get(rowIndex).title; przypadek 1: zwróć wpisy.get(rowIndex).publicationDate; ) return null;

Metoda fireTableDataChanged informuje widok, że model danych uległ zmianie i należy go ponownie narysować.

Tworzymy tabelę i zmieniamy nieco jej wygląd, tak aby bardziej przypominała widget. Usuwamy linie pomiędzy wierszami i kolumnami, zwiększamy wysokość wierszy i usuwamy nagłówek tabeli z nazwami kolumn:

Tabela JTable = nowy JTable(nowy RssFeedTableModel()); tabela.setShowGrid(false); table.setIntercellSpacing(nowy wymiar(0, 0)); tabela.setRowHeight(30); tabela.setTableHeader(null);

Teraz zacznijmy wygląd komórki. Swing umożliwia przypisanie oddzielnych klas widoków różne rodzaje dane. Za renderowanie poszczególnych komórek tabeli odpowiada klasa dziedzicząca interfejs TableCellRenderer. Wartość domyślna to DefaultTableCellRenderer, która jest etykietą tekstową.

Przypiszmy nasz moduł renderujący komórki do danych typu String. Zmieńmy domyślny kolor czcionki i zmieńmy kolor tła, aby poprawić czytelność.

Table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() ( Kolor nieparzystyColor = nowy kolor(0x25, 0x25, 0x25); Kolor EvenColor = nowy kolor(0x1a, 0x1a, 0x1a); Tytuł koloruKolor = nowy kolor(0x3a, 0xa2, 0xd7 ); komponent publiczny getTableCellRendererComponent(tabela JTable, wartość obiektu, wartość logiczna isSelected, wartość logiczna hasFocus, int wiersz, int kolumna) ( super.getTableCellRendererComponent(tabela, wartość, isSelected, hasFocus, wiersz, kolumna); setBackground(wiersz % 2 == 0 ? nieparzystyKolor: parzystyKolor); setForeground(titleColor);

Aby tabela zaczęła korzystać z naszego renderera, musimy dodać metodę, która zwraca typ danych dla każdej komórki do modelu danych:

Klasa publicznagetColumnClass(int kolumnaIndex) ( przełącznik (columnIndex) ( przypadek 0: zwróć String.class; przypadek 1: zwróć Date.class; ) return Object.class; )

Nowości może być dużo, więc postawmy tabelę na pasku przewijania i ukryjmy suwak przewijania, aby nie psuło to wyglądu widżetu:

JScrollPane scrollPane = nowy JScrollPane(tabela); table.setFillsViewportHeight(true); scrollPane.getVerticalScrollBar().setPreferredSize(nowy wymiar(0,0));

Dodaj komponent przewijania do głównego panelu okna. Drugim argumentem może być umiejscowienie komponentu. Domyślnie główny panel okna korzysta z menedżera układu BorderLayout, który rozmieszcza komponenty według głównych kierunków. Umieśćmy tabelę z przewijaniem na środku.

Frame.getContentPane().add(scrollPane, BorderLayout.CENTER);

Podobnie jak ostatnim razem usuniemy standardową ramę okienną. A jako tytuł okna użyjemy stylizowanej etykiety tekstowej, którą umieścimy na górze okna.

JLabel titleLabel = nowy JLabel("Xake RSS"); Tytuł czcionkiFont = new Font("Arial", Font.BOLD, 20); tytułLabel.setFont(tytuł Czcionki); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); titleLabel.setForeground(Kolor.BIAŁY); titleLabel.setPreferredSize(nowy wymiar(0, 40)); ramka.getContentPane().add(titleLabel, BorderLayout.NORTH);

W przeciwieństwie do SWT, obiekty kolorów i czcionek są zwalniane automatycznie, więc nie musisz się już martwić wyciekami pamięci.

Dodaj detektory myszy, aby okno mogło przesuwać się po ekranie.

Odbiornik MouseAdapter = nowy MouseAdapter() ( int startX; int startY; public void MousePressed(MouseEvent e) ( if (e.getButton() == MouseEvent.BUTTON1) ( startX = e.getX(); startY = e.getY( ); ) ) public void myszDragged(MouseEvent e) ( Punkt currCoords = e.getLocationOnScreen(); ramka.setLocation(currCoords.x - startX, currCoords.y - startY); ) ); titleLabel.addMouseListener(słuchacz); titleLabel.addMouseMotionListener(słuchacz);

Zmieńmy teraz kształt okna na prostokąt z zaokrąglonymi narożnikami. Najlepiej zrobić to w odbiorniku komponentowym, ponieważ jeśli zmieni się rozmiar okna, kształt okna zostanie ponownie obliczony poprawnie:

Frame.addComponentListener(new ComponentAdapter() ( public void komponentResized(ComponentEvent e) ( ramka.setShape(new RoundRectangle2D.Double(0, 0, ramka.getWidth(), ramka.getHeight(), 20, 20)); ) ) );

Ustaw rozmiar okna, usuń ramkę i spraw, aby okno było półprzezroczyste.

Frame.setSize(520, 300); ramka.setBez dekoracji(true); ramka.setOpacity(0.85f);

Na koniec otwieramy okno w strumieniu graficznym. SwingUtilities.invokeLater(new Runnable() (public void run() (frame.setVisible(true); ) ));

Pozostaje tylko dodać ładowanie danych w osobnym wątku, a otrzymamy taki widget z najświeższymi wiadomościami z Twojego ulubionego magazynu :).


JavaFX: posłuchajmy muzyki

I wreszcie atrakcją sezonu jest JavaFX. Wykorzystajmy jego możliwości multimedialne i komponent do kreślenia i stwórzmy prosty korektor.

Najpierw dziedziczymy klasę widgetu z Application. Jest to główna klasa aplikacji w JavaFX. Aplikacja zawiera główne metody cyklu życia aplikacji. Komponenty formularza tworzone są w metodzie start, która jako argument przyjmuje klasę Stage. Scena to okno programu. Zmieńmy styl okna na TRANSPARENTNY, aby usunąć obramowanie i przyciski. Stage zawiera klasę Scene, która ustawia rozmiar okna i kolor tła. W Scenie z kolei przekazujemy klasę Group, w której umieścimy komponenty potomne:

Publiczny start void(Stage basicStage) ( basicStage.initStyle(StageStyle.TRANSPARENT); Główny element grupy = nowa grupa(); Scena scena = nowa scena (root, 400, 200, Color.TRANSPARENT); basicStage.setScene(scene);

Aby wyświetlić korektor, używamy wykresu słupkowego, wzdłuż którego osi wyświetlimy częstotliwość i moc akustyczną:

Oś Kategorii xAxis = nowa Oś Kategorii(); NumberAxis yAxis = nowa NumberAxis(0,50,10); Wykres słupkowy bc = nowy wykres słupkowy (oś x, oś y); bc.setPrefSize(400, 200); bc.setLegendVisible(false); bc.setAnimated(false); bc.setBarGap(0); bc.setCategoryGap(1); bc.setVerticalGridLinesVisible(false); bc.setHorizontalGridLinesVisible(false); xAxis.setLabel("Częstotliwość"); yAxis.setLabel("Moc"); yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis, null, "dB"));

Wypełnij diagram danymi początkowymi:

Seria XYChart seria1 = nowa seria XYChart (); series1Data = nowy XYChart.Data; Kategorie ciągów = nowy ciąg; for (int i=0; tj (kategorie[i], 50); seria1.getData().add(seria1Data[i]); ) bc.getData().add(seria1);

Utwórz prostokąt z zaokrąglonymi rogami, aby nadać widgetowi odpowiedni kształt:

Prostokąt prostokąt = nowy prostokąt (0, 0, 400, 200); Stop zatrzymuje = nowy Stop ( nowy Stop(0, nowy Kolor(0, 0, 0, 0.8)), null); LinearGradient lg2 = nowy LinearGradient(0, 0, 0, 0, false, CycleMethod.NO_CYCLE, stopnie); prostokąt.setFill(lg2); prostokąt.setArcHeight(20); prostokąt.setArcWidth(20);

Dodaj oba komponenty do grupy:

Root.getChildren().addAll(prostokąt, bc);

Przypisujemy słuchaczy myszy do grupy, aby przesuwać okno po ekranie:

Root.setOnMousePressed (nowy EventHandler () ( public void handle(MouseEvent me) ( initX = me.getScreenX() - basicStage.getX(); initY = me.getScreenY() - basicStage.getY(); ) )); root.setOnMouseDragged (nowy moduł obsługi zdarzeń () ( public void handle(MouseEvent me) ( basicStage.setX(me.getScreenX() - initX); basicStage.setY(me.getScreenY() - initY); ) ));

Załaduj utwór do odtwarzacza:

Plik plik = nowy Plik("zabierz mnie stąd.mp3"); Media audioMedia = null; audioMedia = nowe multimedia(file.toURI().toURL().toString()); audioMediaPlayer = nowy MediaPlayer(audioMedia);

Dodaj słuchacza, który zaktualizuje wykres słupkowy:

AudioMediaPlayer.setAudioSpectrumListener(new AudioSpectrumListener() ( public void spectrumDataUpdate(podwójny znacznik czasu, podwójny czas trwania, wielkości zmiennoprzecinkowe, fazy zmiennoprzecinkowe) ( for (int i = 0; i< series1Data.length; i++) { series1Data[i].setYValue(magnitudes[i] + 60); } } });

Ustaw scenę jako widoczną i rozpocznij piosenkę:

Scena podstawowa.show(); audioMediaPlayer.play();

Uruchom aplikację:

Publiczny statyczny void main(String args) ( launch(args); )

I cieszymy się takim pięknem.