===== Demo 1 (łatwe): Formularz powitania ===== Cel: szybkie przejście przez ''JFrame'', ''JTextField'', ''JButton'', ''JLabel'', listener. Zadanie demonstracyjne: * Dwa pola: imię i nazwisko * Przycisk "Przywitaj" * Etykieta z wynikiem "Witaj, Imię Nazwisko" Wskazówki: * Użyj ''JPanel'' + ''GridLayout(0, 2, 8, 8)'' * Logikę kliknięcia dodaj przez ''addActionListener'' * Odczytuj tekst przez ''getText().trim()'' Rozwiązanie: public class DemoGreeting { public static void main(String[] args) { SwingUtilities.invokeLater(DemoGreeting::showUi); } static void showUi() { JFrame f = new JFrame("Powitanie"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTextField tfFirst = new JTextField(); JTextField tfLast = new JTextField(); JButton btn = new JButton("Przywitaj"); JLabel out = new JLabel(" "); JPanel p = new JPanel(new GridLayout(0, 2, 8, 8)); p.add(new JLabel("Imię:")); p.add(tfFirst); p.add(new JLabel("Nazwisko:")); p.add(tfLast); p.add(btn); p.add(out); btn.addActionListener(e -> { String full = tfFirst.getText().trim() + " " + tfLast.getText().trim(); out.setText("Witaj, " + full.trim()); }); f.setContentPane(p); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } } ===== Demo 2 (średnie): Lista z modelem danych ===== Cel: ''DefaultListModel'', ''JList'', operacje dodaj/usuń. Zadanie demonstracyjne: * Pole tekstowe + przycisk Dodaj * Lista elementów * Przycisk Usuń zaznaczony Wskazówki: * Dane trzymaj w ''DefaultListModel'' * ''list.getSelectedIndex()'' zwraca pozycję zaznaczenia * Przy braku zaznaczenia pokaż ''JOptionPane'' Rozwiązanie: public class DemoListModel { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame f = new JFrame("Lista z modelem"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DefaultListModel model = new DefaultListModel<>(); JList list = new JList<>(model); JTextField tf = new JTextField(16); JButton add = new JButton("Dodaj"); JButton remove = new JButton("Usuń zaznaczony"); add.addActionListener(e -> { String text = tf.getText().trim(); if (!text.isEmpty()) { model.addElement(text); tf.setText(""); } }); remove.addActionListener(e -> { int idx = list.getSelectedIndex(); if (idx >= 0) { model.remove(idx); } else { JOptionPane.showMessageDialog(f, "Najpierw zaznacz element"); } }); JPanel top = new JPanel(); top.add(tf); top.add(add); top.add(remove); f.add(top, BorderLayout.NORTH); f.add(new JScrollPane(list), BorderLayout.CENTER); f.setSize(520, 320); f.setLocationRelativeTo(null); f.setVisible(true); }); } } ===== Demo 3 (trudniejsze): Tabela i Action ===== Cel: ''DefaultTableModel'', wspólna akcja dla przycisku i menu. Zadanie demonstracyjne: * Tabela: ID, Nazwa, Cena * Akcja "Dodaj przykładowy wiersz" * Ta sama akcja w menu i na toolbarze Wskazówki: * Utwórz ''Action'' dziedzicząc po ''AbstractAction'' * W ''actionPerformed'' modyfikuj ''DefaultTableModel'' * Jeden obiekt ''Action'' podłącz do ''JButton'' i ''JMenuItem'' Rozwiązanie: public class DemoTableAction { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame f = new JFrame("Tabela + Action"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DefaultTableModel model = new DefaultTableModel(new Object[]{"ID", "Nazwa", "Cena"}, 0); JTable table = new JTable(model); Action addSample = new AbstractAction("Dodaj próbkę") { int id = 1; @Override public void actionPerformed(java.awt.event.ActionEvent e) { model.addRow(new Object[]{id++, "Produkt", 19.99}); } }; JToolBar bar = new JToolBar(); bar.add(new JButton(addSample)); JMenu file = new JMenu("Dane"); file.add(new JMenuItem(addSample)); JMenuBar mb = new JMenuBar(); mb.add(file); f.setJMenuBar(mb); f.add(bar, BorderLayout.NORTH); f.add(new JScrollPane(table), BorderLayout.CENTER); f.setSize(640, 360); f.setLocationRelativeTo(null); f.setVisible(true); }); } } ===== Zadania do samodzielnego wykonania - wybór ===== * Zadanie A (łatwe, 15-20 min): Kalkulator BMI * Zadanie B (średnie, 20-25 min): Notatnik TODO z ''JList'' * Zadanie C (średnie+, 25-30 min): Formularz rejestracji z walidacją * Zadanie D (trudniejsze, 30+ min): Mini CRM w ''JTable'' + ''DefaultTableModel'' ===== Zadanie A: Kalkulator BMI ===== Wymagania: * Pola: wzrost (cm), masa (kg) * Przycisk "Oblicz" * Wynik BMI i kategoria (niedowaga, norma, nadwaga, otyłość) Wskazówki: * Parsuj liczby przez ''Double.parseDouble'' * Obsłuż ''NumberFormatException'' i pokaż komunikat ''JOptionPane'' * Kategorie BMI trzymaj w oddzielnej metodzie Rozwiązanie: static String bmiCategory(double bmi) { if (bmi < 18.5) return "Niedowaga"; if (bmi < 25.0) return "Norma"; if (bmi < 30.0) return "Nadwaga"; return "Otyłość"; } // fragment listenera try { double cm = Double.parseDouble(tfHeight.getText().trim()); double kg = Double.parseDouble(tfWeight.getText().trim()); double m = cm / 100.0; double bmi = kg / (m * m); out.setText(String.format("BMI: %.2f (%s)", bmi, bmiCategory(bmi))); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(frame, "Podaj poprawne liczby"); } ===== Zadanie B: Notatnik TODO (JList) ===== Wymagania: * Dodawanie pozycji do listy * Usuwanie zaznaczonej pozycji * Oznaczanie zadania jako wykonane (np. prefiks "[x]") Wskazówki: * Użyj ''DefaultListModel'' * Aktualizuj element przez ''set(index, value)'' * Akcje "Dodaj" i "Usuń" mogą korzystać z osobnych ''Action'' Rozwiązanie: int i = list.getSelectedIndex(); if (i >= 0) { String old = model.get(i); if (!old.startsWith("[x] ")) { model.set(i, "[x] " + old); } } ===== Zadanie C: Formularz rejestracji ===== Wymagania: * Pola: email, hasło, potwierdzenie hasła * Checkbox akceptacji regulaminu * Przycisk "Zarejestruj" aktywny tylko gdy walidacja przejdzie Wskazówki: * Dla hasła użyj ''JPasswordField'' * Walidację uruchamiaj po każdej zmianie (np. ''DocumentListener'') * Wydziel metodę ''validateForm()'' i w niej steruj ''setEnabled'' Rozwiązanie: void validateForm() { String email = tfEmail.getText().trim(); String pass1 = new String(pf1.getPassword()); String pass2 = new String(pf2.getPassword()); boolean okEmail = email.contains("@") && email.contains("."); boolean okPass = pass1.length() >= 8 && pass1.equals(pass2); boolean okTerms = cbTerms.isSelected(); btnRegister.setEnabled(okEmail && okPass && okTerms); } ===== Zadanie D: Mini CRM (JTable) ===== Wymagania: * Tabela klientów: ID, Imię, Miasto, Status * Dodawanie i usuwanie rekordów * Filtrowanie po mieście Wskazówki: * Dane przechowuj w ''DefaultTableModel'' * Filtrowanie zrealizuj przez ''TableRowSorter'' * Każda operacja UI ma aktualizować tylko model, nie widok bezpośrednio Rozwiązanie: DefaultTableModel model = new DefaultTableModel(new Object[]{"ID", "Imię", "Miasto", "Status"}, 0); JTable table = new JTable(model); TableRowSorter sorter = new TableRowSorter<>(model); table.setRowSorter(sorter); // fragment filtrowania String city = tfCityFilter.getText().trim(); if (city.isEmpty()) { sorter.setRowFilter(null); } else { sorter.setRowFilter(RowFilter.regexFilter("(?i)" + java.util.regex.Pattern.quote(city), 2)); } ===== Zadanie 6 Kalkulator ===== Utwórz prosty, czterodziałaniowy kalkulator wykorzystujący Swing dla języka Java. Przy przygotowaniu GUI inspiruj się kalkulatorem systemu Windows. Zadbaj o obsługę liczb niecałkowitych. Wskazówki: * Użyj ''JTextField'' do wyświetlania aktualnego wyniku i wprowadzania liczb * Przyciski dla cyfr (0-9) i działań (+, -, *, /) * Obsłuż zdarzenia kliknięć przycisków przez ''ActionListener'' * Przechowuj aktualną wartość i ostatnią operację, aby umożliwić ciągłe obliczenia