Pytania w tym artykule pojawiły się podczas szkolenia Warsztaty programistyczne z języka Java realizowanego w dniach 05-07.06.2017 r.
Patryk Czarnik
SENIOR JAVA DEVELOPER AND TRAINER
Chciałbym umieścić w oknie Swing tabelę umożliwiającą wyświetlanie i edycję danych; zapleczem jest baza danych SQL.
Istnieje kilka możliwości powiązania graficznej tabeli (JTable) z bazodanowym modelem. Dwie najsensowniejsze to: 1) Zdefiniować własny TableModel, najlepiej na bazie AbstractTableModel, i oprogramować metody takie jak getValueAt, setValueAt i inne bardziej zaawansowane. To podejście daje nam pełną kontrolę nad zachowaniem tabeli, ale jest dość pracochłonne. 2) Drugim rozwiązaniem jest zastosować technologię Beans Binding (dodatkowa biblioteka poza Java SE), w ramach której można skonfigurować automatyczną synchronizację wyświetlanych wartości pól z wartościami naszych obiektów (lub innych komponentów graficznych). Dla tabel ta konfiguracja jest dość złożona, ale w jej utworzeniu bardzo pomaga edytor NetBeans. Dwukierunkowa synchronizacja wartości wymaga też utworzenia własnych klas JavaBean obsługujących takie aspekty jak powiadamianie o zmianach („listenery”). Jest to niezależne od sposobu dostępu do bazy danych, który może być zrealizowany tradycyjnie (JDBC) lub zgodnie z JPA (np. Hibernate).
Jak obsłużyć wartości typów nieobsługiwanych domyślnie w tabeli (np. data i czas)?
Jeśli sami definiujemy TableModel, można do tabeli wpisywać/odczytywać wartości typu String, a konwersji dokonywać w metodach getValueAt i setValueAt. Jednak bardziej porządnym rozwiązaniem, właściwym także wtedy gdy używa się Beans Binding, jest zdefiniować własne klasy TableCellRenderer i TableCellEditor, najprościej na bazie domyślnych DefaultTableCellRenderer/Editor. Można zacząć od prostych pól tekstowych, a w razie potrzeby zmienić je w przyszłości np. na wyskakujące okienka.
Jakich klasy używa się w Javie do reprezentowania daty i czasu?
Obsługa daty i czasu zmieniała się wraz z kolejnymi wersjami Javy i panuje w tym względzie spore zamieszanie. W Java SE 8 pojawił się nowy pakiet java.time, który zapewnia poprawną i porządnie zrealizowaną funkcjonalność. Na rozwiązanie składa się wiele klas, które służą do zapisywania różnego typu wartości dato-czasowych oraz wiele klas pomocniczych. Najbardziej praktyczne to LocalDate, LocalTime, LocalDateTime i ZonedDateTime, a także Duration i Period; wybór zależy od potrzeb, ale sytuacja jest klarowna. W nowych aplikacjach zdecydowanie powinniśmy używać java.time.
W aplikacjach, które muszą być zgodne ze starszymi wersjami Javy używa się obarczonej wieloma wadami klasy GregorianCalendar (lub jej nadklasy Calendar) lub bardzo prymitywnej java.util.Date. Alternatywą jest niestandardowa biblioteka Yoda Time. Przy dostępie do baz danych (JDBC) pojawia się potrzeba użycia jeszcze innych klas: java.sql.Date itp., na szczęście łatwo je konwertować na java.util.Date i nowe klasy z java.time.