===== 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