Zadania praktyczne i samodzielne
Zadanie 5.2 z zajęć PA
Wykorzystując bibliotekę AWT stwórz prosty minutnik, który pozwala na odliczanie czasu od wartości podanej przez użytkownika do 0. Po zakonczeniu odliczania poinformuj o tym użytkownika (np. zmieniając kolor tła okna lub wyświetlając widoczną informację). Aplikacja powinna posiadać możliwość uruchomienia odliczania, zatrzymania go, ponownego uruchomienia i powrotu do stanu pierwotnego licznika. W swoim kodzie postaraj się wykorzystać wątki.
Demo 1 (10-15 min): Mini-formularz
Cel: przećwiczyć Frame, Panel, TextField, Button, ActionListener.
Kroki:
- utwórz
FramezBorderLayout - dodaj dwa pola
TextField(imię, nazwisko) - dodaj przycisk
Pokaż - po kliknięciu wyświetl
Label: „Witaj, Imię Nazwisko”
Wskazówki:
- logikę przycisku zapisz jako lambda
- przypnij
WindowAdapter, by poprawnie zamknąć aplikację
Skrócone rozwiązanie:
showButton.addActionListener(e -> { resultLabel.setText("Witaj, " + nameTf.getText() + " " + surnameTf.getText()); });
Demo 2 (10-15 min): Canvas - rysowanie i czyszczenie
Cel: przećwiczyć Canvas, paint(), repaint(), MouseMotionListener.
Kroki:
- przygotuj klasę
PaintCanvasprzechowującą listę punktów - w
mouseDraggeddodawaj punkt i wywołujrepaint() - dodaj przycisk
Wyczyść, który resetuje listę punktów
Wskazówki:
- nie rysuj bezpośrednio w listenerze
paintma tylko odtwarzać stan zapisany w polach klasy
Skrócone rozwiązanie:
clearButton.addActionListener(e -> canvas.clearAll());
Demo 3 (opcjonalne): Zmiana layoutu w runtime
Cel: pokazać różnicę między FlowLayout i GridLayout.
Kroki:
- utwórz panel z 6 przyciskami
- przełączaj layout przyciskiem
Przełącz układ - po zmianie wykonaj
panel.validate()ipanel.repaint()
Zadania samodzielne - poziom podstawowy
- Zadanie A1: Kalkulator sumy
- Dwa pola
TextField+ przyciskOblicz+Labelz wynikiem - Obsłuż błędne dane (
NumberFormatException) i pokaż komunikat
- Zadanie A2: Licznik kliknięć
- Przycisk
Kliknij mniezwiększa licznik i odświeżaLabel
- Zadanie A3: Formularz wyboru
CheckboxGroup(np. „Tryb A / Tryb B”) iChoicez 3 opcjami- Po zmianie wyboru aktualizuj etykietę podsumowującą
Zadania samodzielne - poziom średni
- Zadanie B1: Notatnik mini
TextArea+ przyciskiWyczyśćiStatystykiStatystykipokazują liczbę znaków i linii
- Zadanie B2: Prosty rysownik figur
- Na
Canvasrysuj kliknięciem koło lub prostokąt (wybór przezChoice) - Dodaj zmianę koloru figur (np.
CheckboxlubChoice)
- Zadanie B3: Okno „Ustawienia”
- Główne okno
Frame+Dialogniemodalny - W dialogu użytkownik zmienia rozmiar czcionki etykiety w głównym oknie
Zadania samodzielne - poziom zaawansowany
- Zadanie C1: Prosty program do rysowania
- Rysowanie na formie lub
Canvasprzy wciśniętym klawiszu myszy. Rejestruj kolejne punkty w odpowiedniej strukturze danych tak aby można było je później odtworzyć. - Dodaj możliwość wyboru koloru i grubości linii
- Dodaj przycisk „Wyczyść” do usuwania rysunku
- Dodaj przycisk „Zapisz” do zapisywania rysunku do pliku (np. jako obraz PNG)
- Dodaj przycisk „Animuj”, który odtwarza sekwencję rysowania (odtwarzanie kolejnych punktów z opóźnieniem) w osobnym wątku. Zatrzymanie animacji powinno być możliwe po ponownym kliknięciu „Animuj”.
- Zadanie C2: Animacja w AWT
- Obiekt (kula/prostokąt) porusza się po
Canvasi odbija od krawędzi - Aktualizacja położenia w osobnym wątku +
repaint()
- Zadanie C3: Mini-gra „reakcja”
- Co losowy czas pojawia się cel; użytkownik klika jak najszybciej
- Mierz czas reakcji i wyświetl średnią z ostatnich N prób
Podpowiedzi i szkice rozwiązań do zadań samodzielnych
- A1 (Kalkulator sumy):
- Podpowiedź: parsuj przez
Integer.parseInt(…)wtry/catch - Szkic rozwiązania:
try { int a = Integer.parseInt(aField.getText().trim()); int b = Integer.parseInt(bField.getText().trim()); result.setText("Suma: " + (a + b)); } catch (NumberFormatException ex) { result.setText("Błąd: podaj poprawne liczby całkowite"); }
- A2 (Licznik kliknięć):
- Podpowiedź: licznik trzymaj w polu klasy, nie w zmiennej lokalnej callbacka
- Szkic rozwiązania:
counter++; label.setText(„Kliknięcia: ” + counter);
- B1 (Notatnik mini):
- Podpowiedź: liczba linii =
textArea.getText().split(„\R”, -1).length - Szkic rozwiązania: po kliknięciu
Statystykipokaż wynik wLabellubDialog
- B2 (Rysownik figur):
- Podpowiedź: przechowuj listę obiektów
ShapeModel(typ, x, y, kolor) - Szkic rozwiązania: w
paintiteruj po liście i rysuj odpowiednią figurę
- C2 (Animacja):
- Podpowiedź: osobny wątek aktualizuje pozycję co 16-25 ms, UI tylko odmalowuje
- Szkic rozwiązania:
new Thread(() -> { while (running) { x += vx; y += vy; if (x < 0 || x > getWidth() - size) vx = -vx; if (y < 0 || y > getHeight() - size) vy = -vy; repaint(); try { Thread.sleep(16); } catch (InterruptedException ignored) {} } }).start();
Wskazówki do zadań i kryteria oceny
- Minimalne wymagania:
- poprawna obsługa zamknięcia okna
- sensowny layout (bez
setLayout(null)) - działająca obsługa zdarzeń
- Dodatkowe punkty:
- walidacja danych wejściowych
- czytelny podział kodu na klasy
- użycie adapterów tam, gdzie mają sens
- brak „zawieszania” GUI