~~NOCACHE~~ ~~REVEAL theme=simple&disableLayout=0&transition=none&controls=1&show_progress_bar=1&build_all_lists=0&show_image_borders=0&horizontal_slide_level=2&enlarge_vertical_slide_headers=0&show_slide_details=1&open_in_new_window=1&size=1024x768~~ ====== Zajęcia 8. - Graficzne interfejsy użytkownika - Swing ====== ===== Swing - wprowadzenie ===== * Swing to biblioteka GUI w pakiecie ''javax.swing'' * Część Java Foundation Classes (JFC) * Zbudowany na AWT, ale komponenty Swing są rysowane głównie w Javie (lightweight) * Spójny wygląd na różnych systemach operacyjnych * Bogatszy zestaw kontrolek niż klasyczne AWT * Dokumentacja: [[https://docs.oracle.com/javase/10/docs/api/javax/swing/package-summary.html|javax.swing (Java SE)]] ===== Swing i AWT - podobieństwa ===== * Te same fundamenty: okna, komponenty, kontenery, layouty * Ten sam model zdarzeń (listener, event object, źródło zdarzenia) * Często używane razem klasy z ''java.awt'' (np. ''BorderLayout'', ''Color'', ''Font'') * Główne okno nadal opiera się o ''java.awt.Window'' (np. ''JFrame'') ===== Swing i AWT - różnice ===== * AWT: komponenty natywne (heavyweight), Swing: głównie lekkie komponenty * Swing ma osobny model prezentacji (UI delegate, Look & Feel) * Swing oferuje więcej gotowych kontrolek i modeli danych * W Swing łatwiej utrzymać spójność UI między platformami * Rysowanie po komponentach przez ''paintComponent(Graphics g)'' * W praktyce: nowe GUI desktopowe w Javie zwykle robimy w Swing (lub JavaFX) ===== Hierarchia Swing - najważniejsze klasy ===== {{zajecia:java_2026_1:114_1.jpg}} ===== ===== * ''Component'' -> ''Container'' -> ''JComponent'' * ''JComponent'' to baza większości kontrolek Swing (''JButton'', ''JLabel'', ''JTable''...) * Top-level containers: * ''JFrame'' - główne okno * ''JDialog'' - okno dialogowe * ''JWindow'' - okno bez ramek systemowych * Każdy top-level container ma ''JRootPane'' z trzema głównymi panelami: ''glassPane'' (szklany), ''layeredPane'' (warstwowy), ''contentPane'' (treści) ===== Top-level containers ===== * ''glassPane'' - przezroczysta warstwa nad wszystkimi panelami (np. do rysowania, obsługi zdarzeń globalnych) * ''layeredPane'' - warstwy Z-order (kolejność ułożenia komponentów) * ''contentPane'' - główny obszar, gdzie dodajesz komponenty * opcjonalnie ''menuBar'' * Najczęściej pracujesz z ''contentPane'' przez ''frame.add(...)'' lub ''frame.getContentPane().add(...)'' JFrame frame = new JFrame("Warstwy Swing"); JComponent glass = (JComponent) frame.getGlassPane(); glass.setVisible(false); // np. true gdy chcemy overlay Container content = frame.getContentPane(); content.setLayout(new BorderLayout()); content.add(new JLabel("Treść główna"), BorderLayout.CENTER); ===== Pierwsze okno Swing ===== * Tworzenie GUI uruchamiaj na EDT (Event Dispatch Thread) - wątek odpowiedzialny za obsługę zdarzeń i rysowanie * Ustaw ''setDefaultCloseOperation(...)'' na ''JFrame.EXIT_ON_CLOSE'', aby zamknąć aplikację po zamknięciu okna * ''pack()'' - dopasuj rozmiar do zawartości import javax.swing.*; import java.awt.*; public class HelloSwing extends JFrame { public HelloSwing() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(new JLabel("Witaj, Swing!", SwingConstants.CENTER), BorderLayout.CENTER); pack(); setLocationRelativeTo(null); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { HelloSwing frame = new HelloSwing(); frame.setVisible(true); }); } } ===== Kontrolki Swing - szybki przegląd ===== * Tekst i input: ''JLabel'', ''JTextField'', ''JTextArea'', ''JPasswordField'' * Wybór: ''JCheckBox'', ''JRadioButton'', ''JComboBox'', ''JList'' * Akcje: ''JButton'', ''JToggleButton'', ''JMenuItem'', ''JToolBar'' * Dane złożone: ''JTable'', ''JTree'' * Kontenery: ''JPanel'', ''JScrollPane'', ''JTabbedPane'', ''JSplitPane'' * Dialogi: ''JOptionPane'', ''JFileChooser'', ''JColorChooser'' * ''JScrollBar'', ''JSeparator'', ''JProgressBar'', ''JSlider'', ''JSpinner'', ... ===== Obsługa zdarzeń ===== * Użytkownik wykonuje akcję na komponencie (źródło zdarzenia) * Swing tworzy obiekt zdarzenia (np. ''ActionEvent'') * Zarejestrowany listener odbiera callback JButton btn = new JButton("Policz"); JTextField input = new JTextField(10); JLabel out = new JLabel("Wynik: -"); btn.addActionListener(e -> { String text = input.getText().trim(); out.setText("Wynik: " + text.length()); }); ===== Layout Managers ===== * ''java.awt.BorderLayout'' - 5 regionów: NORTH, SOUTH, EAST, WEST, CENTER * ''java.awt.FlowLayout'' - komponenty od lewej do prawej * ''java.awt.GridLayout'' - siatka równych komórek * ''java.awt.CardLayout'' - przełączanie widoków * ''java.awt.GridBagLayout'' - najbardziej elastyczny (i najbardziej złożony) * ''javax.swing.BoxLayout'' - pionowo/poziomo * ''javax.swing.SpringLayout'' - układ sprężynowy * ''javax.swing.GroupLayout'' - używany przez GUI Designer ===== Swing GUI Designer ===== * Wtyczka do IntelliJ IDEA do projektowania interfejsów metodą drag-and-drop * Definicja UI w pliku ''.form'' (XML) * Logika aplikacji pozostaje w ''.java'' * Zalety: szybki prototyp, mniej ręcznego ustawiania layoutów * Uwaga: nie edytuj ręcznie ''.form'', jeśli nie musisz * Tworzenie aplikacji: Utwórz formę i ustaw ''setContentPane(panel)'' wskazując na główny panel z GUI Designer {{https://resources.jetbrains.com/help/img/idea/2026.1/ui_designer_example_form.png?400| }} ===== Look & Feel - dostosowanie wyglądu ===== * Każdy komponent Swing ma delegata UI (np. ''ButtonUI'') odpowiedzialnego za rysowanie i zachowanie * Look & Feel (LAF) to zestaw delegatów definiujący styl i zachowanie komponentów * Wbudowane LAF: Metal, Nimbus, System * LAF ustawiaj przed tworzeniem komponentów * Pobranie i ustawienie LAF: for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); break; } } ===== MVC w Swing ===== * Swing był projektowany z myślą o MVC, ale jego komponenty same w sobie są hybrydą View + Controller * Przykład: ''JButton''' ma własny ''ButtonModel''' (Model) i własne listenery (Controller), a Ty dostarczasz logikę. * Komponenty są powiązane z modelem danych (np. ''JTable'' z ''TableModel''), dane trzymasz w modelu, a komponent tylko je wyświetla ===== Modele danych w Swing ===== Dane trzymasz w modelu, a komponent tylko je wyświetla. ^ Komponent ^ Interfejs modelu ^ Domyślna implementacja ^ Opis ^ | ''JList'' | ''ListModel'' | ''DefaultListModel'' | Lista elementów | | ''JTable'' | ''TableModel'' | ''DefaultTableModel'' | Tabela wierszy i kolumn | | ''JComboBox'' | ''ComboBoxModel'' | ''DefaultComboBoxModel'' | Lista rozwijana | | ''JTree'' | ''TreeModel'' | ''DefaultTreeModel'' | Drzewo węzłów | | ''JTextField'', ''JTextArea'' | ''Document'' | ''PlainDocument'' | Treść pola tekstowego | | ''JProgressBar'', ''JSlider'', ''JScrollBar'' | ''BoundedRangeModel'' | ''DefaultBoundedRangeModel'' | Wartość w zakresie min–max | | ''JSpinner'' | ''SpinnerModel'' | ''SpinnerNumberModel'' | Wartość incrementalna | | ''JButton'', ''JCheckBox'', ''JRadioButton'' | ''ButtonModel'' | ''DefaultButtonModel'' | Stan przycisku (wciśnięty, zaznaczony) | ==== Przykład ==== DefaultListModel listModel = new DefaultListModel<>(); listModel.addElement("Ala"); listModel.addElement("Ola"); JList list = new JList<>(listModel); DefaultTableModel tableModel = new DefaultTableModel( new Object[]{"ID", "Nazwa"}, 0 ); tableModel.addRow(new Object[]{1, "Klient"}); JTable table = new JTable(tableModel); ===== Akcje Swing (Action API) ===== * ''Action'' łączy logikę i metadane akcji (tekst, ikona, skrót, enabled) * Jedna akcja może być podpięta do wielu komponentów * Centralizacja logiki: przycisk, menu, toolbar używają tego samego kodu * Parametry: ''Action.NAME'', ''Action.SHORT_DESCRIPTION'', ''Action.SMALL_ICON'', ''Action.ACCELERATOR_KEY'' * [[https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html|Java Tutorials - Actions]] Action saveAction = new AbstractAction("Zapisz") { @Override public void actionPerformed(ActionEvent e) { System.out.println("Zapis..."); } }; saveAction.putValue(Action.SHORT_DESCRIPTION, "Zapisz dane"); JButton saveBtn = new JButton(saveAction); JMenuItem saveItem = new JMenuItem(saveAction); ===== MVC w Swing ===== {{https://examples.javacodegeeks.com/wp-content/uploads/2016/01/swing_mvc_components.jpg?500|Przykład MVC w Swing}} [[https://examples.javacodegeeks.com/java-development/core-java/java-swing-mvc-example/|Java Swing MVC Example]] * Model — czysta logika i dane (np. stan aplikacji, obliczenia, walidacja) * View — komponenty Swing (JFrame, JPanel, JButton, JTable) * Controller — listenery, które reagują na zdarzenia i wywołują metody modelu ===== MVVM-like w Swing + PropertyChangeListener ===== * Swing nie ma natywnego MVVM jak JavaFX, ale można zrobić wariant * ViewModel publikuje zmiany przez ''PropertyChangeSupport'' * View nasłuchuje i aktualizuje kontrolki class PersonViewModel { private final java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this); private String name = ""; public void setName(String newName) { String old = this.name; this.name = newName; pcs.firePropertyChange("name", old, newName); } public void addPropertyChangeListener(java.beans.PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } } ===== Zadanie 7: Kalkulator w Swing ===== Utwórz prosty kalkulator wykorzystujący Swing dla języka Java. Wymagania: * Obsługa podstawowych działań: dodawanie, odejmowanie, mnożenie, dzielenie * Obsługa liczb niecałkowitych (np. 3.14) * Zamiana na liczbę ujemną (±) * Czyszczenie (C) * Przechowuj aktualną wartość i ostatnią operację, aby umożliwić ciągłe obliczenia * Interfejs inspirowany kalkulatorem systemu Windows Przykładowy wygląd aplikacji: {{ zajecia:java_2026_1:kalkulator.png?200 |Kalkulator w Swing - przykładowy interfejs}} ===== Materiały dodatkowe ===== * [[https://docs.oracle.com/javase/tutorial/uiswing/|The Java Tutorials - Swing]] * [[https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html|javax.swing API]] * [[https://docs.oracle.com/javase/8/docs/api/java/awt/event/package-summary.html|java.awt.event API]] * [[https://www.jetbrains.com/help/idea/design-gui-using-swing.html|IntelliJ IDEA - Swing GUI Designer]]