1|Strona Seminarium dyplomowe Mariusz Luttera, 19.04.2013r. Jak używać obiektu JTable – praktyczny przewodnik z przykładami i zapytaniami Niniejsza prezentacja będzie dotyczyć języka programowania java, a dokładniej graficznego interfejsu użytkownika(GUI). Prezentację chciałbym zacząć od wyjaśnienia kilku pojęć, dzięki czemu będziemy wiedzieć skąd wywodzi się obiekt JTable, który chciałbym bardziej szczegółowo omówić. Zacznę od pierwszej biblioteki, która umożliwiała projektowanie graficznego interfejsu użytkownika i nosiła nazwę Abstract Windows Toolkit. Jest to biblioteka, która istnieje już w javie od wersji 1.0 czyli od samego początku. AWT zawiera tylko i wyłącznie tzw. komponenty ciężkie czyli takie, które były rysowane przez system operacyjny co prowadziło do tego, że wygląd aplikacji był zależny od systemu operacyjnego. Biblioteka ta posiada wiele wad m.in.: słabe możliwości graficzne, brak komponentów istotnych dla programowania nowoczesnych graficznych interfejsów użytkownika itp. W celu poradzenia sobie z wadami biblioteki AWT stworzono nową, ulepszoną bibliotekę o nazwie SWING. Przede wszystkim w tej bibliotece graficznej prawie wszystkie komponenty były rysowane od nowa i posiadają przedrostek ‘J’. Są one również tzw. komponentami lekkimi co oznacza, że są one rysowane przez javę a nie jak było w przypadku AWT przez system operacyjny. SWING posiada bardzo bogatą kolekcję obiektów, jest w pełni obiektowa i użyto w niej intuicyjnych nazw co ułatwia życie programistom. Obiekt JTable jest jednym z komponentów biblioteki SWING i o nim chciałbym pokrótce opowiedzieć. Obiekt ten stanowi często wykorzystywany komponent interfejsu użytkownika i służy do wyświetlenia dwuwymiarowej siatki obiektów, czyli tabeli. Tabele są skomplikowanym komponentem, ale w ich przypadku projektantom klasy JTable udało się ukryć tę złożoność. W pełni funkcjonalne tabele o dużych możliwościach tworzymy już za pomocą kilku linijek kodu. Oczywiście kod ten możemy rozbudowywać, dostosowując wygląd i zachowanie tabeli do naszych potrzeb. Aby utworzyć obiekt JTable musimy stworzyć nową klasę o dowolnej nazwie, ale koniecznie musimy dziedziczyć metody z klasy JFrame. Klasa JTable posiada kilka swoich konstruktorów, dzięki którym w łatwy sposób możemy utworzyć tabelę. Najprostszym z nich jest dwuargumentowy konstruktor gdzie w pierwszym argumencie podajemy dwuwymiarową tablicę obiektów, z których ma się składać nasza tabela, a jako drugi argument podajemy jednowymiarową tablicę typu String, która będzie odpowiadała za nazwy naszych kolumn. Oczywiście samo użycie konstruktora nie wystarczy nam po to, żeby wyświetlić tabelę, a w dodatku, żeby tabela była funkcjonalna należałoby ją opakować w JScrollPane, dzięki któremu będziemy mogli przewijać nasze okienko w pionie i poziomie. Najważniejsze jednak jest utworzenie ramki i przy okazji obiektu który będzie w tej ramce. Do tego celu używamy polecenia JFrame ramka = new nazwaObiektu() 2|Strona gdzie ramka to nazwa naszej ramki a nazwaObiektu jest to nazwa klasy tworzącej JTable. Następnie wystarczy tylko użyć polecenia show() i będziemy mogli podziwiać naszą tabelę, która pojawi się na ekranie. Przykład tabeli: public class ProstaTabela { public static void main(String[] args) { Tabelka t = new Tabelka(); t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); t.show(); } } class Tabelka extends JFrame { private Object[][] planety = { { "Merkury", new Double(2440), new Integer(0), Boolean.FALSE, Color.yellow }, { "Wenus", new Double(6052), new Integer(0), Boolean.FALSE, Color.yellow }, … }; private String[] kolumny = { "Planeta", "Promień", "Księżyce", "Gazowa", "Kolor" }; public Tabelka() { setTitle("Prosta tabelka"); setSize(400,150); JTable tabela = new JTable(planety, kolumny); JScrollPane pane = new JScrollPane(tabela); add(pane); } } 3|Strona Jeśli kod nasz umieszcza dane w tablicy, aby zaprezentować je następnie w postaci tabeli, oznacza to, że powinniśmy zastanowić się nad implementacją własnego modelu tabeli. W celu utworzenia takiego modelu musimy koniecznie dziedziczyć z klasy AbstractTableModel, oraz obowiązkowo są do przesłonięcia trzy metody: getRowCount(), getColumnCount() i getValueAt(int row, int column). Jak sama nazwa wskazuje w metodzie getRowCount musimy zwrócić liczbę wierszy jakie będzie posiadać nasza tabela, a w metodzie getColumnCount liczbe kolumn. Liczby te możemy np.: pobrać konstruktorem do zmiennej i zwrócić w tych dwóch metodach odpowiednie zmienne, dzięki czemu nasz model tabeli będzie elastyczny i zawsze będziemy mogli przekazać do konstruktora inne dane, co będzie wypływać na ostateczny wygląd tabeli. Najważniejszą metodą do zaiplementowania jest: getValueAt(int row, int column) która będzie nam odpowiednio formatować dane i wstawiać po kolei w komórki tabeli. Postaram się pokazać na przykładzie, który będzie symulował saldo konta po każdym roku dla poszczególnego oprocentowania. Metoda getValueAt: public Object getValueAt(int row, int column) { double rate = (column + minRate) / 100.0; int nperiods = row; double futureBalance = INITIAL_BALANCE * Math.pow(1 + rate, nperiods); return NumberFormat.getCurrencyInstance().format(futureBalance); } 4|Strona Przyjmijmy, że posiadamy zmienną minRate, maxRate i years, do których przypisaliśmy wartości za pomocą konstruktora i mają się one następująco: 5, 10, 30, oraz zmienną INITIAL_BALANCE, która oznacza saldo początkowe i ma przypisaną wartość 10000. Za pomocą metody getRowCount zwracamy ilość wierszy czyli zwrócimy zmienna years, która odpowiada za to dla ilu lat chcemy policzyć odsetki. Skoro wiemy jaki jest zakres dla naszego oprocentowania (minRate i maxRate) to możemy łatwo policzyć ile kolumn będzie mieć nasza tabela (maxRate-minRate+1) i możemy tę wartość zwrócić metodą getColumnCount. Metoda getValueAt sama przekazuje argumenty ‘row’ i ‘column’ typu int, które oznaczają do jakiej komórki będą teraz liczone dane. Mając te wszystkie zmienne możemy teraz policzyć jakie będzie saldo konta po konkretnej ilości lat, oraz przy konkretnym oprocentowaniu. Jak widać metoda getValueAt będzie nam teraz sama liczyć każdą konkretną komórkę tabeli i co najważniejsze możemy zmieniać oprocentowania za pomocą konstruktora co w przypadku użycia gotowego konstruktora obiektu JTable nie jest możliwe, ponieważ przekazujemy gotową siatkę obiektów, którą musielibyśmy modyfikować jeśli byśmy by nasza tabela zawierała inne dane. Używanie obiektu JTable nie należy do najprostszych przy programowaniu graficznego interfejsu użytkownika ale jak widać przy odrobinie wiadomości można całkiem sprawnie i prosto z niego korzystać. Oczywiście możliwości tego komponentu są o wiele większe ale potrzeba byłoby bardzo dużo czasu na omówienie go dokładnie.