Zajecia 9. - JavaFX - zadania do samodzielnego wykonania
Organizacja
- Czas: 20-30 min
- Forma: samodzielnie lub w parach
- Zakres: od prostych kontrolek po mini-aplikacje z FXML i CSS
Zadanie A (latwe): Konwerter temperatur
Wymagania:
- Pole wejscia temperatury
- Dwa przyciski:
C → FiF → C - Etykieta z wynikiem
Wskazowki:
- Uzyj
Double.parseDouble - Obsluz
NumberFormatException - Obliczenia:
F = C * 9 / 5 + 32orazC = (F - 32) * 5 / 9
Rozwiazanie (przykladowe):
btnCtoF.setOnAction(e -> { try { double c = Double.parseDouble(input.getText().trim()); result.setText(String.format("%.2f F", c * 9 / 5 + 32)); } catch (NumberFormatException ex) { result.setText("Blad danych"); } }); btnFtoC.setOnAction(e -> { try { double f = Double.parseDouble(input.getText().trim()); result.setText(String.format("%.2f C", (f - 32) * 5 / 9)); } catch (NumberFormatException ex) { result.setText("Blad danych"); } });
Zadanie B (srednie): Formularz studenta
Wymagania:
- Pola: imie, nazwisko, numer indeksu
ComboBoxz kierunkiem studiow- Przycisk
Zapiszwyswietla podsumowanie wTextArea
Wskazowki:
- Uzyj
GridPanedo ukladu formularza - Waliduj, czy pola tekstowe nie sa puste
- Przed zapisem wyczysc
TextAreai wpisz podsumowanie
Rozwiazanie (przykladowe):
saveBtn.setOnAction(e -> { String first = firstName.getText().trim(); String last = lastName.getText().trim(); String index = indexField.getText().trim(); String major = majorBox.getValue(); if (first.isEmpty() || last.isEmpty() || index.isEmpty() || major == null) { summary.setText("Uzupelnij wszystkie pola"); return; } summary.setText( "Student:\n" + "Imie: " + first + "\n" + "Nazwisko: " + last + "\n" + "Indeks: " + index + "\n" + "Kierunek: " + major ); });
Zadanie C (srednie+): Lista wydatkow
Wymagania:
TableViewz kolumnami: nazwa, kategoria, kwota- Dodawanie nowego wydatku przez formularz
- Etykieta sumy wszystkich wydatkow
Wskazowki:
- Model danych jako klasa
ExpensezStringPropertyiDoubleProperty - Po dodaniu rekordu aktualizuj etykiete sumy
- Uzyj
PropertyValueFactoryalbo bindingu kolumn
Rozwiazanie (przykladowe):
private final ObservableList<Expense> expenses = FXCollections.observableArrayList(); private void updateTotal() { double total = expenses.stream().mapToDouble(Expense::getAmount).sum(); totalLabel.setText(String.format("Suma: %.2f PLN", total)); } addBtn.setOnAction(e -> { try { Expense expense = new Expense( nameField.getText().trim(), categoryBox.getValue(), Double.parseDouble(amountField.getText().trim()) ); expenses.add(expense); updateTotal(); } catch (Exception ex) { totalLabel.setText("Blad: sprawdz dane"); } });
Zadanie D (trudniejsze): Logowanie w FXML + CSS + walidacja
Wymagania:
- Widok w FXML (email, haslo, przycisk, status)
- Kontroler z walidacja danych
- Stylowanie przez zewnetrzny plik CSS
- Przycisk aktywny tylko dla poprawnych danych
Wskazowki:
fx:idmapuj na pola@FXML- Aktywacje przycisku zrob przez binding
disableProperty - Reguly: email zawiera
@i., haslo minimum 8 znakow
Rozwiazanie (przykladowe):
loginBtn.disableProperty().bind( Bindings.createBooleanBinding( () -> { String email = emailField.getText().trim(); String pass = passwordField.getText(); return !(email.contains("@") && email.contains(".") && pass.length() >= 8); }, emailField.textProperty(), passwordField.textProperty() ) ); loginBtn.setOnAction(e -> statusLabel.setText("Dane poprawne - logowanie..."));
Zadanie E (dla chetnych): Mini klient RIA
Wymagania:
- Widok JavaFX pobiera dane JSON z lokalnego endpointu REST
- Wyswietlenie listy rekordow (np. studenci) w
ListViewlubTableView - Obsluga bledu polaczenia
Wskazowki:
- Uzyj
HttpClientiTask(nie blokuj watku UI) - Wynik wrzuc do UI przez
Platform.runLater(…) - Przygotuj fallback: komunikat o bledzie i pusta lista
Rozwiazanie (szkic):
Task<String> loadTask = new Task<>() { @Override protected String call() throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://localhost:8080/api/students")) .GET() .build(); return HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()) .body(); } }; loadTask.setOnSucceeded(e -> statusLabel.setText("Pobrano dane")); loadTask.setOnFailed(e -> statusLabel.setText("Blad polaczenia")); new Thread(loadTask).start();
Kryteria oceny wykonania
- Dzialajacy interfejs i reakcja na zdarzenia
- Poprawna walidacja danych i obsluga bledow
- Czytelny podzial kodu (UI, logika, model)
- Dla wyzszej oceny: FXML + CSS + binding + dobra struktura projektu