~~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]]