Java 2. Techniki zaawansowane
Upcoming SlideShare
Loading in...5
×
 

Java 2. Techniki zaawansowane

on

  • 1,496 views

...


* Przewodnik dla doświadczonych programistów omawiający zaawansowane możliwości platformy Java dla wersji JDK 1.3 i 1.4.
* Dostarcza wielu praktycznych przykładów kodu!
* Zawiera nowe bądź zaktualizowane omówienie: języka XML, problematyki bezpieczeństwa, programowania aplikacji sieciowych, wielowątkowości, kolekcji, zdalnych obiektów, interfejsu JDBC™, architektury komponentów JavaBeans™, biblioteki Swing i wielu innych zagadnień.


Przewodnik po zaawansowanych metodach programowania w Javie dla zaawansowanych programistów.

Książka ta dostarcza doświadczonym programistom rozwiązań niezbędnych do pełnego wykorzystania możliwości Javy. To praktyczny przewodnik ułatwiający rozwiązywanie nawet najbardziej złożonych problemów programistycznych. Dodatkowo zawiera zupełnie nowy rozdział poświęcony wykorzystaniu języka XML w programach pisanych w Javie oraz zaktualizowane omówienie wielu zaawansowanych możliwości tej platformy -- od kolekcji po metody macierzyste, od bezpieczeństwa po bibliotekę Swing.

Autorzy identyfikują problemy najczęściej napotykane przez doświadczonych programistów Javy i dostarczają przemyślanych rozwiązań zilustrowanych przykładami kodu, które uczyniły z tej książki prawdziwy bestseller. Dzięki niej ujrzysz w nowym świetle zagadnienia interfejsu ODBC™, tworzenia aplikacji sieciowych, wykorzystania zdalnych obiektów i wiele innych.

Najważniejsze informacje dla programistów Java:

* Zaktualizowane omówienie wielowątkowości, kolekcji i aplikacji sieciowych.
* Zmienione przedstawienie problematyki zdalnych obiektów.
* Nowe, zaawansowane techniki wykorzystania architektury komponentów JavaBeans™.
* Zaawansowane techniki tworzenia interfejsu użytkownika wykorzystujące biblioteki Swing i AWT.

Książka będzie dla Ciebie kolejnym krokiem w poznaniu możliwości Javy. Jest rozszerzeniem i doskonałym uzupełnieniem publikacji "Java 2. Postawy".

O autorach:
CAY S. HORSTMANN wykłada informatykę na uniwersytecie stanowym w San Jose. Napisał sześć książek o C++, Javie i programowaniu zorientowanym obiektowo. Jest redaktorem naczelnym bestselerowego cyklu Core Series, wydawnictwa Prentice Hall PTR.

GARY CORNELL zrobił doktorat na uniwersytecie Brown i współpracował z IBM Watson Labs. Jest autorem lub współautorem 20 książek oraz wielu artykułów, wydrukowanych w czasopismach komputerowych. Obecnie kieruje programem Modern Visual Programming na Uniwersytecie Connecticut.

Statistics

Views

Total Views
1,496
Views on SlideShare
1,496
Embed Views
0

Actions

Likes
0
Downloads
5
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Java 2. Techniki zaawansowane Java 2. Techniki zaawansowane Document Transcript

  • IDZ DO PRZYK£ADOWY ROZDZIA£ SPIS TRE CI Java 2. Techniki zaawansowane KATALOG KSI¥¯EK Autorzy: Cay S. Horstmann, Gary Cornell KATALOG ONLINE T³umaczenie: Jaromir Senczyk ISBN: 83-7197-985-1 ZAMÓW DRUKOWANY KATALOG Tytu³ orygina³u: Core Java 2 Volume 2 Advanced Features Format: B5, stron: 1122 TWÓJ KOSZYK DODAJ DO KOSZYKA Ksi¹¿ka ta dostarcza do wiadczonym programistom rozwi¹zañ niezbêdnych do pe³nego wykorzystania mo¿liwo ci Javy. To praktyczny przewodnik u³atwiaj¹cy rozwi¹zywanie nawet najbardziej z³o¿onych problemów programistycznych. Dodatkowo zawiera CENNIK I INFORMACJE zupe³nie nowy rozdzia³ po wiêcony wykorzystaniu jêzyka XML w programach pisanych w Javie oraz zaktualizowane omówienie wielu zaawansowanych mo¿liwo ci tej ZAMÓW INFORMACJE platformy — od kolekcji po metody macierzyste, od bezpieczeñstwa po bibliotekê Swing. O NOWO CIACH Autorzy identyfikuj¹ problemy najczê ciej napotykane przez do wiadczonych programistów Javy i dostarczaj¹ przemy lanych rozwi¹zañ zilustrowanych przyk³adami ZAMÓW CENNIK kodu, które uczyni³y z tej ksi¹¿ki prawdziwy bestseller. Dziêki niej ujrzysz w nowym wietle zagadnienia interfejsu ODBC™, tworzenia aplikacji sieciowych, wykorzystania zdalnych obiektów i wiele innych. CZYTELNIA Najwa¿niejsze informacje dla programistów Java: FRAGMENTY KSI¥¯EK ONLINE • Zaktualizowane omówienie wielow¹tkowo ci, kolekcji i aplikacji sieciowych. • Zmienione przedstawienie problematyki zdalnych obiektów. • Nowe, zaawansowane techniki wykorzystania architektury komponentów JavaBeans™. • Zaawansowane techniki tworzenia interfejsu u¿ytkownika wykorzystuj¹ce biblioteki Swing i AWT. Ksi¹¿ka bêdzie dla Ciebie kolejnym krokiem w poznaniu mo¿liwo ci Javy. Jest rozszerzeniem i doskona³ym uzupe³nieniem publikacji „Java 2. Postawy”. Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl
  • Spis treści Podziękowania................................................................................................................................9 Przedmowa ................................................................................................................................... 11 Do Czytelnika ........................................................................................................................ 11 O książce............................................................................................................................... 11 Rozdział 1. Wielowątkowość ...........................................................................................................15 Czym są wątki? ..................................................................................................................... 16 Zastosowanie wątków...................................................................................................... 21 Uruchamianie i wykonywanie wątków............................................................................... 22 Wykonywanie wielu wątków.............................................................................................. 27 Interfejs Runnable ........................................................................................................... 28 Przerywanie wątków............................................................................................................... 30 Właściwości wątków .............................................................................................................. 32 Stany wątków................................................................................................................... 32 Odblokowanie wątku........................................................................................................ 35 Wątki martwe................................................................................................................... 35 Wątki-demony .................................................................................................................. 36 Grupy wątków .................................................................................................................. 36 Priorytety wątków................................................................................................................... 38 Wątki egoistyczne.................................................................................................................. 45 Synchronizacja ...................................................................................................................... 51 Komunikacja między wątkami bez synchronizacji............................................................. 51 Synchronizacja dostępu do współdzielonych zasobów ..................................................... 55 Blokady obiektów............................................................................................................. 60 Metody wait i notify.......................................................................................................... 61 Bloki synchronizowane..................................................................................................... 66 Synchronizowane metody statyczne................................................................................. 67 Zakleszczenia........................................................................................................................ 68 Dlaczego metody stop i suspend nie są zalecane? ......................................................... 71 Limity czasu..................................................................................................................... 76 Programowanie interfejsu użytkownika przy użyciu wątków.................................................... 77 Wątki i Swing ................................................................................................................... 77 Animacja.......................................................................................................................... 85 Liczniki czasu................................................................................................................... 91 Paski postępu.................................................................................................................. 94 Monitory postępu............................................................................................................. 99 Monitorowanie postępu strumieni wejścia ..................................................................... 103 Zastosowanie potoków do komunikacji pomiędzy wątkami ................................................. 109
  • 4 Java 2. Techniki zaawansowane Rozdział 2. Kolekcje ..................................................................................................................... 115 Interfejsy kolekcji................................................................................................................. 115 Rozdzielenie interfejsów kolekcji od ich implementacji .................................................. 116 Interfejsy Collection i Iterator w bibliotekach języka Java............................................... 118 Kolekcje konkretne.............................................................................................................. 123 Listy powiązane ............................................................................................................. 123 Klasa ArrayList............................................................................................................... 132 Zbiory z kodowaniem mieszającym ................................................................................ 132 Zbiory drzewiaste........................................................................................................... 139 Mapy.............................................................................................................................. 145 Specjalizowane klasy map ............................................................................................. 150 Szkielet kolekcji................................................................................................................... 155 Widoki i opakowania ...................................................................................................... 158 Operacje masowe .......................................................................................................... 164 Wykorzystanie biblioteki kolekcji z tradycyjnymi bibliotekami ......................................... 165 Algorytmy............................................................................................................................. 166 Sortowanie i tasowanie.................................................................................................. 167 Wyszukiwanie binarne.................................................................................................... 170 Proste algorytmy ............................................................................................................ 171 Programowanie własnych algorytmów ............................................................................ 173 Tradycyjne kolekcje ............................................................................................................. 174 Klasa Hashtable ............................................................................................................ 174 Wyliczenia...................................................................................................................... 175 Zbiory właściwości ......................................................................................................... 176 Stosy ............................................................................................................................. 182 Zbiory bitów ................................................................................................................... 182 Rozdział 3. Programowanie aplikacji sieciowych..........................................................................187 Połączenia z serwerem........................................................................................................ 188 Implementacja serwerów..................................................................................................... 191 Obsługa wielu klientów .................................................................................................. 194 Wysyłanie poczty elektronicznej........................................................................................... 197 Zaawansowane programowanie przy użyciu gniazdek sieciowych ........................................ 202 Połączenia wykorzystujące URL ........................................................................................... 207 URL i URI ....................................................................................................................... 208 Zastosowanie klasy URLConnection do pobierania informacji ....................................... 210 Wysyłanie danych do formularzy .......................................................................................... 219 Skrypty CGI i serwlety .................................................................................................... 219 Wysyłanie danych do serwera stron internetowych ........................................................ 221 Zbieranie informacji w sieci Internet.................................................................................... 227 Bezpieczeństwo apletów................................................................................................ 233 Serwery proxy ................................................................................................................ 236 Testowanie apletu prognozy pogody .............................................................................. 243 Rozdział 4. Połączenia do baz danych: JDBC .................................................................................247 Architektura JDBC................................................................................................................ 248 Typowe zastosowania JDBC ........................................................................................... 251 Język SQL ............................................................................................................................ 252 Instalacja JDBC ................................................................................................................... 258 Podstawowe koncepcje programowania przy użyciu JDBC ................................................... 258 Adresy URL baz danych.................................................................................................. 259 Nawiązywanie połączenia............................................................................................... 259
  • Spis treści 5 Wykonywanie poleceń języka SQL .................................................................................. 264 Zaawansowane typy języka SQL (JDBC 2) ...................................................................... 266 Wypełnianie bazy danych ............................................................................................... 268 Wykonywanie zapytań.......................................................................................................... 272 Przewijalne i aktualizowalne zbiory wyników zapytań ........................................................... 282 Przewijalne zbiory rekordów (JDBC 2) ............................................................................. 283 Aktualizowalne zbiory rekordów (JDBC 2) ....................................................................... 286 Metadane............................................................................................................................ 290 Transakcje........................................................................................................................... 300 Aktualizacje wsadowe (JDBC 2)...................................................................................... 301 Zaawansowane zarządzanie połączeniami........................................................................... 302 Rozdział 5. Obiekty zdalne ...........................................................................................................305 Wprowadzenie do problematyki obiektów zdalnych: role klienta i serwera ..................... 306 Wywołania zdalnych metod (RMI)......................................................................................... 308 Namiastka i szeregowanie parametrów ......................................................................... 309 Dynamiczne ładowanie klas ........................................................................................... 311 Konfiguracja wywołania zdalnych metod .............................................................................. 311 Interfejsy i implementacje.............................................................................................. 312 Odnajdywanie obiektów serwera .................................................................................... 315 Po stronie klienta........................................................................................................... 319 Przygotowanie wdrożenia ............................................................................................... 323 Wdrożenie programu ...................................................................................................... 326 Przekazywanie parametrów zdalnym metodom .................................................................... 326 Przekazywanie lokalnych obiektów ................................................................................. 326 Przekazywanie zdalnych obiektów .................................................................................. 338 Wykorzystanie zdalnych obiektów w zbiorach................................................................. 341 Klonowanie zdalnych obiektów....................................................................................... 342 Niewłaściwe zdalne parametry....................................................................................... 343 Wykorzystanie RMI w apletach ............................................................................................ 344 Aktywacja obiektów serwera................................................................................................ 348 Java IDL i CORBA................................................................................................................. 355 Język IDL........................................................................................................................ 356 Przykład aplikacji CORBA ............................................................................................... 361 Implementacja serwerów CORBA ................................................................................... 370 Rozdział 6. Zaawansowane mo liwości pakietu Swing .................................................................377 Listy..................................................................................................................................... 377 Komponent JList ............................................................................................................ 378 Modele list..................................................................................................................... 382 Wstawianie i usuwanie .................................................................................................. 387 Odrysowywanie zawartości listy...................................................................................... 389 Drzewa ................................................................................................................................ 394 Najprostsze drzewa........................................................................................................ 395 Przeglądanie węzłów ...................................................................................................... 410 Rysowanie węzłów ......................................................................................................... 412 Nasłuchiwanie zdarzeń w drzewach ............................................................................... 419 Własne modele drzew.................................................................................................... 425 Tabele ................................................................................................................................. 433 Najprostsze tabele......................................................................................................... 433 Modele tabel.................................................................................................................. 437 Filtry sortujące ............................................................................................................... 447
  • 6 Java 2. Techniki zaawansowane Rysowanie i edytowanie zawartości komórek................................................................. 454 Operacje na wierszach i kolumnach............................................................................... 469 Wybór wierszy, kolumn i komórek .................................................................................. 470 Komponenty formatujące tekst ........................................................................................... 478 Organizatory komponentów ................................................................................................. 484 Panele dzielone ............................................................................................................. 485 Panele z zakładkami ...................................................................................................... 489 Panele pulpitu i ramki wewnętrzne................................................................................. 494 Rozmieszczenie kaskadowe i sąsiadujące..................................................................... 497 Zgłaszanie weta do zmiany właściwości......................................................................... 500 Rozdział 7. Zaawansowane mo liwości biblioteki AWT ..................................................................513 Potokowe tworzenie grafiki .................................................................................................. 514 Figury................................................................................................................................... 516 Wykorzystanie klas obiektów graficznych ....................................................................... 518 Pola ..................................................................................................................................... 531 Ślad pędzla ......................................................................................................................... 535 Wypełnienia......................................................................................................................... 543 Przekształcenia układu współrzędnych ................................................................................ 549 Przycinanie .......................................................................................................................... 557 Przezroczystość i składanie obrazów ................................................................................... 562 Wskazówki operacji graficznych........................................................................................... 570 Czytanie i zapisywanie plików graficznych............................................................................ 575 Wykorzystanie obiektów zapisu i odczytu plików graficznych.......................................... 576 Odczyt i zapis plików zawierających sekwencje obrazów ................................................ 578 Operacje na obrazach.......................................................................................................... 588 Dostęp do danych obrazu .............................................................................................. 588 Filtrowanie obrazów ....................................................................................................... 595 Drukowanie ......................................................................................................................... 604 Drukowanie grafiki ......................................................................................................... 604 Drukowanie wielu stron.................................................................................................. 614 Podgląd wydruku............................................................................................................ 616 Usługi drukowania ......................................................................................................... 625 Usługi drukowania za pośrednictwem strumieni ............................................................ 631 Atrybuty drukowania....................................................................................................... 636 Schowek.............................................................................................................................. 643 Klasy i interfejsy umożliwiające przekazywanie danych .................................................. 644 Przekazywanie tekstu..................................................................................................... 644 Interfejs Transferable i formaty danych.......................................................................... 649 Przekazywanie obrazów za pomocą schowka ................................................................. 651 Wykorzystanie lokalnego schowka do przekazywania referencji obiektów ...................... 656 Wykorzystanie schowka systemowego do przekazywania obiektów Java ....................... 662 Mechanizm „przeciągnij i upuść”......................................................................................... 666 Cele mechanizmu „przeciągnij i upuść” ......................................................................... 668 Źródła mechanizmu „przeciągnij i upuść” ...................................................................... 677 Przekazywanie danych pomiędzy komponentami Swing ................................................. 683 Rozdział 8. JavaBeans.................................................................................................................687 Dlaczego ziarnka? ............................................................................................................... 688 Proces tworzenia ziarnek JavaBeans ................................................................................... 689 Wykorzystanie ziarnek do tworzenia aplikacji....................................................................... 693 Umieszczanie ziarnek w plikach JAR .............................................................................. 694 Korzystanie z ziarnek ..................................................................................................... 696
  • Spis treści 7 Wzorce nazw właściwości ziarnek i zdarzeń......................................................................... 701 Typy właściwości ziarnek ..................................................................................................... 703 Właściwości proste ........................................................................................................ 703 Właściwości indeksowane ............................................................................................. 704 Właściwości powiązane ................................................................................................. 705 Właściwości ograniczone ............................................................................................... 711 Tworzenie własnych zdarzeń związanych z ziarnkami........................................................... 721 Edytory właściwości ............................................................................................................. 727 Implementacja edytora właściwości ............................................................................... 735 Klasa informacyjna ziarnka.................................................................................................. 749 Klasa FeatureDescriptor ................................................................................................ 751 Indywidualizacja ziarnka ...................................................................................................... 758 Implementacja klasy indywidualizacji ............................................................................. 760 Kontekst ziarnka ................................................................................................................. 768 Zaawansowane zastosowanie introspekcji..................................................................... 768 Odnajdywanie ziarnek siostrzanych................................................................................ 771 Korzystanie z usług kontekstu ziarnka ........................................................................... 773 Rozdział 9. Bezpieczeństwo.........................................................................................................783 Ładowanie klas.................................................................................................................... 784 Implementacja własnej procedury ładującej................................................................... 787 Weryfikacja kodu maszyny wirtualnej................................................................................... 794 Menedżery bezpieczeństwa i pozwolenia............................................................................. 799 Bezpieczeństwo na platformie Java 2 ............................................................................ 801 Pliki polityki bezpieczeństwa.......................................................................................... 806 Tworzenie własnych klas pozwoleń ................................................................................ 813 Implementacja klasy pozwoleń ...................................................................................... 814 Tworzenie własnych menedżerów bezpieczeństwa......................................................... 820 Uwierzytelnianie użytkowników....................................................................................... 828 Podpis cyfrowy..................................................................................................................... 834 Skróty wiadomości......................................................................................................... 834 Podpisywanie wiadomości ............................................................................................. 840 Uwierzytelnianie wiadomości ......................................................................................... 847 Certyfikaty X.509 ........................................................................................................... 849 Tworzenie certyfikatów................................................................................................... 851 Podpisywanie certyfikatów ............................................................................................. 854 Podpisywanie kodu.............................................................................................................. 861 Podpisywanie plików JAR ............................................................................................... 862 Wskazówki dotyczące wdrożenia.................................................................................... 866 Certyfikaty twórców oprogramowania ............................................................................. 867 Szyfrowanie ......................................................................................................................... 868 Szyfrowanie symetryczne ............................................................................................... 869 Szyfrowanie kluczem publicznym ................................................................................... 875 Strumienie szyfrujące .................................................................................................... 880 Rozdział 10. Internacjonalizacja...................................................................................................883 Lokalizatory ......................................................................................................................... 884 Liczby i waluty ..................................................................................................................... 890 Data i czas .......................................................................................................................... 896 Tekst ................................................................................................................................... 903 Porządek alfabetyczny.................................................................................................... 903 Granice tekstu ............................................................................................................... 910
  • 8 Java 2. Techniki zaawansowane Formatowanie komunikatów .......................................................................................... 916 Formatowanie z wariantami ........................................................................................... 920 Konwersje zbiorów znaków ............................................................................................ 924 Internacjonalizacja a pliki źródłowe programów.............................................................. 925 Zasoby ................................................................................................................................ 926 Lokalizacja zasobów ...................................................................................................... 927 Tworzenie klas zasobów ................................................................................................ 928 Lokalizacja graficznego interfejsu użytkownika .................................................................... 931 Lokalizacja apletu .......................................................................................................... 934 Rozdział 11. Metody macierzyste ..................................................................................................951 Wywołania funkcji języka C z programów w języku Java ....................................................... 953 Wykorzystanie funkcji printf............................................................................................ 954 Numeryczne parametry metod i wartości zwracane ............................................................. 959 Wykorzystanie funkcji printf do formatowania liczb ........................................................ 959 Łańcuchy znaków jako parametry ........................................................................................ 961 Wywołanie funkcji sprintf przez metodę macierzystą...................................................... 964 Dostęp do składowych obiektu............................................................................................ 966 Dostęp do statycznych składowych klasy ............................................................................ 969 Sygnatury ............................................................................................................................ 971 Wywoływanie metod języka Java.......................................................................................... 973 Wywoływanie metod obiektów........................................................................................ 973 Wywoływanie metod statycznych.................................................................................... 976 Konstruktory .................................................................................................................. 977 Alternatywne sposoby wywoływania metod .................................................................... 977 Tablice................................................................................................................................. 980 Obsługa błędów................................................................................................................... 984 Interfejs programowy wywołań języka Java .......................................................................... 989 Kompletny przykład: dostęp do rejestru systemu Windows ................................................. 992 Rejestr systemu Windows.............................................................................................. 992 Interfejs dostępu do rejestru na platformie Java............................................................ 994 Implementacja dostępu do rejestru za pomocą metod macierzystych ........................... 995 Rozdział 12. Język XML ..............................................................................................................1009 Wprowadzenie do języka XML............................................................................................ 1010 Struktura dokumentu XML ........................................................................................... 1012 Parsowanie dokumentów XML........................................................................................... 1015 Definicje typów dokumentów ............................................................................................. 1026 Praktyczny przykład ...................................................................................................... 1034 Przestrzenie nazw.............................................................................................................. 1046 Wykorzystanie parsera SAX ............................................................................................... 1048 Tworzenie dokumentów XML ............................................................................................. 1053 Przekształcenia XSL .......................................................................................................... 1061 Skorowidz.................................................................................................................................1073
  • 6 Zaawansowane mo liwości pakietu Swing W tym rozdziale: n Listy. n Drzewa. n Tabele. n Komponenty formatujące tekst. n Organizatory komponentów. W rozdziale tym kontynuować będziemy rozpoczęte w ksią ce Java 2. Podstawy omówienie pakietu Swing wykorzystywanego do tworzenia interfejsu u ytkownika. Pakiet Swing posiada bardzo rozbudowane mo liwości, a w ksią ce Java 2. Podstawy zdołaliśmy przedstawić jedy- nie komponenty najczęściej u ywane. Większość niniejszego rozdziału poświęcimy zło onym komponentom, takim jak listy, drzewa i tabele. Komponenty umo liwiające formatowanie tek- stu, na przykład HTML, posiadają jeszcze bardziej zło oną implementację. Omówimy sposób ich praktycznego wykorzystania. Rozdział zakończymy przedstawieniem organizatorów kom- ponentów, takich jak panele z zakładkami i panele z wewnętrznymi ramkami. Listy Prezentując u ytkownikowi zbiór elementów do wyboru, mo emy skorzystać z ró nych kom- ponentów. Jeśli zbiór ten zawierać będzie wiele elementów, to ich przedstawienie za pomocą pól wyboru zajmie zdecydowanie za du o miejsca w oknie programu. Skorzystamy wtedy zwykle z listy bądź listy rozwijalnej. Listy rozwijalne są stosunkowo prostymi komponentami i dlatego omówiliśmy je ju w ksią ce Java 2. Podstawy. Natomiast listy reprezentowane przez komponent ,.KUV posiadają du o większe mo liwości, a sposób ich u ycia przypomina korzystanie z innych zło onych komponentów, takich jak drzewa czy tabele. Dlatego właśnie od list rozpoczniemy omówienie zło onych komponentów pakietu Swing.
  • 378 Java 2. Techniki zaawansowane Listy często składają się z łańcuchów znaków, ale w praktyce zawierać mogą dowolne obiekty i kontrolować przy tym sposób ich prezentacji. Wewnętrzna architektura listy, która umo li- wia taki stopień ogólności, prezentuje się dość elegancko. Niestety projektanci z firmy Sun postanowili pochwalić się elegancją tworzonych rozwiązań, zamiast ukryć ją przed programi- stami korzystającymi z komponentu. Skutkiem tego posługiwanie się listami w najprostszych przypadkach jest trochę skomplikowane, poniewa programista musi manipulować mechani- zmami, które umo liwiają wykorzystanie list w bardziej zło onych przypadkach. Omówienie rozpoczniemy od przedstawienia najprostszego i najczęściej spotykanego zastosowania tego komponentu — listy, której elementami są łańcuchy znaków. Później przejdziemy do bardziej zło onych przykładów ilustrujących uniwersalność komponentu. Komponent JList Zastosowanie komponentu ,.KUV przypomina u ycie zbioru komponentów, takich jak przy- ciski lub pola wyboru. Ró nica polega na tym, e elementy listy umieszczone są we wspól- nej ramce, a wyboru dokonuje się, wskazując dany element, a nie związane z nim pole bądź przycisk. U ytkownik mo e te wybrać wiele elementów listy, jeśli pozwolimy na to. Rysunek 6.1 pokazuje najprostszy przykład listy. U ytkownik mo e z niej wybrać atrybuty opisujące lisa, takie jak „quick”, „brown”, „hungry” i „wild” oraz, z braku innych pomy- słów, „static”, „private” i „final”. Rysunek 6.1. Komponent klasy JList Tworzenie listy rozpoczynamy od skonstruowania tablicy łańcuchów znaków, którą na- stępnie przekazujemy konstruktorowi klasy ,.KUV: 5VTKPI=? YQTFU  ] SWKEM  DTQYP  JWPIT[  YKNF    _ ,.KUV YQTF.KUV  PGY ,.KUV YQTFU  Mo emy wykorzystać w tym celu tak e anonimową tablicę: ,.KUV YQTF.KUV  PGY ,.KUV PGY 5VTKPI=? ] SWKEM  DTQYP  JWPIT[  YKNF    _  Komponenty ,.KUV nie przewijają automatycznie swojej zawartości. W tym celu musimy umieścić listę w panelu przewijalnym: ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG YQTF.KUV 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 379 Panel ten, a nie listę, umieszczamy następnie na docelowym panelu okna. Rozdzielenie prezentacji listy od mechanizmu przewijania jest z pewnością rozwiązaniem eleganckim, ale mało praktycznym. Właściwie prawie wszystkie listy wymagają przewija- nia. Zmuszanie programistów, by za ka dym razem, gdy tworzą najprostszą listę, podzi- wiali działanie tego mechanizmu, jest okrutne. Domyślnie lista mieści osiem elementów widocznych jednocześnie. Mo emy to zmienić, korzystając z metody UGV8KUKDNG4QY%QWPV: YQTF.KUVUGV8KUKDNG4QY%QWPV    RQMCWLG LGFPQEG PKG  GNGOGPVÎY Domyślnie u ytkownik mo e wybierać wiele elementów listy. Wymaga to od niego za- awansowanego posługiwania się myszą: wybierając kolejne elementy, musi jednocześnie wciskać klawisz Ctrl. Aby wytypować pewien ciągły zakres elementów, u ytkownik po- winien zaznaczyć pierwszy z nich a następnie, wciskając klawisz Shift, wybrać ostatni z elementów. Mo liwość wyboru elementów przez u ytkownika mo emy ograniczyć, korzystając z me- tody UGV5GNGEVKQP/QFG: YQTF.KUVUGV5GNGEVKQP/QFG .KUV5GNGEVKQP/QFGN5+0).'A5'.'%6+10   OQ NKYQ è Y[DQTW RQLGF[PEGIQ GNGOGPVW YQTF.KUVUGV5GNGEVKQP/QFG .KUV5GNGEVKQP/QFGN5+0).'A+06'48#.A5'.'%6+10   OQ NKYQ è Y[DQTW RQLGF[PEGIQ GNGOGPVW NWD RQLGF[PEGIQ CMTGUW GNGOGPVÎY Z lektury ksią ki Java 2. Podstawy przypominamy sobie z pewnością, e podstawowe ele- menty interfejsu u ytkownika generują zdarzenia akcji w momencie ich aktywacji przez u ytkownika. Listy wykorzystują jednak inny mechanizm powiadomień. Zamiast nasłu- chiwać zdarzeń akcji, w przypadku list nasłuchiwać będziemy zdarzeń wyboru na liście. W tym celu musimy dodać do komponentu listy obiekt nasłuchujący wyboru i zaimple- mentować następującą metodę obiektu nasłuchującego: RWDNKE XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV GXV Podczas dokonywania wyboru na liście generuje się sporo zdarzeń. Załó my na przykład, e u ytkownik przechodzi do kolejnego elementu listy. Gdy naciska klawisz myszy, gene- rowane jest zdarzenie zmiany wyboru na liście. Zdarzenie to jest przejściowe i wywołanie metody GXGPVKU#FLWUVKPI zwraca wartość VTWG, gdy wybór nie jest ostateczny. Gdy u ytkownik puszcza klawisz my- szy, generowane jest kolejne zdarzenie, dla którego wywołanie metody KU#FLWUVKPI zwróci tym razem wartość HCNUG. Jeśli nie jesteśmy zainteresowani przejściowymi zdarzeniami na liście, to wystarczy poczekać jedynie na zdarzenie, dla którego metoda KU#FLWUVKPI zwróci właśnie wartość HCNUG. W przeciwnym razie musimy obsługiwać wszystkie zdarzenia. Zwykle po zawiadomieniu o zdarzeniu będziemy chcieli się dowiedzieć, które elementy zo- stały wybrane. Metoda IGV5GNGEVGF8CNWGU zwraca tablicę obiektów zawierającą wybrane elementy.
  • 380 Java 2. Techniki zaawansowane Ka dy z jej elementów musimy rzutować na łańcuch znaków. 1DLGEV=? XCNWGU  NKUVIGV5GNGEVGF8CNWGU  HQT KPV K K  XCNWGUNGPIVJ K RTGVYCTCPKG GNGOGPVÎY RQUVCEK 5VTKPI XCNWGU=K? Nie możemy rzutować tablicy 1DLGEV=? zwróconej przez metodę IGV5GNGEVGF8CNWGU na tablicę 5VTKPI=?. Zwracana przez metodę tablica została utworzona nie jako tablica łańcuchów znaków, ale jako tablica obiektów, z których każdy jest akurat łańcuchem znaków. Jeśli chcemy przetwarzać zwróconą tablicę jako tablicę łańcuchów znaków, to powinniśmy skorzystać z poniższego kodu: KPV NGPIVJ  XCNWGUNGPIVJ 5VTKPI=? YQTFU  PGY 5VTKPI=NGPIVJ? 5[UVGOCTTC[%QR[ XCNWGU  YQTFU  NGPIVJ  Jeśli lista nie dopuszcza wyboru wielu elementów, to mo emy skorzystać z metody IGV5G NGEVGF8CNWG. Zwraca ona pierwszy element wybrany na liście. 5VTKPI UGNGEVKQP  5VTKPI UQWTEGIGV5GNGEVGF8CNWG  Listy nie obsługują dwukrotnych kliknięć myszą. Projektanci pakietu Swing założyli, że na liście dokonuje się jedynie wyboru, a następnie zaznacza się komponent przycisku, aby wykonać jakąś akcję. Niektóre interfejsy użytkownika posiadają możliwość dwu- krotnego kliknięcia elementu listy w celu dokonania jego wyboru i wykonania na nim pewnej akcji. Uważamy, że nie jest to zbyt dobry styl tworzenia interfejsu użytkownika, ponieważ wymaga, by użytkownik samodzielnie odkrył możliwość takiego jego działa- nia. Jeśli jednak z pewnych powodów chcemy skorzystać z możliwości implementacji takiego zachowania listy, to musimy dodać do niej obiekt nasłuchujący mysz i obsłu- giwać zdarzenia myszy w następujący sposób: RWDNKE XQKF OQWUG%NKEMGF /QWUG'XGPV GXV ] KH GXVIGV%NKEM%QWPV   ] ,.KUV UQWTEG  ,.KUV GXVIGV5QWTEG  1DLGEV=? UGNGEVKQP  UQWTEGIGV5GNGEVGF8CNWGU  FQ#EVKQP UGNGEVKQP  _ _ Listing 6.1 zawiera tekst źródłowy programu demonstrującego wykorzystanie listy wypeł- nionej łańcuchami znaków. Zwróćmy uwagę na sposób, w jaki metoda XCNWG%JCPIGF two- rzy łańcuch komunikatu z wybranych elementów listy. Listing 6.1. ListTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG NKUV[ CYKGTCLæEGL C EWEJ[ PCMÎY
  •  RWDNKE ENCUU .KUV6GUV
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 381 ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY .KUV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC NKUVú U ÎY K GV[MKGVú RQMCWLæEæ FCPKG Q QPG Y[DTCP[EJ U ÎY 2T[VT[OWLæE MNCYKU %VTN Y[DTCè OQ PC YKGNG U ÎY C MNCYKU 5JKHV RQYCNC PC Y[DÎT EC GIQ CMTGUW U ÎY
  •  ENCUU .KUV(TCOG GZVGPFU ,(TCOG ] RWDNKE .KUV(TCOG ] UGV6KVNG .KUV6GUV  UGV5KG 9+&6* *'+)*6  5VTKPI=? YQTFU  ] SWKEM  DTQYP  JWPIT[  YKNF  UKNGPV  JWIG  RTKXCVG  CDUVTCEV  UVCVKE  HKPCN _ YQTF.KUV  PGY ,.KUV YQTFU  ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG YQTF.KUV  ,2CPGN R  PGY ,2CPGN  RCFF UETQNN2CPG  YQTF.KUVCFF.KUV5GNGEVKQP.KUVGPGT PGY .KUV5GNGEVKQP.KUVGPGT ] RWDNKE XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV GXGPV ] 1DLGEV=? XCNWGU  YQTF.KUVIGV5GNGEVGF8CNWGU  5VTKPI$WHHGT VGZV  PGY 5VTKPI$WHHGT RTGHKZ  HQT KPV K   K  XCNWGUNGPIVJ K ] 5VTKPI YQTF  5VTKPI XCNWGU=K? VGZVCRRGPF YQTF  VGZVCRRGPF  _ VGZVCRRGPF UWHHKZ  NCDGNUGV6GZV VGZVVQ5VTKPI  _ _  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF R $QTFGT.C[QWV5176*  NCDGN  PGY ,.CDGN RTGHKZ UWHHKZ  EQPVGPV2CPGCFF NCDGN $QTFGT.C[QWV%'06'4  _
  • 382 Java 2. Techniki zaawansowane RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   RTKXCVG ,.KUV YQTF.KUV RTKXCVG ,.CDGN NCDGN RTKXCVG 5VTKPI RTGHKZ  6JG  RTKXCVG 5VTKPI UWHHKZ  HQZ LWORU QXGT VJG NC[ FQI  _ LCXCZUYKPI,.KUV n ,.KUV 1DLGEV=? KVGOU tworzy listę wyświetlającą podane elementy. n XQKF UGV8KUKDNG4QY%QWPV KPV E określa liczbę elementów widocznych jednocześnie na liście (bez przewijania). n XQKF UGV5GNGEVKQP/QFG KPV OQFG określa mo liwość wyboru pojedynczego lub wielu elementów. Parametry: OQFG jedna z wartości 5+0).'A5'.'%6+10 5+0).'A+06'48#.A5'.'%6+10 /7.6+2.'A+06'48#.A5'.'%6+10. n XQKF CFF.KUV5GNGEVKQP.KUVGPGT .KUV5GNGEVKQP.KUVGPGT NKUVGPGT dodaje do listy obiekt nasłuchujący zdarzeń wyboru na liście. n 1DLGEV=? IGV5GNGEVGF8CNWGU zwraca elementy wybrane na liście lub pustą tablicę, jeśli aden element nie został wybrany. n 1DLGEV IGV5GNGEVGF8CNWG zwraca pierwszy element wybrany na liście lub wartość PWNN. LCXCZUYKPIGXGPV.KUV5GNGEVKQP.KUVGPGT n XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV G metoda wywoływana za ka dym razem, gdy wybór na liście uległ zmianie. Modele list W poprzednim podrozdziale pokazaliśmy najczęściej spotykany sposób wykorzystania list polegający na: n utworzeniu niezmiennego zbioru elementów listy (łańcuchów znaków), n umo liwieniu przewijania listy, n obsłudze zdarzeń wyboru elementów listy. W dalszej części przedstawimy bardziej skomplikowane sposoby wykorzystania list, czyli: n listy o bardzo du ej liczbie elementów, n listy o zmiennej zawartości, n listy zawierające elementy inne ni łańcuchy znaków.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 383 W naszym pierwszym przykładzie utworzyliśmy listę zawierającą określony zbiór łańcu- chów znaków. Często jednak zachodzi potrzeba dodawania nowych elementów listy bądź usuwania elementów ju umieszczonych na liście. Zaskakujący mo e wydać się fakt, e klasa ,.KUV nie zawiera metod umo liwiających takie operacje na liście. Aby zrozumieć te- go przyczynę, musimy zapoznać się bli ej z wewnętrzną architekturą komponentu listy. Podobnie jak w przypadku komponentów tekstowych tak e i lista jest przykładem zastoso- wania wzorca model-widok-nadzorca w celu oddzielenia wizualizacji listy (czyli kolumny elementów wyświetlonych w pewien sposób) od danych (kolekcji obiektów). Klasa ,.KUV odpowiedzialna jest jedynie za wizualizację danych i niewiele wie na temat ich reprezentacji. Potrafi jedynie pobrać dane, korzystając z obiektu implementującego interfejs .KUV/QFGN: RWDNKE KPVGTHCEG .KUV/QFGN ] RWDNKE KPV IGV5KG  RWDNKE 1DLGEV IGV'NGOGPV#V KPV K  RWDNKE XQKF CFF.KUV&CVC.KUVGPGT .KUV&CVC.KUVGPGT N  RWDNKE XQKF TGOQXG.KUV&CVC.KUVGPGT .KUV&CVC.KUVGPGT N  _ Wykorzystując ten interfejs, komponent klasy ,.KUV mo e określić liczbę elementów i po- brać ka dy z nich. Mo e tak e dodać się jako obiekt nasłuchujący danych. Dzięki temu bę- dzie powiadamiany o ka dej zmianie w kolekcji elementów i będzie mógł aktualizować re- prezentację list na ekranie. Jaki jest cel takiego rozwiązania? Dlaczego komponent ,.KUV nie przechowuje po prostu swoich elementów za pomocą wektora? Zwróćmy uwagę, e interfejs nie określa sposobu przechowywania obiektów. W szczegól- ności nie wymaga on nawet, by obiekty były przechowywane! Metoda IGV'NGOGPV#V mo e wyznaczać wartość elementu od nowa, za ka dym razem gdy jest wywoływana. Mo e oka- zać się to przydatne, jeśli lista prezentować ma bardzo liczną kolekcję danych, których nie chcemy przechowywać. A oto najprostszy przykład: lista umo liwiać będzie u ytkownikowi wybór spośród wszyst- kich mo liwych kombinacji trzech liter (patrz rysunek 6.2). Rysunek 6.2. Wybór z listy zawierającej dużą liczbę elementów
  • 384 Java 2. Techniki zaawansowane Istnieje 26 ∗ 26 ∗ 26 = 17 576 takich kombinacji. Zamiast przechowywać je wszystkie, program będzie tworzył je podczas przewijania listy przez u ytkownika. Implementacja programu okazuje się bardzo prosta. Zadanie dodania i usuwania odpo- wiednich obiektów nasłuchujących wykona za nas klasa #DUVTCEV.KUV/QFGN, którą roz- szerzymy. Naszym zadaniem będzie jedynie dostarczenie implementacji metod IGV5KG i IGV'NGOGPV#V: ENCUU 9QTF.KUV/QFGN GZVGPFU #DUVTCEV.KUV/QFGN ] RWDNKE 9QTF.KUV/QFGN KPV P ] NGPIVJ  P _ RWDNKE KPV IGV5KG ] TGVWTP KPV /CVJRQY  NGPIVJ  _ RWDNKE 1DLGEV IGV'NGOGPV#V KPV P ]  Y[PCEC PV[ C EWEJ    _    _ Wyznaczenie n-tego łańcucha jest trochę skomplikowane — szczegóły znajdziemy w tek- ście programu umieszczonym w listingu 6.2. Po utworzeniu modelu listy łatwo wykreować taką listę, która pozwoli u ytkownikowi na przeglądanie wartości dostarczanych przez model: YQTF.KUV  PGY ,.KUV PGY 9QTF.KUV/QFGN   YQTF.KUVUGV5GNGEVKQP/QFG .KUV5GNGEVKQP/QFGN5+0).'A5'.'%6+10  ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG YQTF.KUV  Zaletą programu jest to, e prezentowane na liście łańcuchy nie są nigdzie przechowywane. Generowane są jedynie elementy listy widoczne w danym momencie dla u ytkownika. Musimy jeszcze dostarczyć do listy informację, e ka dy z jej elementów posiada stałą sze- rokość i wysokość. YQTF.KUVUGV(KZGF%GNN9KFVJ   YQTF.KUVUGV(KZGF%GNN*GKIJV   W przeciwnym razie lista będzie wyznaczać te wartości dla ka dego elementu, co będzie zbyt czasochłonne. W praktyce listy zawierające tak du ą liczbę elementów są rzadko przydatne, poniewa przeglądanie ich jest kłopotliwe dla u ytkownika. Dlatego te uwa amy, e projektanci list pakietu Swing przesadzili nieco z ich uniwersalnością. Liczba elementów, które u ytkow- nik mo e wygodnie przeglądać na ekranie, jest tak mała, e mogłyby one być przechowy- wane po prostu wewnątrz komponentu listy. Oszczędziłoby to programistom tworzenia modeli list. Z drugiej jednak strony zastosowane rozwiązanie sprawia, e sposób wykorzy- stania komponentu ,.KUV jest spójny ze sposobami u ywania komponentów ,6TGG i ,6CDNG, w przypadku których taka uniwersalność okazuje się przydatna.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 385 Listing 6.2. LongListTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG NKUV[ MVÎTC F[PCOKEPKG Y[PCEC UYQLG GNGOGPV[
  •  RWDNKE ENCUU .QPI.KUV6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY .QPI.KUV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC F WIæ NKUVú U ÎY K GV[MKGVú RQMCWLæEæ FCPKG Q QPG Y[DTCP[EJ U ÎY
  •  ENCUU .QPI.KUV(TCOG GZVGPFU ,(TCOG ] RWDNKE .QPI.KUV(TCOG ] UGV6KVNG .QPI.KUV6GUV  UGV5KG 9+&6* *'+)*6  YQTF.KUV  PGY ,.KUV PGY 9QTF.KUV/QFGN   YQTF.KUVUGV5GNGEVKQP/QFG .KUV5GNGEVKQP/QFGN5+0).'A5'.'%6+10  YQTF.KUVUGV(KZGF%GNN9KFVJ   YQTF.KUVUGV(KZGF%GNN*GKIJV   ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG YQTF.KUV  ,2CPGN R  PGY ,2CPGN  RCFF UETQNN2CPG  YQTF.KUVCFF.KUV5GNGEVKQP.KUVGPGT PGY .KUV5GNGEVKQP.KUVGPGT ] RWDNKE XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV GXV ] 5VTKPI$WHHGT YQTF  5VTKPI$WHHGT YQTF.KUVIGV5GNGEVGF8CNWG  UGV5WDLGEV YQTFVQ5VTKPI  _ _  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF R $QTFGT.C[QWV5176* 
  • 386 Java 2. Techniki zaawansowane NCDGN  PGY ,.CDGN RTGHKZ UWHHKZ  EQPVGPV2CPGCFF NCDGN $QTFGT.C[QWV%'06'4  UGV5WDLGEV HQZ  _ 
  • 1MTG NC RQFOKQV FCPKC RQMC[YCPGIQ C RQOQEæ GV[MKGV[ "RCTCO YQTF PQY[ RQFOKQV FCPKC
  •  RWDNKE XQKF UGV5WDLGEV 5VTKPI YQTF ] 5VTKPI$WHHGT VGZV  PGY 5VTKPI$WHHGT RTGHKZ  VGZVCRRGPF YQTF  VGZVCRRGPF UWHHKZ  NCDGNUGV6GZV VGZVVQ5VTKPI  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   RTKXCVG ,.KUV YQTF.KUV RTKXCVG ,.CDGN NCDGN RTKXCVG 5VTKPI RTGHKZ  6JG SWKEM DTQYP  RTKXCVG 5VTKPI UWHHKZ  LWORU QXGT VJG NC[ FQI  _ 
  • /QFGN NKUV[ F[PCOKEPKG IGPGTWLæE[ MQODKPCELG P NKVGT
  •  ENCUU 9QTF.KUV/QFGN GZVGPFU #DUVTCEV.KUV/QFGN ] 
  • 6YQT[ OQFGN "RCTCO P F WIQ è MQODKPCELK U QYC
  •  RWDNKE 9QTF.KUV/QFGN KPV P ] NGPIVJ  P _ RWDNKE KPV IGV5KG ] TGVWTP KPV /CVJRQY .#56  (+456  NGPIVJ  _ RWDNKE 1DLGEV IGV'NGOGPV#V KPV P ] 5VTKPI$WHHGT T  PGY 5VTKPI$WHHGT  HQT KPV K   K  NGPIVJ K ] EJCT E  EJCT (+456 P .#56  (+456   TKPUGTV  E  P  P  .#56  (+456   _ TGVWTP T _ RTKXCVG KPV NGPIVJ RWDNKE UVCVKE HKPCN EJCT (+456  C  RWDNKE UVCVKE HKPCN EJCT .#56   _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 387 LCXCZUYKPI,.KUV n ,.KUV .KUV/QFGN FCVC/QFGN tworzy listę, która wyświetla elementy dostarczane przez określony model. n XQKF UGV(KZGF%GNN9KFVJ KPV YKFVJ jeśli parametr YKFVJ ma wartość większą od zera, to określa on szerokość ka dej komórki listy. Wartością domyślną jest –1, co wymusza wyznaczenie rozmiarów ka dej komórki z osobna. n XQKF UGV(KZGF%GNN*GKIJV KPV JGKIJV jeśli parametr JGKIJV ma wartość większą od zera, to określa on wysokość ka dej komórki listy. Wartością domyślną jest –1, co wymusza wyznaczenie rozmiarów ka dej komórki z osobna. LCXCZUYKPI.KUV/QFGN n KPV IGV5KG zwraca liczbę elementów w danym modelu. n 1DLGEV IGV'NGOGPV#V KPV KPFGZ zwraca element modelu. Wstawianie i usuwanie Kolekcji elementów listy nie mo emy modyfikować bezpośrednio. Operacje te mo emy wykonywać jedynie za pośrednictwem modelu. Załó my, e chcemy umieścić na liście ko- lejne elementy. Najpierw pobierzemy referencję odpowiedniego modelu: .KUV/QFGN OQFGN  NKUVIGV/QFGN  Jednak interfejs .KUV/QFGN nie zawiera metod umo liwiających wstawianie i usuwanie ele- mentów, poniewa nie wymaga on przechowywania elementów listy. Spróbujmy więc inaczej. Jeden z konstruktorów klasy ,.KUV korzysta z wektora obiektów: 8GEVQT XCNWGU  PGY 8GEVQT  XCNWGUCFF'NGOGPV SWKEM  XCNWGUCFF'NGOGPV DTQYP     ,.KUV NKUV  PGY ,.KUV XCNWGU  Elementy wektora mo emy następnie usuwać lub dodawać, ale oczywiście lista nie zareje- struje tych operacji i wobec tego nie będzie odzwierciedlać zmian w zbiorze elementów. Nie istnieje konstruktor klasy ,.KUV, który posiadałby parametr klasy #TTC[.KUV. Jed- nak już konstrukcja komponentu listy z wykorzystaniem wektora jest rzadko przydatna i wobec tego brak ten nie stanowi istotnego ograniczenia. Rozwiązanie polega na utworzeniu modelu klasy &GHCWNV.KUV/QFGN, wypełnieniu go po- czątkowymi elementami i związaniu z listą. &GHCWNV.KUV/QFGN OQFGN  PGY &GHCWNV.KUV/QFGN  OQFGNCFF'NGOGPV SWKEM  OQFGNCFF'NGOGPV DTQYP     ,.KUV NKUV  PGY ,.KUV OQFGN 
  • 388 Java 2. Techniki zaawansowane Mo emy teraz dodawać i usuwać elementy modelu, który będzie powiadamiać listę o tych zmianach. OQFGNTGOQXG'NGOGPV DTQYP  OQFGNCFF'NGOGPV UNQY  Jak łatwo zauwa yć, klasa &GHCWNV/QFGN.KUV stosuje nazwy metod odmienne ni klasy ko- lekcji. Zastosowany model listy wykorzystuje wektor do przechowania danych. Model ten dzie- dziczy mechanizm powiadamiania listy z klasy #DUVTCEV.KUV/QFGN, podobnie jak nasza kla- sa w poprzednim podrozdziale. Dostępne są konstruktory klasy ,.KUV tworzące listę w oparciu o tablicę lub wektor obiektów. Wydawać się może, że wykorzystują one model &GHCWNV.KUV/QFGN w celu przechowania elementów listy. Nie jest to prawdą. Konstruktory te korzystają z uprosz- czonego modelu, który umożliwia jedynie dostęp do elementów, ale nie posiada me- chanizmu powiadamiania o zmianach. Poniżej prezentujemy kod konstruktora klasy ,.KUV tworzącego listę na podstawie wektora: RWDNKE ,.KUV HKPCN 8GEVQT NKUV&CVC ] VJKU PGY #DUVTCEV.KUV/QFGN ] RWDNKE KPV IGV5KG ] TGVWTP NKUV&CVCUKG  _ RWDNKE 1DLGEV IGV'GNGOGPV#V KPV K ] TGVWTP NKUV&CVCGNGOGPV#V K  _ _  _ Pokazuje on, że jeśli zmienimy zawartość wektora po utworzeniu listy, to pokazywać ona będzie mylącą mieszankę starych i nowych elementów, aż do momentu gdy cała lista zostanie odrysowana. (Słowo kluczowe HKPCN w deklaracji konstruktora nie za- brania wprowadzania zmian zawartości wektora w innych fragmentach kodu. Oznacza ono jedynie, że konstruktor nie modyfikuje referencji NKUV&CVC. Słowo kluczowe HKPCN jest wymagane w tej deklaracji, ponieważ obiekt NKUV&CVC wykorzystywany jest przez klasę wewnętrzną). LCXCZUYKPI,.KUV n .KUV/QFGN IGV/QFGN pobiera model listy. LCXCZUYKPI&GHCWNV.KUV/QFGN n XQKF CFF'NGOGPV 1DLGEV QDL umieszcza obiekt na końcu danych modelu. n DQQNGCP TGOQXG'NGOGPV 1DLGEV QDL usuwa pierwsze wystąpienie obiektu z modelu. Zwraca wartość VTWG, jeśli obiekt został odnaleziony w modelu, wartość HCNUG — w przeciwnym razie.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 389 Odrysowywanie zawartości listy Jak dotąd wszystkie przykłady wykorzystywały listy zawierające łańcuchy znaków. W prak- tyce równie łatwo mo emy utworzyć listę ikon, dostarczając konstruktorowi tablicę lub wek- tor wypełniony obiektami klasy +EQP. W ogóle mo emy reprezentować elementy listy za po- mocą dowolnych rysunków. Klasa ,.KUV automatycznie wyświetla łańcuchy znaków oraz ikony, ale w pozostałych przy- padkach nale y dostarczyć jej obiekt odrysowujący zawartość komórek listy. Obiekt taki musi nale eć do klasy, która implementuje poni szy interfejs: KPVGTHCEG .KUV%GNN4GPFGTGT ] %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV ,.KUV NKUV 1DLGEV XCNWG KPV KPFGZ DQQNGCP KU5GNGEVGF DQQNGCP EGNN*CU(QEWU  _ Jeśli liście dostarczymy taki obiekt, to jego metoda wywoływana będzie dla ka dego ele- mentu listy, aby: n ustalić jego wymiary (w przypadku gdy nie wybraliśmy listy o stałych wymiarach komórek), n narysować go. Obiekt ten musi tworzyć i zwracać obiekt typu %QORQPGPV, którego metody IGV2TGHGTTGF 5KG oraz RCKPV%QORQPGPV wykonają odpowiednie operacje wymagane dla prezentacji ele- mentów listy. Najprostszym sposobem spełnienia tego wymagania jest wykorzystanie klasy wewnętrznej dysponującej tymi metodami: ENCUU /[%GNN4GPFGTGT KORNGOGPVU .KUV%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV HKPCN ,.KUV NKUV HKPCN 1DLGEV XCNWG HKPCN KPV KPFGZ HKPCN DQQNGCP KU5GNGEVGF HKPCN DQQNGCP EGNN*CU(QEWU ] TGVWTP PGY ,2CPGN ] RWDNKE XQKF RCKPV%QORQPGPV )TCRJKEU I ]  MQF T[UWLæE[ GNGOGPV _ RWDNKE &KOGPUKQP IGV2TGHGTTGF5KG ]  MQF Y[PCECLæE[ TQOKCT[ _ _ _ _
  • 390 Java 2. Techniki zaawansowane Program, którego kod źródłowy zawiera listing 6.3, umo liwia wybór czcionki, korzystając z jej rzeczywistego przedstawienia na liście (patrz rysunek 6.3). Metoda RCKPV%QORQPGPV wyświetla nazwę danej czcionki, wykorzystując ją samą. Musi tak e dopasować kolorysty- kę do aktualnego wyglądu klasy ,.KUV. Uzyskujemy ją, posługując się metodami IGV(QTG ITQWPFIGV$CEMITQWPF oraz IGV5GNGEVKQP(QTGITQWPFIGV5GNGEVKQP$CEMITQWPF klasy ,.KUV. Metoda IGV2TGHGTTGF5KG mierzy łańcuch znaków w sposób opisany w ksią ce Java 2. Pod- stawy w rozdziale 7. Rysunek 6.3. Lista o komórkach rysowanych przez program Obiekt rysujący komórki instalujemy za pomocą metody UGV%GNN4GPFGTGT: HQPV.KUVUGV%GNN4GPFGTGT PGY (QPV%GNN4GPFGTGT  Od tego momentu wszystkie komórki listy będą rysowane przez ten obiekt. W wielu przypadkach sprawdza się prostsza metoda tworzenia obiektów rysujących ko- mórki list. Jeśli komórka składa się z tekstu, ikony i zmienia swój kolor, to wszystkie te mo liwości uzyskać mo emy, korzystając z obiektu klasy ,.CDGN. Aby na przykład pokazać nazwę czcionki za jej pomocą, mo emy skorzystać z następującego obiektu: ENCUU (QPV%GNN4GPFGTGT KORNGOGPVU .KUV%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV ,.KUV NKUV 1DLGEV XCNWG KPV KPFGZ DQQNGCP KU5GNGEVGF DQQNGCP EGNN*CU(QEWU ] ,.CDGN NCDGN  PGY ,.CDGN  (QPV HQPV  (QPV XCNWG NCDGNUGV6GZV HQPVIGV(COKN[  NCDGNUGV(QPV HQPV  NCDGNUGV1RCSWG VTWG  NCDGNUGV$CEMITQWPF KU5GNGEVGF ! NKUVIGV5GNGEVKQP$CEMITQWPF  NKUVIGV$CEMITQWPF  NCDGNUGV(QTGITQWPF KU5GNGEVGF ! NKUVIGV5GNGEVKQP(QTGITQWPF  NKUVIGV(QTGITQWPF  TGVWTP NCDGN _ _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 391 Zwróćmy uwagę, e w tym przypadku nie implementujemy wcale metod RCKPV%QORQPGPV oraz IGV2TGHGTTGF5KG. Implementacje tych metod posiada bowiem klasa ,.CDGN. Nasze zadanie polega jedynie na skonfigurowaniu tekstu, czcionki i koloru etykiety klasy ,.CDGN zgodnie z naszymi wymaganiami. Klasa (QPV%GNN4GPFGTGT mo e być nawet klasą pochodną klasy ,.CDGN i sama konfiguro- wać swoje parametry w wywołaniu metody IGV.KUV%GNN4GPFGTGT%QORQPGPV, a następnie zwracać wartość VJKU: ENCUU (QPV%GNN4GPFGTGT GZVGPFU ,.CDGN KORNGOGPVU .KUV%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV ,.KUV NKUV 1DLGEV XCNWG KPV KPFGZ DQQNGCP KU5GNGEVGF DQQNGCP EGNN*CU(QEWU ] (QPV HQPV  (QPV XCNWG UGV6GZV HQPVIGV(COKN[  UGV(QPV HQPV  UGV1RCSWG VTWG  UGV$CEMITQWPF KU5GNGEVGF ! NKUVIGV5GNGEVKQP$CEMITQWPF  NKUVIGV$CEMITQWPF  UGV(QTGITQWPF KU5GNGEVGF ! NKUVIGV5GNGEVKQP(QTGITQWPF  NKUVIGV(QTGITQWPF  TGVWTP VJKU _ _ Kod taki stanowi wygodny skrót w sytuacjach, w których istnieje komponent (,.CDGN w na- szym przypadku) o funkcjonalności wystarczającej do narysowania zawartości komórki listy. Listing 6.3. ListRenderingTest.java KORQTV LCXCWVKN
  •  KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG QDKGMVÎY T[UWLæE[EJ MQOÎTMK NKUV[
  •  RWDNKE ENCUU .KUV4GPFGTKPI6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY .KUV4GPFGTKPI(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC NKUVú EEKQPGM K RQNG VGMUVQYG MVÎTGIQ VGMUV RQMC[YCP[ LGUV Y[DTCPæ NKUV[ EEKQPMæ
  • 392 Java 2. Techniki zaawansowane
  •  ENCUU .KUV4GPFGTKPI(TCOG GZVGPFU ,(TCOG ] RWDNKE .KUV4GPFGTKPI(TCOG ] UGV6KVNG .KUV4GPFGTKPI6GUV  UGV5KG 9+&6* *'+)*6  #TTC[.KUV HQPVU  PGY #TTC[.KUV  HKPCN KPV 5+<'   HQPVUCFF PGY (QPV 5GTKH  (QPV2.#+0 5+<'  HQPVUCFF PGY (QPV 5CPU5GTKH  (QPV2.#+0 5+<'  HQPVUCFF PGY (QPV /QPQURCEGF  (QPV2.#+0 5+<'  HQPVUCFF PGY (QPV &KCNQI  (QPV2.#+0 5+<'  HQPVUCFF PGY (QPV &KCNQI+PRWV  (QPV2.#+0 5+<'  HQPV.KUV  PGY ,.KUV HQPVUVQ#TTC[  HQPV.KUVUGV8KUKDNG4QY%QWPV   HQPV.KUVUGV5GNGEVKQP/QFG .KUV5GNGEVKQP/QFGN5+0).'A5'.'%6+10  HQPV.KUVUGV%GNN4GPFGTGT PGY (QPV%GNN4GPFGTGT  ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG HQPV.KUV  ,2CPGN R  PGY ,2CPGN  RCFF UETQNN2CPG  HQPV.KUVCFF.KUV5GNGEVKQP.KUVGPGT PGY .KUV5GNGEVKQP.KUVGPGT ] RWDNKE XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV GXV ] (QPV HQPV  (QPV HQPV.KUVIGV5GNGEVGF8CNWG  VGZVUGV(QPV HQPV  _ _  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF R $QTFGT.C[QWV5176*  VGZV  PGY ,6GZV#TGC 6JG SWKEM DTQYP HQZ LWORU QXGT VJG NC[ FQI  VGZVUGV(QPV (QPV HQPVUIGV   VGZVUGV.KPG9TCR VTWG  VGZVUGV9TCR5V[NG9QTF VTWG  EQPVGPV2CPGCFF VGZV $QTFGT.C[QWV%'06'4  _ RTKXCVG ,6GZV#TGC VGZV RTKXCVG ,.KUV HQPV.KUV RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • 1DKGMV T[UWLæE[ MQOÎTMK NKUV[ RT[ W [EKW EEKQPMK MVÎTGL PCYú CYKGTC MQOÎTMC
  •  ENCUU (QPV%GNN4GPFGTGT KORNGOGPVU .KUV%GNN4GPFGTGT ]
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 393 RWDNKE %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV HKPCN ,.KUV NKUV HKPCN 1DLGEV XCNWG HKPCN KPV KPFGZ HKPCN DQQNGCP KU5GNGEVGF HKPCN DQQNGCP EGNN*CU(QEWU ] TGVWTP PGY ,2CPGN ] RWDNKE XQKF RCKPV%QORQPGPV )TCRJKEU I ] (QPV HQPV  (QPV XCNWG 5VTKPI VGZV  HQPVIGV(COKN[  (QPV/GVTKEU HO  IIGV(QPV/GVTKEU HQPV  IUGV%QNQT KU5GNGEVGF ! NKUVIGV5GNGEVKQP$CEMITQWPF  NKUVIGV$CEMITQWPF  IHKNN4GEV   IGV9KFVJ  IGV*GKIJV  IUGV%QNQT KU5GNGEVGF ! NKUVIGV5GNGEVKQP(QTGITQWPF  NKUVIGV(QTGITQWPF  IUGV(QPV HQPV  IFTCY5VTKPI VGZV  HOIGV#UEGPV  _ RWDNKE &KOGPUKQP IGV2TGHGTTGF5KG ] (QPV HQPV  (QPV XCNWG 5VTKPI VGZV  HQPVIGV(COKN[  )TCRJKEU I  IGV)TCRJKEU  (QPV/GVTKEU HO  IIGV(QPV/GVTKEU HQPV  TGVWTP PGY &KOGPUKQP HOUVTKPI9KFVJ VGZV  HOIGV*GKIJV  _ _ _ _ LCXCZUYKPI,.KUV n %QNQT IGV$CEMITQWPF zwraca kolor tła komórki listy, która nie jest wybrana. n %QNQT IGV5GNGEVKQP$CEMITQWPF zwraca kolor tła komórki listy, która została wybrana. n XQKF UGV%GNN4GPFGTGT .KUV%GNN4GPFGTGT EGNN4GPFGTGT instaluje obiekt wykorzystywany do rysowania zawartości komórek listy. LCXCZUYKPI.KUV%GNN4GPFGTGT n %QORQPGPV IGV.KUV%GNN4GPFGTGT%QORQPGPV ,.KUV NKUV 1DLGEV KVGO KPV KPFGZ DQQNGCP KU5GNGEVGF DQQNGCP JCU(QEWU zwraca komponent, którego metoda RCKPV rysuje zawartość komórek. Jeśli komórki listy nie posiadają stałych rozmiarów, to komponent ten musi tak e implementować metodę IGV2TGHGTTGF5KG.
  • 394 Java 2. Techniki zaawansowane Parametry: NKUV lista, której komórki mają zostać narysowane, KVGO rysowany element, KPFGZ indeks elementu w modelu, KU5GNGEVGF wartość VTWG, jeśli komórka jest wybrana, JCU(QEWU wartość VTWG, jeśli komórka jest bie ąca. Drzewa Ka dy u ytkownik komputera, którego system operacyjny posiada hierarchicznie zbudo- wany system plików, spotkał się w praktyce z jego reprezentacją za pomocą drzewa, taką jak na przykład na rysunku 6.4. Katalogi i pliki tworzą tylko jedną z wielu mo liwych struktur drzewiastych. Programiści stosują drzewa równie do opisu hierarchii dziedzicze- nia klas. Tak e w yciu codziennym często spotykamy struktury drzewiaste, takie jak hie- rarchie administracyjne państw, stanów, miast itd. (patrz rysunek 6.5). Rysunek 6.4. Drzewo katalogów W programach często trzeba zaprezentować dane w postaci struktury drzewiastej. Biblioteka Swing dostarcza w tym celu klasę ,6TGG. Klasa ,6TGG (wraz z klasami pomocniczymi) słu y do tworzenia reprezentacji graficznej drzewa i przetwarzania akcji u ytkownika polegających na rozwijaniu i zwijaniu węzłów drzewa. W podrozdziale tym nauczymy się korzystać z mo li- wości klasy ,6TGG. Podobnie jak w przypadku innych zło onych komponentów biblioteki Swing, skoncentrujemy się na omówieniu najczęstszych i najbardziej przydatnych przypad- ków zastosowań klasy ,6TGG. Jeśli spotkasz się z nietypowym zastosowaniem drzewa, to po- lecamy ksią kę Core Java Foundation Classes autorstwa Kim Topley (Prentice-Hall, 1998) lub Graphic Java 2 napisaną przez Davida M. Geary’ego (Prentice-Hall, 1999).
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 395 Rysunek 6.5. Hierarchia państw, stanów i miast Zanim przejdziemy do konkretów, warto usystematyzować terminologię związaną z opisem drzew (patrz rysunek 6.6). Drzewo składa się z węzłów. Ka dy węzeł jest albo liściem, albo posiada węzły podrzędne. Ka dy węzeł drzewa z wyjątkiem jego korzenia, posiada dokład- nie jeden węzeł nadrzędny. Ka de drzewo posiada jeden korzeń. Czasami występuje kolek- cja drzew, z których ka de posiada własny korzeń. Nazywamy ją lasem. Rysunek 6.6. Terminologia drzew Najprostsze drzewa Pierwszy przykładowy program wyświetlać będzie drzewo o kilku węzłach (patrz rysunek 6.8). Podobnie jak inne komponenty biblioteki Swing, tak e i klasa ,6TGG jest przykładem zastosowania wzorca model-widok-nadzorca. W praktyce oznacza to, e komponentowi interfejsu u ytkownika musimy dostarczyć model danych. W przypadku klasy ,6TGG będzie to parametr konstruktora: 6TGG/QFGN OQFGN      ,6TGG VTGG  PGY ,6TGG OQFGN  Dostępne są także konstruktory tworzące drzewo na podstawie kolekcji elementów: ,6TGG 1DLGEV=? PQFGU ,6TGG 8GEVQT PQFGU ,6TGG *CUJVCDNG PQFGU  YCTVQ EK VCDNKE[ UVCLæ UKú Yú COK FTGYC
  • 396 Java 2. Techniki zaawansowane Konstruktory te są jednak mało przydatne, gdyż tworzą las drzew, z których każde po- siada jeden węzeł. Ostatni z konstruktorów jest wyjątkowo nieprzydatny, ponieważ wę- zły umieszczane są w drzewie w praktycznie przypadkowy sposób określony przez kody mieszające elementów. Model drzewa tworzymy, definiując klasę implementującą interfejs 6TGG/QFGN. Z mo liwo- ści tej skorzystamy w dalszej części rozdziału, a na początku u yjemy klasy &GHCWNV6TG G/QFGN dostarczanej przez bibliotekę Swing. Kreując model tej klasy, musimy dostarczyć mu korzeń. 6TGG0QFG TQQV      &GHCWNV6TGG/QFGN OQFGN  PGY &GHCWNV6TGG/QFGN TQQV  6TGG0QFG jest kolejnym z interfejsów związanych z drzewami. Drzewo powstaje z węzłów do- wolnych klas implementujących interfejs 6TGG0QFG. Na razie wykorzystamy w tym celu kon- kretną klasę &GHCWNV/WVCDNG6TGG0QFG udostępnianą przez bibliotekę Swing. Klasa ta imple- mentuje interfejs /WVCDNG6TGG0QFG będący specjalizacją interfejsu 6TGG0QFG (patrz rysunek 6.7). Rysunek 6.7. Zależności pomiędzy klasami drzewa Węzeł klasy &GHCWNV/WVCDNG6TGG0QFG przechowuje obiekt zwany obiektem u ytkownika. Drzewo rysuje reprezentację obiektów u ytkownika dla wszystkich węzłów. Dopóki nie zostanie zainstalowany specjalizowany obiekt rysujący węzły, to drzewo wyświetla po pro- stu łańcuch znaków będący wynikiem wywołania metody VQ5VTKPI. Nasz pierwszy przykład wykorzystywać będzie łańcuchy znaków jako obiekty u ytkowni- ka. W praktyce drzewo tworzą zwykle bardziej zło one obiekty, na przykład drzewo repre- zentujące system plików składać się mo e z obiektów klasy (KNG. Obiekt u ytkownika mo emy przekazać jako parametr konstruktora węzła bądź później za pomocą metody UGV7UGT1DLGEV. &GHCWNV/WVCDNG6TGG0QFG PQFG  PGY &GHCWNV/WVCDNG6TGG0QFG 6GZCU PQFGUGV7UGT1DLGEV %CNKHQTPKC 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 397 Następnie musimy utworzyć powiązania pomiędzy węzłami nadrzędnymi i podrzędnymi. Konstrukcję drzewa rozpoczniemy od korzenia, a później dodamy do niego węzły podrzędne: &GHCWNV/WVCDNG6TGG0QFG TQQV  PGY &GHCWNV/WVCDNG6TGG0QFG 9QTNF  &GHCWNV/WVCDNG6TGG0QFG EQWPVT[  PGY &GHCWNV/WVCDNG6TGG0QFG 75#  TQQVCFF EQWPVT[  &GHCWNV/WVCDNG6TGG0QFG UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG %CNKHQTPKC  EQWPVT[CFF UVCVG  Rysunek 6.8 pokazuje drzewo utworzone przez program. Rysunek 6.8. Najprostsze drzewo Po skonstruowaniu i połączeniu wszystkich węzłów mo emy utworzyć model drzewa, prze- kazując mu korzeń, a następnie wykorzystać model do opracowania komponentu ,6TGG. &GHCWNV6TGG/QFGN VTGG/QFGN  PGY &GHCWNV6TGG/QFGN TQQV  ,6TGG  PGY ,6TGG VTGG/QFGN  Mo emy nawet przekazać korzeń bezpośrednio konstruktorowi klasy ,6TGG, który w takim przypadku sam utworzy model drzewa: ,6TGG  PGY ,6TGG TQQV  Listing 6.4 zawiera kompletny tekst źródłowy programu. Listing 6.4. SimpleTree.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVTGG
  •  
  • 2TQITCO Y[ YKGVNCLæE[ PCLRTQUVUG FTGYQ
  •  RWDNKE ENCUU 5KORNG6TGG ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 5KORNG6TGG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _
  • 398 Java 2. Techniki zaawansowane 
  • 4COMC CYKGTCLæEC FTGYQ Y[ YKGVNCLæEG FCPG WOKGUEQPG RTG RTQITCO Y OQFGNW
  •  ENCUU 5KORNG6TGG(TCOG GZVGPFU ,(TCOG ] RWDNKE 5KORNG6TGG(TCOG ] UGV6KVNG 5KORNG6TGG  UGV5KG 9+&6* *'+)*6   DWFWLG OQFGN FTGYC &GHCWNV/WVCDNG6TGG0QFG TQQV  PGY &GHCWNV/WVCDNG6TGG0QFG 9QTNF  &GHCWNV/WVCDNG6TGG0QFG EQWPVT[  PGY &GHCWNV/WVCDNG6TGG0QFG 75#  TQQVCFF EQWPVT[  &GHCWNV/WVCDNG6TGG0QFG UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG %CNKHQTPKC  EQWPVT[CFF UVCVG  &GHCWNV/WVCDNG6TGG0QFG EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG 5CP ,QUG  UVCVGCFF EKV[  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG %WRGTVKPQ  UVCVGCFF EKV[  UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG /KEJKICP  EQWPVT[CFF UVCVG  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG #PP #TDQT  UVCVGCFF EKV[  EQWPVT[  PGY &GHCWNV/WVCDNG6TGG0QFG )GTOCP[  TQQVCFF EQWPVT[  UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG 5EJNGUYKI*QNUVGKP  EQWPVT[CFF UVCVG  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG -KGN  UVCVGCFF EKV[   VYQT[ FTGYQ K WOKGUEC LG Y RTGYKLCNP[O RCPGNW ,6TGG VTGG  PGY ,6TGG TQQV  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF PGY ,5ETQNN2CPG VTGG  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ Po uruchomieniu programu powstanie drzewo, które zobaczymy na rysunku 6.9. Widoczny będzie jedynie korzeń drzewa oraz jego węzły podrzędne. Wybranie myszą uchwytu węzła spowoduje rozwinięcie poddrzewa. Odcinki wystające z ikony uchwytu węzła skierowane są w prawo, gdy poddrzewo jest zwinięte i w dół w przeciwnym razie (patrz rysunek 6.10). Nie wiemy, co mieli na myśli projektanci wyglądu interfejsu zwanego Metal, tworząc ikonę uchwytu węzła, ale nam przypomina ona w działaniu klamkę drzwi. Kierujemy ją w dół, aby rozwinąć poddrzewo.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 399 Rysunek 6.9. Początkowy wygląd drzewa Rysunek 6.10. Zwinięte i rozwinięte poddrzewa Wygląd drzewa zależy od wybranego wyglądu komponentów interfejsu użytkownika. Opisując dotąd drzewo, korzystaliśmy ze standardowego dla aplikacji Java wyglądu in- terfejsu Metal. W przypadku interfejsów Motif lub Windows uchwyty węzłów posiadają postać kwadratów zawierających znaki plus lub minus (patrz rysunek 6.11). Rysunek 6.11. Drzewo o wyglądzie Windows Do wersji SDK 1.3 włącznie linie łączące węzły drzewa domyślnie nie były rysowane (patrz rysunek 6.12). Począwszy od SKD 1.4, rysowane są domyślnie. Rysunek 6.12. Drzewo bez linii łączących węzły Korzystając z SDK 1.4., mo emy wyłączyć rysowanie linii łączących węzły: VTGGRWV%NKGPV2TQRGTV[ ,6TGGNKPG5V[NG  0QPG 
  • 400 Java 2. Techniki zaawansowane lub włączyć je z powrotem: VTGGRWV%NKGPV2TQRGTV[ ,6TGGNKPG5V[NG  #PINGF  Istnieje tak e styl linii *QTKQPVCN pokazany na rysunku 6.13. Poziome linie oddzielają wtedy węzły podrzędne korzenia. Nie jesteśmy przekonani o celowości takiego rozwiązania. Rysunek 6.13. Drzewo wykorzystujące styl linii Horizontal Domyślnie korzeń drzewa nie posiada uchwytu, który umo liwiałby zwinięcie całego drzewa. Mo emy go dodać następująco: VTGGUGV5JQYU4QQV*CPFNGU VTWG  Rysunek 6.14 pokazuje rezultat. Mo emy teraz zwinąć całe drzewo do korzenia. Rysunek 6.14. Drzewo posiadające uchwyt korzenia Mo emy tak e w ogóle usunąć reprezentację korzenia drzewa, uzyskując w ten sposób las drzew, z których ka de posiada własny korzeń. Tworząc taki las, nadal musimy jednak po- łączyć wszystkie drzewa wspólnym korzeniem, który następnie ukrywamy, wywołując VTGGUGV4QQV8KUKDNG HCNUG  Efekt przedstawia rysunek 6.15. Występują na nim dwa korzenie oznaczone „USA” i „Ger- many”. W rzeczywistości są to węzły posiadające wspólny, ukryty korzeń. Rysunek 6.15. Las Zajmijmy się teraz liśćmi drzewa. Zwróćmy uwagę, e ikony liści ró nią się od ikon pozo- stałych węzłów drzewa (patrz rysunek 6.16).
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 401 Rysunek 6.16. Ikony liści Ka dy węzeł drzewa reprezentowany jest za pomocą pewnej ikony. Wyró nić mo na trzy rodzaje takich ikon: ikona liścia, ikona węzła, którego poddrzewo jest rozwinięte i ikona węzła, którego poddrzewo jest zwinięte. Dla uproszczenia dwa ostatnie rodzaje ikon bę- dziemy nazywać wspólnie ikonami folderu. Obiekt rysujący węzły drzewa musi otrzymać informację, jakiej ikony powinien u yć dla da- nego węzła. Domyślny proces decyzyjny przebiega następująco: jeśli metoda KU.GCH zwraca wartość VTWG, to rysowana jest ikona liścia. W przeciwnym razie u ywana jest ikona folderu. Metoda KU.GCH klasy &GHCWNV/WVCDNG6TGG0QFG zwraca wartość VTWG dla ka dego węzła, któ- ry nie posiada węzłów podrzędnych. W ten sposób węzły posiadające węzły podrzędne otrzymują ikonę folderu, a pozostałe węzły — ikonę liścia. Czasami rozwiązanie takie nie jest jednak właściwe. Załó my, e do naszego drzewa doda- liśmy węzeł reprezentujący stan Montana i dopiero zastanawiamy się, jakie miasta powin- niśmy umieścić jako jego węzły podrzędne. Nie chcemy przy tym, aby węzeł reprezentują- cy stan posiadał ikonę liścia, poniewa koncepcyjnie przysługuje ona tylko miastom. Klasa ,6TGG nie wie, które węzły powinny być liśćmi. Decyduje o tym model drzewa. Jeśli węzeł, który nie posiada węzłów podrzędnych, nie jest liściem z punktu widzenia koncepcji drzewa, to model drzewa mo e zastosować inne kryterium rozpoznawania liści. Polega ono na wykorzystaniu właściwości węzła zezwalającej na posiadanie węzłów podrzędnych. Dla węzłów, które nie będą posiadać węzłów podrzędnych, nale y wtedy wywołać: PQFGUGV#NNQYU%JKNFTGP HCNUG  oraz poinformować model drzewa, by, decydując czy danym węzeł jest liściem, sprawdzał, czy mo e on posiadać węzły podrzędne. W tym celu wywołujemy metodę UGV#UMU#NNQYU %JKNFTGP klasy &GHCWNV6TGG/QFGN: OQFGN UGV#UMU#NNQYU%JKNFTGP VTWG  Od tego momentu węzły, które mogą posiadać węzły podrzędne, otrzymują ikonę folderu, a pozostałe ikonę liścia. Takie kryterium doboru ikony mo emy tak e uzyskać, tworząc obiekt klasy ,6TGG za po- mocą odpowiedniego konstruktora: ,6TGG VTGG  PGY ,6TGG TQQV VTWG   Yú [ MVÎTG PKG OQIæ RQUKCFCè Yú ÎY RQFTúFP[EJ QVT[OCLæ KMQPú NK EKC
  • 402 Java 2. Techniki zaawansowane LCXCZUYKPI,6TGG n ,6TGG 6TGG/QFGN OQFGN tworzy drzewo na podstawie modelu. n ,6TGG 6TGG0QFG TQQV n ,6TGG 6TGG0QFG TQQV DQQNGCP CUMU#NNQY%JKNFTGP Tworzą drzewo, korzystając z domyślnego modelu i wyświetlając początkowo korzeń i jego węzły podrzędne. Parametry: TQQV korzeń, CUMU#NNQY%JKNFTGP, jeśli posiada wartość VTWG, to węzeł jest liściem, gdy mo e posiadać węzły podrzędne. n XQKF UGV5JQYU4QQV*CPFNGU DQQNGCP D , jeśli D posiada wartość VTWG, to korzeń posiada uchwyt umo liwiający zwinięcie drzewa. n XQKF UGV4QQV8KUKDNG DQQNGCP D , jeśli D posiada wartość VTWG, to korzeń jest wyświetlany. W przeciwnym razie jest ukryty. LCXCZUYKPIVTGG6TGG0QFG n DQQNGCP KU.GCH zwraca wartość VTWG, jeśli dany węzeł reprezentuje liść na poziomie koncepcji. n DQQNGCP IGV#NNQYU%JKNFTGP zwraca wartość VTWG, jeśli dany węzeł mo e posiadać węzły podrzędne. LCXCZUYKPIVTGG/WVCDNG6TGG0QFG n XQKF UGV7UGT1DLGEV 1DLGEV WUGT1DLGEV określa obiekt u ytkownika dla danego węzła. LCXCZUYKPIVTGG6TGG/QFGN n DQQNGCP KU.GCH 1DLGEV PQFG zwraca wartość VTWG, jeśli węzeł PQFG zostanie wyświetlony jako liść. LCXCZUYKPIVTGG&GHCWNV6TGG/QFGN n XQKF UGV#UMU#NNQYU%JKNFTGP DQQNGCP D , jeśli D posiada wartość VTWG, to węzły wyświetlane są jako liście, w przypadku gdy metoda IGV#NNQYU%JKNFTGP zwraca wartość HCNUG. Gdy D posiada wartość HCNUG, to węzły wyświetlane są jako liście, jeśli metoda KU.GCH zwraca wartość VTWG. LCXCZUYKPIVTGG&GHCWNV/WVCDNG6TGG0QFG n &GHCWNV/WVCDNG6TGG0QFG 1DLGEV WUGT1DLGEV tworzy węzeł drzewa zawierający podany obiekt u ytkownika.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 403 n XQKF CFF /WVCDNG6TGG0QFG EJKNF dodaje do węzła węzeł podrzędny. n XQKF UGV#NNQYU%JKQNFTGP DQQNGCP D , jeśli D posiada wartość VTWG, to do węzła mogą być dodawane węzły podrzędne. LCXCZUYKPI,%QORQPGPV n XQKF RWV%NKGPV2TQRGTV[ 1DLGEV MG[ 1DLGEV XCNWG dodaje parę MG[XCNWG do niewielkiej tablicy, którą zarządza ka dy komponent. Mechanizm ten jest stosowany przez niektóre komponenty Swing w celu przechowywania specyficznych właściwości związanych z wyglądem komponentu. Modyfikacje drzew i ście ki drzew Następny przykład programu ilustrować będzie sposób modyfikacji drzew. Rysunek 6.17 przedstawia potrzebny interfejs u ytkownika. Jeśli wybierzemy przycisk Add Sibling lub Add Child, to program doda do drzewa nowy węzeł opisany jako New. Jeśli wybierzemy przycisk Delete, to usuniemy wybrany węzeł. Rysunek 6.17. Modyfikowanie drzewa Aby zaimplementować takie zachowanie, musimy uzyskać informację o tym, który z wę- złów drzewa jest aktualnie wybrany. Klasa ,6TGG zaskoczy nas z pewnością sposobem identyfikacji węzłów w drzewie. Wykorzystuje ona ście ki do obiektów nazywane ście ka- mi drzewa. Ście ka taka zaczyna się zawsze od korzenia i zawiera sekwencje węzłów pod- rzędnych (patrz rysunek 6.18). Rysunek 6.18. Ścieżka drzewa Zastanawiać mo e, w jakim celu klasa ,6TGG potrzebuje całej ście ki. Czy nie wystarczyłby jej obiekt klasy 6TGG0QFG i mo liwość wywołania metody IGV2CTGPV? Okazuje się, e klasa ,6TGG nie ma pojęcia o istnieniu interfejsu 6TGG0QFG. Nie jest on wykorzystywany przez in- terfejs 6TGG/QFGN, a dopiero przez implementującą go klasę &GHCWNV6TGG/QFGN. Mo emy tworzyć te inne modele drzewa, które nie będą wykorzystywać interfejsu 6TGG0QFG. Więc
  • 404 Java 2. Techniki zaawansowane zdarza się, e obiekty w takim modelu nie będą posiadać metod IGV2CTGPV i IGV%JKNF, ale wykorzystywać będą inny sposób połączeń pomiędzy węzłami. Łączenie węzłów jest zada- niem modelu drzewa. Klasa ,6TGG nie posiada adnej wiedzy na temat natury tych połą- czeń. I to jest właśnie przyczyną, dla której klasa ,6TGG musi wykorzystywać kompletne ście ki drzewa. Klasa 6TGG2CVJ zarządza sekwencją referencji do obiektów klasy 1DLGEV (nie 6TGG0QFG!). Wiele metod klasy ,6TGG zwraca obiekty klasy 6TGG2CVJ. Gdy dysponujemy ju ście ką, to mo emy pobrać węzeł znajdujący się na jej końcu, korzystając z metody IGV.CUVRCVJ%QO RQPGPV. Aby na przykład odnaleźć aktualnie wybrany węzeł drzewa, korzystamy z metody IGV5GNGEVKQP2CVJ klasy ,6TGG. W rezultacie otrzymujemy obiekt klasy 6TGG2CVJ, za pomo- cą którego mo emy z kolei uzyskać aktualnie wybrany węzeł. 6TGG2CVJ UGNGEVKQP2CVJ  VTGGIGV5GNGEVKQP2CVJ  &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG UGNGEVKQP2CVJIGV.CUV2CVJ%QORQPGPV  Poniewa potrzeba taka pojawia się bardzo często, to udostępniono dodatkową metodę, któ- ra natychmiast zwraca wybrany węzeł drzewa. &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG VTGGIGV.CUV5GNGEVGF2CVJ%QORQPGPV  Metody tej nie nazwano IGV5GNGEVGF0QFG, poniewa drzewo nie operuje na węzłach, a je- dynie na ście kach. Ścieżki są jedną z dwu metod wykorzystywanych przez klasę ,6TGG do opisu węzłów. Istnieje kilka metod klasy ,6TGG, które wykorzystują lub zwracają wartość indeksu określającą pozycję wiersza. Jest to po prostu numer wiersza (numeracja rozpoczyna się od 0), w którym znajduje się dany węzeł. Numerowane są jedynie węzły widoczne w danym momencie i w związku z tym numer wiersza danego węzła ulega zmianie pod- czas operacji, takich jak wstawianie, zwijanie i rozwijanie, wykonywanych dla węzłów po- przedzających dany węzeł w drzewie. Dlatego też należy unikać korzystania z numerów węzłów. Wszystkie metody klasy ,6TGG używające numerów węzłów posiadają odpo- wiedniki posługujące się ścieżkami. Po uzyskaniu wybranego węzła mo emy dodać do niego węzły podrzędne, ale nie w poni - szy sposób: UGNGEVGF0QFGCFF PGY0QFG   0+' Zmieniając strukturę węzła, dokonujemy zmiany jedynie modelu, ale jego widok nie uzy- skuje o tym informacji. Mo emy sami wysłać odpowiednie zawiadomienie, ale jeśli sko- rzystamy z metody KPUGTV0QFG+PVQ klasy &CHCWNV6TGG/QFGN, to zrobi to za nas automatycz- nie model drzewa. Na przykład poni sze wywołanie doda nowy węzeł jako ostatni węzeł podrzędny wybranego węzła i powiadomi o tym widok drzewa: OQFGNKPUGTV0QFG+PVQ PGY0QFG UGNGEVGF0QFG UGNGEVGF0QFGIGV%JKNF%QWPV  Natomiast metoda TGOQXG0QFG(TQO2CTGPV usunie węzeł i powiadomi widok drzewa: OQFGNTGOQXG0QFG(TQO2CTGPV UGNGEVGF0QFG 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 405 Jeśli struktura drzewa pozostaje zachowana, a zmienił się jedynie obiekt u ytkownika, wy- starczy wywołać: OQFGNPQFG%JCPIGF EJCPIGF0QFG  Automatyczne powiadamianie widoku drzewa jest główna zaletą korzystania z klasy &G HCWNV6TGG/QFGN. Jeśli utworzymy własny model drzewa, to sami musimy zawiadamiać jego widok o zmianach. (Patrz Core Java Foundation Classes autorstwa Kim Topley). Klasa &GHCWNV6TGG/QFGN posiada metodę TGNQCF, która powoduje przeładowanie mo- delu. Nie należy jednak z niej korzystać w celu aktualizacji widoku drzewa po każdej przeprowadzonej zmianie modelu. Przeładowanie modelu powoduje, że zwijane są wszystkie węzły drzewa z wyjątkiem węzłów podrzędnych korzenia. Użytkownik będzie więc zmuszony rozwijać drzewo po każdej wprowadzonej zmianie. Gdy widok drzewa jest zawiadamiany o zmianie w strukturze węzłów, to aktualizuje odpo- wiednio reprezentację graficzną drzewa. Nie rozwija jednak przy tym automatycznie węzłów, jeśli nowe węzły zostały dodane jako węzły podrzędne do zwiniętego węzła. Szczególnie jeśli u ytkownik doda nowy węzeł do węzła, który jest zwinięty, to nie wywoła adnej zmiany w bie ącej prezentacji drzewa. U ytkownik nie będzie więc wiedzieć, czy nowy węzeł został faktycznie dodany, dopóki sam nie rozwinie odpowiedniego poddrzewa. W takim przypadku program powinien postarać o rozwinięcie odpowiednich węzłów, tak by widoczny był nowo dodany węzeł. W tym celu wykorzystać mo na metodę OCMG8KUKDNG klasy ,6TGG. Jej parame- trem jest ście ka prowadząca do węzła, który powinien być widoczny. Musimy więc skonstruować ście kę prowadzącą od korzenia do nowego węzła. Wywołamy w tym celu metodę IGV2CVJ6Q4QQV klasy &GHCWNV6TGG/QFGN, która zwróci tablicę 6TGG0QFG=? wszystkich węzłów ście ki od danego węzła do korzenia. Tablicę tę przeka emy jako pa- rametr konstruktora klasy 6TGG2CVJ. Poni ej demonstrujemy przykładowy kod rozwijający ście kę do nowego węzła. 6TGG0QFG=? PQFGU  OQFGNIGV2CVJ6Q4QQV PGY0QFG  6TGG2CVJ RCVJ  PGY 6TGG2CVJ PQFGU  VTGGOCMG8KUKDNG RCVJ  Ciekawe, że klasa &GHCWNV6TGG/QFGN ignoruje zupełnie istnienie klasy 6TGG2CVJ, mimo że musi komunikować się z klasą ,6TGG. Klasa ,6TGG wykorzystuje ścieżki, ale nigdy nie używa tablic węzłów. Załó my teraz, e drzewo nasze umieszczone jest wewnątrz przewijalnego panelu. Po do- daniu nowego węzła mo e on nadal nie być widoczny, poniewa znajdzie się poza widocz- nym fragmentem drzewa. Zamiast wywołać metodę OCMG8KUKDNG, wykorzystamy wtedy: VTGGUETQNN2CVJ6Q8KUKDNG RCVJ  Wywołanie to spowoduje nie tylko rozwinięcie węzłów wzdłu ście ki prowadzącej do nowego węzła, ale i takie przewinięcie zawartości panelu, e nowy węzeł będzie widoczny (patrz rysunek 6.19).
  • 406 Java 2. Techniki zaawansowane Rysunek 6.19. Przewinięcie panelu w celu prezentacji nowego węzła Domyślnie węzły drzewa nie mogą być modyfikowane. Jeśli jednak wywołamy: VTGGUGV'FKVCDNG VTWG  to u ytkownik mo e edytować węzły, klikając je dwukrotnie myszą, zmieniając łańcuch opisujący węzeł i zatwierdzając zmianę klawiszem Enter. Dwukrotne kliknięcie węzła my- szą powoduje wywołanie domyślnego edytora komórki implementowanego przez klasę &G HCWNV%GNN'FKVQT (patrz rysunek 6.20). Mo na zainstalować własny edytor, ale temat ten omówimy podczas przedstawiania tabel, w przypadku których zastosowanie edytorów ko- mórek jest bardziej naturalne. Rysunek 6.20. Domyślny edytor komórek Listing 6.5 zawiera kompletny tekst źródłowy programu edycji drzewa. Umo liwia on wsta- wianie węzłów i edytowanie ich. Zwróćmy przy tym uwagę, w jaki sposób rozwijane są wę- zły drzewa i przewijany panel, tak aby mo na było zobaczyć nowe węzły dodane do drzewa. Listing 6.5. TreeEditTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVTGG
  •  
  • 2TQITCO FGOQPUVTWLæE[ GF[ELú FTGYC
  •  RWDNKE ENCUU 6TGG'FKV6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 6TGG'FKV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 407 
  • 4COMC CYKGTCLæEC VT[ RT[EKUMK K GF[VQYCPG FTGYQ
  •  ENCUU 6TGG'FKV(TCOG GZVGPFU ,(TCOG ] RWDNKE 6TGG'FKV(TCOG ] UGV6KVNG 6TGG'FKV6GUV  UGV5KG 9+&6* *'+)*6   VYQT[ FTGYQ 6TGG0QFG TQQV  OCMG5CORNG6TGG  OQFGN  PGY &GHCWNV6TGG/QFGN TQQV  VTGG  PGY ,6TGG OQFGN  VTGGUGV'FKVCDNG VTWG   WOKGUEC FTGYQ Y RTGYKLCNP[O RCPGNW ,5ETQNN2CPG UETQNN2CPG  PGY ,5ETQNN2CPG VTGG  IGV%QPVGPV2CPG CFF UETQNN2CPG $QTFGT.C[QWV%'06'4  OCMG$WVVQPU   VYQT[ RCPGN RT[EKUMÎY _ RWDNKE 6TGG0QFG OCMG5CORNG6TGG ] &GHCWNV/WVCDNG6TGG0QFG TQQV  PGY &GHCWNV/WVCDNG6TGG0QFG 9QTNF  &GHCWNV/WVCDNG6TGG0QFG EQWPVT[  PGY &GHCWNV/WVCDNG6TGG0QFG 75#  TQQVCFF EQWPVT[  &GHCWNV/WVCDNG6TGG0QFG UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG %CNKHQTPKC  EQWPVT[CFF UVCVG  &GHCWNV/WVCDNG6TGG0QFG EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG 5CP ,QUG  UVCVGCFF EKV[  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG %WRGTVKPQ  UVCVGCFF EKV[  UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG /KEJKICP  EQWPVT[CFF UVCVG  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG #PP #TDQT  UVCVGCFF EKV[  EQWPVT[  PGY &GHCWNV/WVCDNG6TGG0QFG )GTOCP[  TQQVCFF EQWPVT[  UVCVG  PGY &GHCWNV/WVCDNG6TGG0QFG 5EJNGUYKI*QNUVGKP  EQWPVT[CFF UVCVG  EKV[  PGY &GHCWNV/WVCDNG6TGG0QFG -KGN  UVCVGCFF EKV[  TGVWTP TQQV _ 
  • 6YQT[ RT[EKUMK WOQ NKYKCLæEG FQFCPKG Yú C UKQUVTCPGIQ FQFCPKG Yú C RQFTúFPGIQ QTC WUWPKúEKG Y[DTCPGIQ Yú C
  • 408 Java 2. Techniki zaawansowane
  •  RWDNKE XQKF OCMG$WVVQPU ] ,2CPGN RCPGN  PGY ,2CPGN  ,$WVVQP CFF5KDNKPI$WVVQP  PGY ,$WVVQP #FF 5KDNKPI  CFF5KDNKPI$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG VTGGIGV.CUV5GNGEVGF2CVJ%QORQPGPV  KH UGNGEVGF0QFG  PWNN TGVWTP &GHCWNV/WVCDNG6TGG0QFG RCTGPV  &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFGIGV2CTGPV  KH RCTGPV  PWNN TGVWTP &GHCWNV/WVCDNG6TGG0QFG PGY0QFG  PGY &GHCWNV/WVCDNG6TGG0QFG 0GY  KPV UGNGEVGF+PFGZ  RCTGPVIGV+PFGZ UGNGEVGF0QFG  OQFGNKPUGTV0QFG+PVQ PGY0QFG RCTGPV UGNGEVGF+PFGZ    Y[ YKGVNC PQY[ YúG 6TGG0QFG=? PQFGU  OQFGNIGV2CVJ6Q4QQV PGY0QFG  6TGG2CVJ RCVJ  PGY 6TGG2CVJ PQFGU  VTGGUETQNN2CVJ6Q8KUKDNG RCVJ  _ _  RCPGNCFF CFF5KDNKPI$WVVQP  ,$WVVQP CFF%JKNF$WVVQP  PGY ,$WVVQP #FF %JKNF  CFF%JKNF$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG VTGGIGV.CUV5GNGEVGF2CVJ%QORQPGPV  KH UGNGEVGF0QFG  PWNN TGVWTP &GHCWNV/WVCDNG6TGG0QFG PGY0QFG  PGY &GHCWNV/WVCDNG6TGG0QFG 0GY  OQFGNKPUGTV0QFG+PVQ PGY0QFG UGNGEVGF0QFG UGNGEVGF0QFGIGV%JKNF%QWPV   Y[ YKGVNC PQY[ YúG 6TGG0QFG=? PQFGU  OQFGNIGV2CVJ6Q4QQV PGY0QFG  6TGG2CVJ RCVJ  PGY 6TGG2CVJ PQFGU 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 409 VTGGUETQNN2CVJ6Q8KUKDNG RCVJ  _ _  RCPGNCFF CFF%JKNF$WVVQP  ,$WVVQP FGNGVG$WVVQP  PGY ,$WVVQP &GNGVG  FGNGVG$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG VTGGIGV.CUV5GNGEVGF2CVJ%QORQPGPV  KH UGNGEVGF0QFG  PWNN UGNGEVGF0QFGIGV2CTGPV  PWNN OQFGNTGOQXG0QFG(TQO2CTGPV UGNGEVGF0QFG  _ _  RCPGNCFF FGNGVG$WVVQP  IGV%QPVGPV2CPG CFF RCPGN $QTFGT.C[QWV5176*  _ RTKXCVG &GHCWNV6TGG/QFGN OQFGN RTKXCVG ,6TGG VTGG RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ LCXCZUYKPI,6TGG n 6TGG2CVJ IGV5GNGEVKQP2CVJ zwraca ście kę do aktualnie wybranego węzła (lub pierwszego wybranego, jeśli wybranych zostało wiele węzłów) bądź wartość PWNN, jeśli aden węzeł nie jest wybrany. n 1DLGEV IGV.CUV5GNGEVGF2CVJ%QORQPGPV zwraca obiekt aktualnie wybranego węzła (lub pierwszego wybranego, jeśli wybranych zostało wiele węzłów) bądź wartość PWNN, jeśli aden węzeł nie jest wybrany. n XQKF OCMG8KUKDNG 6TGG2CVJ RCVJ rozwija wszystkie węzły wzdłu ście ki. n XQKF UETQNN2CVJ6Q8KUKDNG 6TGG2CVJ RCVJ rozwija wszystkie węzły wzdłu ście ki oraz, jeśli drzewo jest umieszczone w panelu przewijalnym, przewija panel, tak by widoczny był ostatni węzeł ście ki. LCXCZUYKPIVTGG6TGG2CVJ n 1DLGEV IGV.CUV2CVJ%QORQPGPV zwraca ostatni obiekt ście ki czyli węzeł, do którego dostęp reprezentuje ście ka.
  • 410 Java 2. Techniki zaawansowane LCXCZUYKPIVTGG6TGG0QFG n 6TGG0QFG IGV2CTGPV zwraca węzeł nadrzędny danego węzła. n 6TGG0QFG IGV%JKNF#V KPV KPFGZ zwraca węzeł podrzędny o danym indeksie. Wartość indeksu musi być z przedziału od 0 do IGV%JKNF%QWPV . n KPV IGV%JKNF%QWPV zwraca liczbę węzłów podrzędnych danego węzła. n 'PWOGTCVKQP EJKNFTGP zwraca obiekt wyliczenia umo liwiający przeglądanie wszystkich węzłów podrzędnych danego węzła. LCXCZUYKPI&GHCWNV6TGG/QFGN n XQKF KPUGTV0QFG+PVQ /WVCDNG6TGG0QFG PGY%JKNF /WVCDNG6TGG0QFG RCTGPV KPV KPFGZ wstawia PGY%JKNF jako nowy węzeł podrzędny węzła RCTGPV o podanym indeksie. n XQKF TGOQXG0QFG(TQO2CTGPV /WVCDNG6TGG0QFG PQFG usuwa węzeł PQFG z modelu. n XQKF PQFG%JCPIGF 6TGG0QFG PQFG zawiadamia obiekty nasłuchujące modelu o modyfikacji węzła PQFG. n XQKF PQFGU%JCPIGF 6TGG0QFG RCTGPV KPV=? EJCPIGF%JKNF+PFGZGU zawiadamia obiekty nasłuchujące modelu, e uległy modyfikacji węzły podrzędne węzła RCTGPV o podanych indeksach. n XQKF TGNQCF ładuje wszystkie węzły do modelu. Operacja ta wykonywana powinna być jedynie, gdy zaszła zasadnicza modyfikacja węzłów spowodowana zewnętrzną przyczyną. Przeglądanie węzłów Często, aby odnaleźć poszukiwany węzeł, musimy przejrzeć wszystkie jego węzły. Klasa &GHCWNV/WVCDNG6TGG0QFG posiada kilka metod przydatnych w tym celu. Metody DTGCFVJ(KTUV'PWOGTCVKQP i FGRVJ(KTUV'PWOGTCVKQP zwracają obiekty wyliczeń, których metoda PGZV'NGOGPV umo liwia przeglądanie wszystkich węzłów podrzędnych bie- ącego węzła, korzystając z metody przeglądania wszerz i w głąb. Rysunek 6.21 pokazuje porządek przeglądania węzłów przykładowego drzewa w obu metodach. Rysunek 6.21. Kolejność przeglądania węzłów drzewa
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 411 Przeglądanie wszerz jest nieco łatwiejsze do wyjaśnienia. Drzewo przeglądane jest war- stwami. Najpierw odwiedzany jest korzeń drzewa, potem jego wszystkie węzły podrzędne, a następnie ich węzły podrzędne itd. W przypadku przeglądania w głąb sposób poruszania się po drzewie przypomina mysz bie- gającą po labiryncie w kształcie drzewa. Porusza się ona wzdłu ście ek drzewa a do na- potkania liścia, po czym wycofuje się i wybiera następną ście kę. Taki sposób przeglądania drzewa nazywany bywa tak e przeglądaniem od końca, poniewa węzły podrzędne są przeglądane przed węzłami nadrzędnymi. Zgodnie z tym nazewnictwem dodano metodę przeszukiwania od końca RQUV1TFGT6TCXGTUCN będącą synonimem metody FGRVJ(KTUV6TCXGTUCN przeszukiwania w głąb. Aby zestaw ten był kompletny, uzupełniono go metodą RTG1TFGT6TCXGTUCN, która przegląda drzewo równie w głąb, ale najpierw węzły nadrzędne, a potem podrzędne. Poni ej typowy przykład u ycia metod przeglądania drzewa: 'PWOGTCVKQP DTGCFVJ(KTUV  PQFGDTGCFVJ(KTUV'PWOGTCVKQP  YJKNG DTGCFVJ(KTUVJCU/QTG'NGOGPVU QRGTCELG PC Yú NG DTGCFVJ(KTUVPGZV'NGOGPV  Z przeglądaniem drzewa związana jest tak e metoda RCVJ(TQO#PEGUVQT'PWOGTCVKQP, która wyznacza ście kę od jednego z przodków węzła do danego węzła i tworzy wyliczenie wę- złów znajdujących się na ście ce. Jej implementacja polega na wywoływaniu metody IGV 2CTGPV do momentu znalezienia przodka, a następnie przejściu ście ki z powrotem. Nasz następny program ma przeglądać drzewo. Będzie on wyświetlał drzewo dziedziczenia klas. Po wprowadzeniu nazwy klasy w polu tekstowym w dolnej części okna klasa ta zo- stanie dodana do drzewa wraz z jej wszystkimi klasami bazowymi (patrz rysunek 6.22). Rysunek 6.22. Drzewo dziedziczenia W przykładzie tym wykorzystamy fakt, e obiekt u ytkownika danego węzła mo e być dowolnego typu. Poniewa węzły naszego drzewa reprezentować będą klasy, umieścimy w nich obiekty klasy %NCUU. Poniewa nie chcemy, by drzewo zawierało wiele wystąpień tej samej klasy, to najpierw będziemy musieli je przeszukać, aby sprawdzić, czy dana klasa ju występuje. Poni sza metoda znajduje węzeł zawierający podany obiekt u ytkownika pod warunkiem, e istnieje on w drzewie.
  • 412 Java 2. Techniki zaawansowane RWDNKE &GHCWNV/WVCDNG6TGG0QFG HKPF7UGT1DLGEV 1DLGEV QDL ] 'PWOGTCVKQP G  TQQVDTGCFVJ(KTUV'PWOGTCVKQP  YJKNG GJCU/QTG'NGOGPVU ] &GHCWNV/WVCDNG6TGG0QFG PQFG  &GHCWNV/WVCDNG6TGG0QFG GPGZV'NGOGPV  KH PQFGIGV7UGT1DLGEV GSWCNU QDL TGVWTP PQFG _ TGVWTP PWNN _ Rysowanie węzłów Specyfika aplikacji często wymaga zmiany sposobu prezentacji drzewa. Najczęściej polega ona na zmianie ikon folderów i liści, zmianie czcionki opisującej węzeł lub zastąpieniu opisu obrazkiem. Wszystkie te zmiany są osiągalne przez zainstalowanie nowego obiektu rysują- cego komórki danego drzewa. Domyślnie klasa ,6TGG wykorzystuje obiekt klasy &GHCWNV 6TGG%GNN4GPFGTGT, która jest klasą pochodną klasy ,.CDGN. Etykieta reprezentowana przez obiekt klasy ,.CDGN składa się w tym przypadku z ikony węzła i jego opisu. Obiekt rysujący komórki drzewa nie jest odpowiedzialny za narysowanie uchwytów wę- złów umożliwiających zwijanie i rozwijanie poddrzew. Uchwyty te są częścią ogólnego wyglądu komponentów interfejsu użytkownika i nie powinny być modyfikowane. Wygląd drzewa zmodyfikować mo emy na trzy ró ne sposoby. 1. Zmieniamy ikony, czcionkę oraz kolor tła wykorzystywany przez obiekt klasy &GHCWNV6TGG%GNN4GPFGTGT. Ustawienia te wykorzystywane będą podczas rysowania wszystkich węzłów drzewa. 2. Instalujemy własny obiekt rysujący komórki drzewa, który nale eć będzie do klasy pochodnej klasy &GHCWNV6TGG%GNN4GPFGTGT. Mo e on zmieniać ikony, czcionkę i kolor tła, rysując poszczególne węzły. 3. Instalujemy własny obiekt rysujący komórki drzewa, który implementować będzie interfejs 6TGG%GNN4GPFGTGT i rysować dowolną reprezentację węzłów drzewa. Przyjrzyjmy się po kolei tym sposobom. Najprostszy z nich wymaga utworzenia obiektu klasy &GHCWNV6TGG%GNN4GPFGTGT, zmiany ikony i zainstalowania obiektu dla danego drzewa: &GHCWNV6TGG%GNN4GPFGTGT TGPFGTGT  PGY &GHCWNV6TGG%GNN4GPFGTGT  TGPFGTGTUGV.GCH+EQP PGY KOCIG+EQP DNWGDCNNIKH   KMQPC NK EK TGPFGTGTUGV%NQUGF+EQP PGY KOCIG+EQP TGFDCNNIKH   KMQPC YKPKúVGIQ Yú C TGPFGTGTUGV1RGP+EQP PGY KOCIG+EQP [GNNQYDCNNIKH   KMQPC TQYKPKúVGIQ Yú C VTGGUGV%GNN4GPFGTGT TGPFGTGT 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 413 Efekt takiego rozwiązania przedstawia rysunek 6.22. Nie zalecamy zmiany czcionki bądź koloru tła dla całego drzewa, poniewa to jest zada- niem wyglądu komponentów interfejsu u ytkownika. Mo emy jednak zmieniać czcionkę pojedynczych węzłów drzewa dla ich wyró nienia. Jeśli przyjrzymy się uwa nie rysunkowi 6.22, to zauwa ymy, e nazwy klas abstrakcyjnych pi- sane są kursywą. Aby zmieniać wygląd poszczególnych węzłów, musimy zainstalować własny obiekt rysujący komórki drzewa. Przypomina on obiekty rysujące komórki list, które omówiliśmy w 9. roz- dziale ksią ki Java 2. Podstawy. Interfejs 6TGG%GNN4GPFGTGT posiada pojedynczą metodę: %QORQPGPV IGV6TGG%GNN4GPFGTGT%QORQPGPV ,6TGG VTGG 1DLGEV XCNWG DQQNGCP UGNGEVGF DQQNGCP GZRCPFGF DQQNGCP NGCH KPV TQY DQQNGCP JCU(QEWU Metoda ta wywoływana jest dla ka dego węzła. Zwraca ona komponent, którego metoda RCKPV rysuje reprezentację węzła drzewa. Metodzie RCKPV przekazywany jest odpowiedni obiekt )TCRJKEU, który zawiera informację o współrzędnych umo liwiającą narysowanie reprezentacji węzła we właściwym miejscu drzewa. Zastanawiać może, dlaczego nie wystarczy po prostu umieścić metody RCKPV w klasie implementującej interfejs 6TGG%GNN4GPFGTGT. Przyczyna tego jest bardzo prozaiczna. Często łatwiej wykorzystać dla prezentacji węzłów drzewa istniejące już komponenty in- terfejsu, niż programować metodę RCKPV od podstaw. Z metody tej skorzystali także projektanci biblioteki Swing, ponieważ domyślny obiekt rysujący komórki drzewa sta- nowi rozszerzenie komponentu ,.CDGN, który zapewnia odpowiednie rozmieszczenie ikony i tekstu. Metoda IGV6TGG%GNN4GPFGTGT%QORQPGPV klasy &GHCWNV6TGG%GNN4GPFGTGT zwraca po prostu wartość VJKU, czyli innymi słowy komponent etykiety. (Przypomnijmy, e klasa &GHCWNV 6TGG%GNN4GPFGTGT jest pochodną klasy ,.CDGN). Aby zmodyfikować komponent, musimy sami utworzyć klasę pochodną klasy &GHCWNV6TGG%GNN4GPFGTGT i zastąpić jej metodę IGV 6TGG%GNN4GPFGTGT%QORQPGPV implementacją, która: n wywoła metodę klasy nadrzędnej w celu przygotowania danych komponentu etykiety, n zmodyfikuje właściwości etykiety, n zwróci VJKU. ENCUU %NCUU0COG6TGG%GNN4GPFGTGT GZVGPFU &GHCWNV6TGG%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV6TGG%GNN4GPFGTGT%QORQPGPV ,6TGG VTGG 1DLGEV XCNWG DQQNGCP UGNGEVGF DQQNGCP GZRCPFGF DQQNGCP NGCH KPV TQY DQQNGCP JCU(QEWU ] UWRGTIGV6TGG%GNN4GPFGTGT%QORQPGPV VTGG XCNWG UGNGEVGF GZRCPFGF NGCH TQY JCU(QEWU  &GHCWNV/WVCDNG6TGG0QFG PQFG  &GHCWNV/WVCDNG6TGG0QFG XCNWG URTCYF PQFGIGV7UGT1DLGEV 
  • 414 Java 2. Techniki zaawansowane (QPV HQPV  QFRQYKGFPKC EEKQPMC  UGV(QPV RNCKP(QPV  TGVWTP VJKU _ Parametr XCNWG metody IGV6TGG%GNN4GPFGTGT%QORQPGPV nie jest obiektem użytkownika, ale obiektem reprezentującym węzeł! Przypomnijmy w tym miejscu, że obiekty użyt- kownika wykorzystywane są przez klasę &GHCWNV/WVCDNG6TGG0QFG, natomiast klasa ,6TGG może zawierać węzły dowolnego typu. Jeśli drzewo składa się z węzłów klasy &GHCWNV/WVCDNG6TGG0QFG, to obiekt użytkownika możemy pobrać z nich dopiero, wywo- łując metodę IGV7UGT1DLGEV, tak jak uczyniliśmy to w powyższym przykładzie. Obiekt klasy &GHCWNV6TGG%GNN4GPFGTGT wykorzystuje ten sam obiekt klasy ,.CDGN dla wszystkich węzłów, zmieniając jedynie tekst etykiety. Jeśli więc dokonamy zmiany czcionki dla danego węzła, to musimy przywrócić czcionkę domyślną, gdy metoda zo- stanie wywołana po raz kolejny. W przeciwnym razie wszystkie kolejne węzły zostaną opisane zmienioną czcionką! Kod programu w listingu 6.6 pokazuje sposób przywró- cenia domyślnej czcionki. Nie będziemy pokazywać osobnego przykładu obiektu rysującego komórkę drzewa dowol- nej postaci. Sposób jego działania jest analogiczny do pracy obiektu rysującego komórki li- sty przedstawionego na początku tego rozdziału. Zaprzęgnijmy zatem do pracy obiekty rysujące komórki drzewa. Listing 6.6 zawiera tekst źródłowy programu tworzącego drzewo klas. Program prezentuje drzewo dziedziczenia klas, wyró niając klasy abstrakcyjne kursywą. W polu tekstowym w dolnej części okna programu u ytkownik mo e wpisać nazwę dowolnej klasy, a następnie wybrać klawisz Enter lub przycisk Add, aby dodać klasę i jej klasy bazowe do drzewa. Nale y podać wy- łącznie pełną nazwę klasy, czyli na przykład LCXCWVKN#TTC[.KUV. Działanie programu jest trochę skomplikowane, poniewa wykorzystuje on przy tworzeniu drzewa refleksję klas, co odbywa się wewnątrz metody CFF%NCUU. (Szczegóły nie są w tym przypadku istotne. Przykładowy program tworzy akurat drzewo klas, poniewa drzewo dziedziczenia jest dobrym przykładem struktury drzewiastej. Zwykle programy reprezen- tują jednak za pomocą drzewa inne struktury danych). Metoda CFF%NCUU wywołuje metodę HKPF7UGT1DLGEV, aby sprawdzić, czy klasa znajduje się ju w drzewie. Metoda HKPF7UGT1D LGEV przegląda drzewo wszerz. Jeśli klasa nie znajduje się jeszcze w drzewie, to program dodaje najpierw do drzewa jej klasy bazowe, a na końcu daną klasę i troszczy się o to, by jej węzeł był widoczny. Obiekt klasy %NCUU0COG6TGG%GNN4GPFGTGT prezentuje nazwę klasy czcionką prostą lub pochyłą w zale ności od modyfikatora #$564#%6 obiektu klasy %NCUU. Program korzysta z czcionki, którą dla reprezentacji etykiet drzewa przewidział bie ący wygląd komponentów i tworzy na jej podstawie wersję pochyłą. Poniewa wszystkie wywołania zwracają ten sam obiekt klasy ,.CDGN, to kolejne wywołanie metody IGV6TGG%GNN4GPFGTGT%QORQPGPV musi odtwo- rzyć oryginalną czcionkę, jeśli wcześniej u yta była jej wersja pochyła. Konstruktor klasy %NCUU6TGG(TCOG zmienia dodatkowo ikony reprezentujące węzły drzewa.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 415 Listing 6.6. ClassTree.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCNCPITGHNGEV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  KORQTV LCXCZUYKPIVTGG
  •  
  • 2TQITCO FGOQPUVTWLæE[ URQUÎD T[UQYCPKC MQOÎTGM FTGYC PC RT[M CFKG FTGYC MNCU K KEJ MNCU DCQY[EJ
  •  RWDNKE ENCUU %NCUU6TGG ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY %NCUU6TGG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC FTGYQ MNCU QTC RQNG VGMUVQYG K RT[EKUM WOQ NKYKCLæEG FQFCYCPKG MNCU FQ FTGYC
  •  ENCUU %NCUU6TGG(TCOG GZVGPFU ,(TCOG ] RWDNKE %NCUU6TGG(TCOG ] UGV6KVNG %NCUU6TGG  UGV5KG 9+&6* *'+)*6   MQTGPKGO FTGYC LGUV MNCUC 1DLGEV TQQV  PGY &GHCWNV/WVCDNG6TGG0QFG LCXCNCPI1DLGEVENCUU  OQFGN  PGY &GHCWNV6TGG/QFGN TQQV  VTGG  PGY ,6TGG OQFGN   FQFCLG MNCUú FQ FTGYC CFF%NCUU IGV%NCUU   VYQT[ KMQP[ Yú ÎY %NCUU0COG6TGG%GNN4GPFGTGT TGPFGTGT  PGY %NCUU0COG6TGG%GNN4GPFGTGT  TGPFGTGTUGV%NQUGF+EQP PGY +OCIG+EQP TGFDCNNIKH  TGPFGTGTUGV1RGP+EQP PGY +OCIG+EQP [GNNQYDCNNIKH  TGPFGTGTUGV.GCH+EQP PGY +OCIG+EQP DNWGDCNNIKH  VTGGUGV%GNN4GPFGTGT TGPFGTGT  IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VTGG  $QTFGT.C[QWV%'06'4  CFF6GZV(KGNF  _
  • 416 Java 2. Techniki zaawansowane 
  • &QFCLG RQNG VGMUVQYG K RT[EKUM
  •  RWDNKE XQKF CFF6GZV(KGNF ] ,2CPGN RCPGN  PGY ,2CPGN  #EVKQP.KUVGPGT CFF.KUVGPGT  PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ]  FQFCLG FQ FTGYC MNCUú MVÎTGL PCYC PCLFWLG UKú  Y RQNW VGMUVQY[O VT[ ] 5VTKPI VGZV  VGZV(KGNFIGV6GZV  CFF%NCUU %NCUUHQT0COG VGZV   WUWYC VGMUV RQNC VGMUVQYGIQ VGZV(KGNFUGV6GZV  _ ECVEJ %NCUU0QV(QWPF'ZEGRVKQP G ] ,1RVKQP2CPGUJQY/GUUCIG&KCNQI PWNN %NCUU PQV HQWPF  _ _ _  VYQT[ RQNG VGMUVQYG VGZV(KGNF  PGY ,6GZV(KGNF   VGZV(KGNFCFF#EVKQP.KUVGPGT CFF.KUVGPGT  RCPGNCFF VGZV(KGNF  ,$WVVQP CFF$WVVQP  PGY ,$WVVQP #FF  CFF$WVVQPCFF#EVKQP.KUVGPGT CFF.KUVGPGT  RCPGNCFF CFF$WVVQP  IGV%QPVGPV2CPG CFF RCPGN $QTFGT.C[QWV5176*  _ 
  • <PCLFWLG QDKGMV Y FTGYKG "RCTCO QDL UWMCP[ QDKGMV "TGVWTP YúG CYKGTCLæE[ QDKGMV NWD PWNN LG NK QDKGMVW PKG OC Y FTGYKG
  •  RWDNKE &GHCWNV/WVCDNG6TGG0QFG HKPF7UGT1DLGEV 1DLGEV QDL ]  PCLFWLG YúG CYKGTCLæE[ FCP[ QDKGMV W [VMQYPKMC 'PWOGTCVKQP G  TQQVDTGCFVJ(KTUV'PWOGTCVKQP  YJKNG GJCU/QTG'NGOGPVU ] &GHCWNV/WVCDNG6TGG0QFG PQFG  &GHCWNV/WVCDNG6TGG0QFG GPGZV'NGOGPV  KH PQFGIGV7UGT1DLGEV GSWCNU QDL TGVWTP PQFG _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 417 TGVWTP PWNN _ 
  • &QFCLG FQ FTGYC MNCUú K LGL MNCU[ DCQYG MVÎT[EJ PKG OC LGUEG Y FTGYKG "RCTCO E FQFCYCPC MNCU "TGVWTP PQYQ FQFCP[ YúG 
  •  RWDNKE &GHCWNV/WVCDNG6TGG0QFG CFF%NCUU %NCUU E ]  FQFCLG MNCUú FQ FTGYC  RQOKLC V[R[ MVÎTG PKG Uæ MNCUCOK KH EKU+PVGTHCEG ^^ EKU2TKOKVKXG TGVWTP PWNN  LG NK MNCUC PCLFWLG UKú LW Y FTGYKG VQ YTCEC LGL YúG &GHCWNV/WVCDNG6TGG0QFG PQFG  HKPF7UGT1DLGEV E  KH PQFG  PWNN TGVWTP PQFG  MNCUC PKG PCLFWLG UKú Y FTGYKG  PCLRKGTY PCNG [ FQFCè FQ FTGYC LGL MNCU[ DCQYG %NCUU U  EIGV5WRGTENCUU  &GHCWNV/WVCDNG6TGG0QFG RCTGPV KH U  PWNN RCTGPV  TQQV GNUG RCTGPV  CFF%NCUU U   FQFCLG MNCUú LCMQ YúG RQFTúFP[ &GHCWNV/WVCDNG6TGG0QFG PGY0QFG  PGY &GHCWNV/WVCDNG6TGG0QFG E  OQFGNKPUGTV0QFG+PVQ PGY0QFG RCTGPV RCTGPVIGV%JKNF%QWPV   URTCYKC G YúG LGUV YKFQEP[ 6TGG2CVJ RCVJ  PGY 6TGG2CVJ OQFGNIGV2CVJ6Q4QQV PGY0QFG  VTGGOCMG8KUKDNG RCVJ  TGVWTP PGY0QFG _ RTKXCVG &GHCWNV/WVCDNG6TGG0QFG TQQV RTKXCVG &GHCWNV6TGG/QFGN OQFGN RTKXCVG ,6TGG VTGG RTKXCVG ,6GZV(KGNF VGZV(KGNF RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • -NCUC QRKUWLæEC Yú [ FTGYC EEKQPMæ Y[M æ NWD RQEJ[NQPæ Y RT[RCFMW MNCU CDUVTCME[LP[EJ 
  •  ENCUU %NCUU0COG6TGG%GNN4GPFGTGT GZVGPFU &GHCWNV6TGG%GNN4GPFGTGT
  • 418 Java 2. Techniki zaawansowane ] RWDNKE %QORQPGPV IGV6TGG%GNN4GPFGTGT%QORQPGPV ,6TGG VTGG 1DLGEV XCNWG DQQNGCP UGNGEVGF DQQNGCP GZRCPFGF DQQNGCP NGCH KPV TQY DQQNGCP JCU(QEWU ] UWRGTIGV6TGG%GNN4GPFGTGT%QORQPGPV VTGG XCNWG UGNGEVGF GZRCPFGF NGCH TQY JCU(QEWU   RQDKGTC QDKGMV W [VMQYPKMC &GHCWNV/WVCDNG6TGG0QFG PQFG  &GHCWNV/WVCDNG6TGG0QFG XCNWG %NCUU E  %NCUU PQFGIGV7UGT1DLGEV   RT[ RKGTYU[O W [EKW VYQT[ EEKQPMú  RQEJ[ æ QFRQYKCFCLæEæ FCPGL EEKQPEG RTQUVGL KH RNCKP(QPV  PWNN ] RNCKP(QPV  IGV(QPV  
  • QDKGMV T[UWLæE[ MQOÎTMú FTGYC Y[YQ [YCP[ LGUV ECUCOK FNC GV[MKGV[ MVÎTC PKG RQUKCFC QMTG NQPGL EEKQPMK PWNN 
  •  KH RNCKP(QPV  PWNN KVCNKE(QPV  RNCKP(QPVFGTKXG(QPV (QPV+6#.+%  _  WUVCYKC EEKQPMú RQEJ[ æ LG NK MNCUC LGUV CDUVTCME[LPC KH EIGV/QFKHKGTU /QFKHKGT#$564#%6   UGV(QPV RNCKP(QPV  GNUG UGV(QPV KVCNKE(QPV  TGVWTP VJKU _ RTKXCVG (QPV RNCKP(QPV  PWNN RTKXCVG (QPV KVCNKE(QPV  PWNN _ LCXCZUYKPIVTGG&GHCWNV/WVCDNG6TGG0QFG n 'PWOGTCVKQP DTGCFVJ(KTUV'PWOGTCVKQP n 'PWOGTCVKQP FGRVJ(KTUV'PWOGTCVKQP n 'PWOGTCVKQP RTG1TFGT'PWOGTCVKQP n 'PWOGTCVKQP RQUV1TFGT'PWOGTCVKQP Zwracają obiekt wyliczenia umo liwiający przeglądanie wszystkich węzłów drzewa w odpowiednim porządku: wszerz, gdzie węzły podrzędne le ące bli ej korzenia odwiedzane są wcześniej, w głąb, gdzie wszystkie węzły podrzędne danego węzła są odwiedzane, zanim odwiedzone zostaną jego węzły siostrzane. Metoda RQUV1TFGT'PWOGTCVKQP stanowi synonim metody FGRVJ(KTUV'PWOGTCVKQP. Metoda RTG1TFGT'PWOGTCVKQP przegląda drzewo podobnie do niej, z tą ró nicą, e węzły nadrzędne przeglądane są przed ich węzłami podrzędnymi.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 419 LCXCZUYKPIVTGG6TGG%GNN4GPFGTGT n %QORQPGPV IGV6TGG%GNN4GPFGTGT%QORQPGPV ,6TGG VTGG 1DLGEV XCNWG DQQNGCP UGNGEVGF DQQNGCP GZRCPFGF DQQNGCP NGCH KPV TQY DQQNGCP JCU(QEWU zwraca komponent, którego metoda RCKPV wywoływana jest w celu narysowania komórki drzewa. Parametry: VTGG drzewo, do którego nale y rysowana komórka, XCNWG rysowany węzeł, UGNGEVGF wartość VTWG, jeśli węzeł jest wybrany, GZRCPFGF wartość VTWG, jeśli węzły podrzędne danego węzła są widoczne, NGCH wartość VTWG, jeśli węzeł jest liściem, TQY numer wiersza graficznej reprezentacji drzewa zawierającej węzeł, JCU(QEWU wartość VTWG, jeśli węzeł jest przeglądany w danym momencie przez u ytkownika. LCXCZUYKPIVTGG&GHCWNV6TGG%GNN4GPFGTGT n XQKF UGV.GCH+EQP +EQP KEQP n XQKF UGV1RGP+EQP +EQP KEQP n XQKF UGV%NQUGF+EQP +EQP KEQP Ustalają ikonę prezentującą odpowiednio: liść, węzeł rozwinięty, węzeł zwinięty. Nasłuchiwanie zdarzeń w drzewach Najczęściej komponent drzewa wykorzystywany jest razem z innym komponentem inter- fejsu u ytkownika. Gdy u ytkownik wybiera węzły drzewa, to inny komponent pokazuje pewną informację o nich, tak jak na przykład program przedstawiony na rysunku 6.23. Kiedy u ytkownik wybiera węzeł drzewa reprezentujący klasę języka Java, to w polu tek- stowym obok prezentowana jest informacja o jej zmiennych. Rysunek 6.23. Przeglądarka klas
  • 420 Java 2. Techniki zaawansowane Aby uzyskać takie działanie programu, konieczne jest zainstalowanie obiektu nasłuchują- cego wyboru w drzewie. Obiekt ten musi implementować interfejs 6TGG5GNGEVKQP.KUVGPGT, który posiada tylko jedną metodę: XQKF XCNWG%JCPIGF 6TGG5GNGEVKQP'XGPV GXGPV Jest ona wywoływana za ka dym razem, gdy węzeł drzewa zostaje wybrany lub przestaje być wybrany. Obiekt nasłuchujący dodajemy do drzewa w zwykły sposób: VTGGCFF5GNGEVKQP.KUVGPGT NKUVGPGT  Mo emy określić sposób wyboru węzłów drzewa przez u ytkownika. Wybrany mo e być tylko jeden węzeł, ciągły zakres węzłów lub dowolny, potencjalnie nieciągły zbiór węzłów. Klasa ,6TGG wykorzystuje klasę 6TGG5GNGEVKQP/QFGN do zarządzania wyborem węzłów. Dla modelu, który musimy najpierw pobrać, określić mo emy jeden z następujących stanów wyboru: 5+0).'A 64''A5'.'%6+10, %106+)7175A64''A5'.'%6+10 lub &+5%106+)7175A64''A5'.'%6+10 (ten ostatni jest stanem domyślnym). Nasza przeglądarka umo liwiać będzie wybór pojedynczej klasy: KPV OQFG  6TGG5GNGEVKQP/QFGN5+0).'A64''A5'.'%6+10 VTGGIGV5GNGEVKQP/QFGN UGV5GNGEVKQP/QFG OQFG  Po określeniu sposobu wyboru na drzewie nie musimy więcej zajmować się modelem wyboru. Sposób wyboru wielu węzłów drzewa zależy od bieżącego wyglądu komponentów inter- fejsu użytkownika. W przypadku wyglądu Metal wystarczy przytrzymać klawisz Ctrl pod- czas kliknięcia myszą, aby dokonać wyboru kolejnego węzła lub usunąć jego wybór, je- śli wcześniej był już wybrany. Podobnie przytrzymanie klawisza Shift umożliwia wybranie zakresu węzłów. Aby uzyskać informacje o tym, które z węzłów zostały wybrane, wywołujemy metodę IGV 5GNGEVKQP2CVJU: 6TGG2CVJ=? UGNGEVGF2CVJU  VTGGIGV5GNGEVKQP2CVJU  W przypadku gdy mo liwość wyboru ograniczyliśmy do jednego węzła, mo emy skorzy- stać z metody IGV5GNGEVKQP2CVJ, która zwróci ście kę do pierwszego wybranego węzła lub wartość PWNN, jeśli aden węzeł nie został wybrany. Klasa 6TGG5GNGEVKQP'XGPV dysponuje metodą IGV2CVJU, która zwraca tablicę obiek- tów klasy 6TGG2CVJ reprezentujących zmiany wyboru, a nie aktualnie wybrane węzły. Program, którego kod źródłowy zawiera listing 6.7, wykorzystuje mechanizm wyboru węzła drzewa. Program ten stanowi rozbudowaną wersję programu z listingu 6.6. Jednak aby uczy- nić jego tekst źródłowy mo liwie krótkim, zrezygnowaliśmy tym razem z u ycia własnego obiektu rysującego komórki drzewa. W kodzie konstruktora ramki ograniczamy mo liwość wyboru do jednego węzła i dodajemy do drzewa obiekt nasłuchujący wyboru. Gdy wywołana zostaje jego metoda XCNWG%JCPIGF, ignorujemy jej parametr i korzystamy z metody IGV5GNGE VKQP2CVJ. Pobieramy ostatni węzeł uzyskanej ście ki i zawarty w nim obiekt u ytkownika. Następnie wywołujemy metodę IGV(KGNF&GUETKRVKQP, która korzysta z mechanizmu refleksji, aby utworzyć łańcuch znaków opisujący wszystkie składowe danej klasy. Otrzymany łańcuch znaków wyświetlamy w polu tekstowym okna.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 421 Listing 6.7. ClassBrowserTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCNCPITGHNGEV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  KORQTV LCXCZUYKPIVTGG
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[DÎT Yú C FTGYC
  •  RWDNKE ENCUU %NCUU$TQYUGT6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY %NCUU$TQYUGT6GUV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC FTGYQ MNCU RQNG VGMUVQYG RQMCWLæEG UM CFQYG Y[DTCPGL MNCU[ QTC RQNG VGMUVQYG WOQ NKYKCLæEG FQFCYCPKG PQY[EJ MNCU FQ FTGYC
  •  ENCUU %NCUU$TQYUGT6GUV(TCOG GZVGPFU ,(TCOG ] RWDNKE %NCUU$TQYUGT6GUV(TCOG ] UGV6KVNG %NCUU$TQYUGT6GUV  UGV5KG 9+&6* *'+)*6   Y MQTGPKW FTGYC PCLFWLG UKú MNCUC 1DLGEV TQQV  PGY &GHCWNV/WVCDNG6TGG0QFG LCXCNCPI1DLGEVENCUU  OQFGN  PGY &GHCWNV6TGG/QFGN TQQV  VTGG  PGY ,6TGG OQFGN   FQFCLG MNCUú FQ FTGYC CFF%NCUU IGV%NCUU   UGV WR UGNGEVKQP OQFG VTGGCFF6TGG5GNGEVKQP.KUVGPGT PGY 6TGG5GNGEVKQP.KUVGPGT ] RWDNKE XQKF XCNWG%JCPIGF 6TGG5GNGEVKQP'XGPV GXGPV ]  W [VMQYPKM Y[DTC KPP[ YúG FTGYC  K PCNG [ CMVWCNKQYCè QRKU MNCU[ 6TGG2CVJ RCVJ  VTGGIGV5GNGEVKQP2CVJ  KH RCVJ  PWNN TGVWTP &GHCWNV/WVCDNG6TGG0QFG UGNGEVGF0QFG  &GHCWNV/WVCDNG6TGG0QFG RCVJIGV.CUV2CVJ%QORQPGPV 
  • 422 Java 2. Techniki zaawansowane %NCUU E  %NCUU UGNGEVGF0QFGIGV7UGT1DLGEV  5VTKPI FGUETKRVKQP  IGV(KGNF&GUETKRVKQP E  VGZV#TGCUGV6GZV FGUETKRVKQP  _ _  KPV OQFG  6TGG5GNGEVKQP/QFGN5+0).'A64''A5'.'%6+10 VTGGIGV5GNGEVKQP/QFGN UGV5GNGEVKQP/QFG OQFG   RQNG VGMUVQYG CYKGTCLæEG QRKU MNCU[ VGZV#TGC  PGY ,6GZV#TGC   FQFCLG MQORQPGPV[ FTGYC K RQNC VGMUVQYGIQ FQ RCPGNW ,2CPGN RCPGN  PGY ,2CPGN  RCPGNUGV.C[QWV PGY )TKF.C[QWV    RCPGNCFF PGY ,5ETQNN2CPG VTGG  RCPGNCFF PGY ,5ETQNN2CPG VGZV#TGC  IGV%QPVGPV2CPG CFF RCPGN $QTFGT.C[QWV%'06'4  CFF6GZV(KGNF  _ 
  • &QFCLG RQNG VGMUVQYG K RT[EKUM #FF WOQ NKYKCLæEG FQFCPKG PQYGL MNCU[ FQ FTGYC
  •  RWDNKE XQKF CFF6GZV(KGNF ] ,2CPGN RCPGN  PGY ,2CPGN  #EVKQP.KUVGPGT CFF.KUVGPGT  PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ]  FQFCLG FQ FTGYC MNCUú MVÎTGL PCYC  PCLFWLG UKú Y RQNW VGMUVQY[O VT[ ] 5VTKPI VGZV  VGZV(KGNFIGV6GZV  CFF%NCUU %NCUUHQT0COG VGZV   ENGCT VGZV HKGNF VQ KPFKECVG UWEEGUU VGZV(KGNFUGV6GZV  _ ECVEJ %NCUU0QV(QWPF'ZEGRVKQP G ] ,1RVKQP2CPGUJQY/GUUCIG&KCNQI PWNN %NCUU PQV HQWPF  _ _ _  RQNG VGMUVQYG Y MVÎT[O YRTQYCFCPG Uæ PCY[ PQY[EJ MNCU VGZV(KGNF  PGY ,6GZV(KGNF   VGZV(KGNFCFF#EVKQP.KUVGPGT CFF.KUVGPGT  RCPGNCFF VGZV(KGNF 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 423 ,$WVVQP CFF$WVVQP  PGY ,$WVVQP #FF  CFF$WVVQPCFF#EVKQP.KUVGPGT CFF.KUVGPGT  RCPGNCFF CFF$WVVQP  IGV%QPVGPV2CPG CFF RCPGN $QTFGT.C[QWV5176*  _ 
  • 9[UWMWLG QDKGMV Y FTGYKG "RCTCO QDL UWMCP[ QDKGMV "TGVWTP YúG CYKGTCLæE[ UWMCP[ QDKGMV NWD PWNN LG NK QDKGMV PKG PCLFWLG UKú Y FTGYKG
  •  RWDNKE &GHCWNV/WVCDNG6TGG0QFG HKPF7UGT1DLGEV 1DLGEV QDL ]  UWMC Yú C CYKGTCLæEGIQ QDKGMV W [VMQYPKMC 'PWOGTCVKQP G  TQQVDTGCFVJ(KTUV'PWOGTCVKQP  YJKNG GJCU/QTG'NGOGPVU ] &GHCWNV/WVCDNG6TGG0QFG PQFG  &GHCWNV/WVCDNG6TGG0QFG GPGZV'NGOGPV  KH PQFGIGV7UGT1DLGEV GSWCNU QDL TGVWTP PQFG _ TGVWTP PWNN _ 
  • &QFCLG FQ FTGYC MNCUú K LGL MNCU[ DCQYG MVÎT[EJ PKG OC LGUEG Y FTGYKG "RCTCO E FQFCYCPC MNCUC "TGVWTP PQYQ FQFCP[ YúG 
  •  RWDNKE &GHCWNV/WVCDNG6TGG0QFG CFF%NCUU %NCUU E ]  FQFCLG MNCUú FQ FTGYC  RQOKLC V[R[ MVÎTG PKG Uæ MNCUCOK KH EKU+PVGTHCEG ^^ EKU2TKOKVKXG TGVWTP PWNN  LG NK MNCUC PCLFWLG UKú LW Y FTGYKG VQ YTCEC LGL YúG &GHCWNV/WVCDNG6TGG0QFG PQFG  HKPF7UGT1DLGEV E  KH PQFG  PWNN TGVWTP PQFG  MNCUC PKG PCLFWLG UKú Y FTGYKG  PCLRKGTY PCNG [ FQFCè FQ FTGYC LGL MNCU[ DCQYG %NCUU U  EIGV5WRGTENCUU  &GHCWNV/WVCDNG6TGG0QFG RCTGPV KH U  PWNN RCTGPV  TQQV GNUG RCTGPV  CFF%NCUU U   FQFCLG MNCUú LCMQ YúG RQFTúFP[ &GHCWNV/WVCDNG6TGG0QFG PGY0QFG  PGY &GHCWNV/WVCDNG6TGG0QFG E 
  • 424 Java 2. Techniki zaawansowane OQFGNKPUGTV0QFG+PVQ PGY0QFG RCTGPV RCTGPVIGV%JKNF%QWPV   URTCYKC G YúG LGUV YKFQEP[ 6TGG2CVJ RCVJ  PGY 6TGG2CVJ OQFGNIGV2CVJ6Q4QQV PGY0QFG  VTGGOCMG8KUKDNG RCVJ  TGVWTP PGY0QFG _ 
  • <YTCEC QRKU UM CFQY[EJ MNCU[ "RCTCO MNCUC "TGVWTP C EWEJ PCMÎY CYKGTCLæE[ PCY[ K V[R[ OKGPP[EJ
  •  RWDNKE UVCVKE 5VTKPI IGV(KGNF&GUETKRVKQP %NCUU E ]  MQT[UVC OGEJCPKOW TGHNGMULK 5VTKPI$WHHGT T  PGY 5VTKPI$WHHGT  (KGNF=? HKGNFU  EIGV&GENCTGF(KGNFU  HQT KPV K   K  HKGNFUNGPIVJ K ] (KGNF H  HKGNFU=K? KH HIGV/QFKHKGTU /QFKHKGT56#6+%   TCRRGPF UVCVKE  TCRRGPF HIGV6[RG IGV0COG  TCRRGPF  TCRRGPF HIGV0COG  TCRRGPF >P  _ TGVWTP TVQ5VTKPI  _ RTKXCVG &GHCWNV/WVCDNG6TGG0QFG TQQV RTKXCVG &GHCWNV6TGG/QFGN OQFGN RTKXCVG ,6TGG VTGG RTKXCVG ,6GZV(KGNF VGZV(KGNF RTKXCVG ,6GZV#TGC VGZV#TGC RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ LCXCZUYKPI,6TGG n 6TGG2CVJ IGV5GNGEVKQP2CVJ n 6TGG2CVJ=? IGV5GNGEVKQP2CVJU Zwracają odpowiednio ście kę do pierwszego wybranego węzła lub tablicę ście ek do wybranych węzłów. Jeśli aden węzeł nie jest wybrany, obie metody zwracają PWNN. LCXCZUYKPIGXGPV6TGG5GNGEVKQP.KUVGPGT n XQKF XCNWG%JCPIGF 6TGG5GNGEVKQP'XGPV GXGPV wywoływana, gdy węzeł zostaje wybrany lub przestaje być wybrany.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 425 LCXCZUYKPIGXGPV6TGG5GNGEVKQP'XGPV n 6TGG2CVJ IGV2CVJ n 6TGG2CVJ=? IGV2CVJU Zwracają odpowiednio ście kę do pierwszego obiektu lub tablicę ście ek obiektów, których stan uległ zmianie na skutek danego zdarzenia wyboru. Jeśli interesują nas wybrane elementy, a nie zmiana ich wyboru, to powinniśmy skorzystać z metody IGV5GNGEVKQP2CVJ lub IGV5GNGEVKQP2CVJU klasy ,6TGG. Własne modele drzew Ostatnim przykładem wykorzystania drzew będzie program umo liwiający inspekcję war- tości zmiennych, podobnie jak czynią to narzędzia uruchomieniowe (patrz rysunek 6.24). Rysunek 6.24. Drzewo inspekcji obiektów Zanim rozpoczniemy omawianie programu, zalecamy, by skompilować go, uruchomić i za- poznać się z jego działaniem. Ka dy węzeł utworzonego przez program drzewa odpowiada zmiennej składowej obiektu. Jeśli z kolei ta zmienna reprezentuje tak e obiekt, to mo emy rozwinąć jej węzeł, aby sprawdzić zmienne tak e i tego obiektu. Program umo liwia in- spekcję obiektów składających się na jego interfejs u ytkownika. Jeśli rozejrzymy się tro- chę po drzewie, to znajdziemy znajome obiekty odpowiadające komponentom interfejsu u ytkownika. Jednocześnie nabierzemy tak e respektu dla zło oności mechanizmów bi- blioteki Swing, która nie jest zwykle widoczna dla programisty. Istotna ró nica w działaniu tego programu w stosunku do poprzednich przykładów polega na tym, e nie u ywa on klasy &GHCWNV6TGG/QFGN. Jeśli program dysponuje ju danymi zor- ganizowanymi w hierarchiczną strukturę, to nie ma sensu duplikować jej za pomocą nowe- go modelu i dodatkowo zajmować się jeszcze zapewnieniem synchronizacji obu struktur. Sytuacja taka występuje właśnie w przypadku naszego programu, poniewa obiekty inter- fejsu u ytkownika są ju powiązane wzajemnymi referencjami. Interfejs 6TGG/QFGN definiuje szereg metod. Pierwsza ich grupa umo liwia klasie ,6TGG odna- lezienie węzłów drzewa przez pobranie najpierw jego korzenia, a później węzłów podrzęd- nych. Klasa ,6TGG korzysta z tych metod jedynie, gdy u ytkownik rozwija węzeł drzewa.
  • 426 Java 2. Techniki zaawansowane 1DLGEV IGV4QQV KPV IGV%JKNF%QWPV 1DLGEV RCTGPV 1DLGEV IGV%JKNF 1DLGEV RCTGPV KPV KPFGZ Przykład ten ukazuje, dlaczego interfejs 6TGG/QFGN, podobnie jak klasa ,6TGG, nie korzysta bezpośrednio z pojęcia węzłów. Korzeń i jego węzły podrzędne mogą być dowolnymi obiektami. Interfejs 6TGG/QFGN umo liwia klasie ,6TGG uzyskanie informacji o sposobie ich powiązania. Kolejna metoda interfejsu 6TGG/QFGN wykonuje operację odwrotną do metody IGV%JKNF: KPV IGV+PFGZ1H%JKNF 1DLGEV RCTGPV 1DLGEV EJKNF Metoda ta mo e zostać zaimplementowana za pomocą wymienionych wcześniej trzech metod — patrz kod programu w listingu 6.8. Model drzewa informuje klasę ,6TGG o tym, które węzły powinny zostać przedstawione ja- ko liście: DQQNGCP KU.GCH 1DLGEV PQFG Jeśli w wyniku działania programu dane modelu drzewa ulegają zmianie, to drzewo musi zostać o tym powiadomione, aby dokonać aktualizacji swojego widoku. Dlatego te drzewo powinno być dodane jako obiekt nasłuchujący 6TGG/QFGN.KUVGPGT do modelu. Model musi więc posiadać typowe metody związane z zarządzaniem obiektami nasłuchującymi: XQKF CFF6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N XQKF TGOQXG6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N Implementację tych metod pokazuje tak e listing 6.8. Gdy zawartość modelu ulega zmianie, to wywołuje on jedną z czterech metod definiowa- nych przez interfejs 6TGG/QFG.KUVGPGT: XQKF VTGG0QFGU%JCPIGF 6TGG/QFGN'XGPV G XQKF VTGG0QFGU+PUGTVGF 6TGG/QFGN'XGPV G XQKF VTGG0QFGU4GOQXGF 6TGG/QFGN'XGPV G XQKF VTGG5VTWEVWTG%JCPIGF 6TGG/QFGN'XGPV G Parametr tych metod opisuje miejsce wystąpienia zmian w drzewie. Szczegóły tworzenia obiektu zdarzenia opisującego wstawienie bądź usunięcie węzła są dość skomplikowane, ale musimy się nimi zajmować tylko wtedy, gdy węzły naszego drzewa są rzeczywiście dodawane bądź usuwane. Listing 6.8 pokazuje konstrukcję obiektu zdarzenia w przypadku zastąpienia korzenia nowym obiektem. Programiści biblioteki Swing znużeni wysyłaniem obiektów zdarzeń utworzyli klasę LCXCZUYKPI'XGPV.KUVGPGT.KUV zawierającą listę obiektów nasłuchujących. Rozdział 8. książki Java 2. Podstawy zawiera więcej informacji na ten temat. Jeśli u ytkownik zmodyfikuje węzeł drzewa, to model zostaje o tym poinformowany przez wywołanie jego metody: XQKF XCNWG(QT2CVJ%JCPIGF 6TGG2CVJ RCVJ 1DLGEV PGY8CNWG
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 427 Gdy nie zezwolimy u ytkownikowi na edycję drzewa, to metoda ta nigdy nie zostanie wy- wołana. W przypadku takim konstrukcja modelu drzewa staje się łatwa. Nale y zaimplementować trzy poni sze metody: 1DLGEV IGV4QQV KPV IGV%JKNF%QWPV 1DLGEV RCTGPV 1DLGEV IGV%JKNF 1DLGEV RCTGPV KPV KPFGZ Opisują one strukturę drzewa. Następnie musimy dostarczyć jeszcze implementacji pozostałych pięciu metod, co pokazano w listingu 6.8 i będziemy gotowi do wyświetlenia własnego drzewa. Zajmijmy się teraz implementacją naszego programu. Drzewo zawierać będzie obiekty klasy 8CTKCDNG. Gdybyśmy skorzystali z klasy &GHCWNV6TGG/QFGN, to węzły naszego drzewa byłyby obiek- tami klasy &GHCWNV/WVCDNG6TGG0QFG zawierającymi obiekty użytkownika klasy 8CTKCDNG. Załó my, e inspekcji poddać chcemy zmienną: 'ORNQ[GG LQG Zmienna ta posiada typ 'ORNQ[GGENCUU, nazwę LQG i wartość, którą stanowi referencja do obiektu LQG. W programie zdefiniujemy klasę 8CTKCDNG słu ącą reprezentacji zmiennych: 8CTKCDNG X  PGY 8CTKCDNG 'ORNQ[GG%NCUU LQG  LQG  Jeśli zmienna jest typu podstawowego, musimy u yć dla jej wartości obiektu opakowującego. PGY 8CTKCDNG FQWDNG%NCUU UCNCT[  PGY &QWDNG UCNCT[  Jeśli typem zmiennej jest klasa, to zawierać będzie ona pola. Korzystając z mechanizmu re- fleksji, dokonujemy wyliczenia wszystkich pól i umieszczamy je w tablicy #TTC[.KUV. Ponie- wa metoda IGV(KGNFU klasy %NCUU nie zwraca pól klasy bazowej, to musimy ją dodatkowo wywołać dla wszystkich klas bazowych danej klasy. Odpowiedni kod odnajdziemy w kon- struktorze klasy 8CTKCDNG. Metoda IGV(KGNFU klasy 8CTKCDNG zwraca tablicę pól, natomiast metoda VQ5VTKPI — łańcuch znaków opisujący węzeł drzewa. Opis ten zawiera zawsze typ i nazwę zmiennej. Jeśli zmienna jest typu podstawowego, to opis zawiera tak e jej wartość. Jeśli typem zmiennej jest tablica, to program nie wyświetla jej elementów. Nie jest to trudne zadanie i pozostawiamy je jako ćwiczenie dla czytelników. Przejdźmy teraz do omówienia modelu drzewa. Pierwsze dwie jego metody są bardzo proste. RWDNKE 1DLGEV IGV4QQV ] TGVWTP TQQV _ RWDNKE KPV IGV%JKNF%QWPV 1DLGEV RCTGPV ] TGVWTP 8CTKCDNG RCTGPV IGV(KGNFU UKG  _
  • 428 Java 2. Techniki zaawansowane Metoda IGV%JKNF zwraca nowy obiekt klasy 8CTKCDNG opisujący dane pole. Metody IGV6[RG oraz IGV0COG klasy (KGNF udostępniają typ i nazwę pola. Korzystając z mechanizmu reflek- sji, mo emy odczytać wartość pola za pomocą wywołania HIGV RCTGPV8CNWG . Metoda ta mo e wyrzucić wyjątek +NNGICN#EEGUU'ZEGRVKQP. Poniewa w konstruktorze udostępniamy wszystkie pola, to wyjątek ten nie powinien się pojawić. Poni ej przedstawiamy kompletny kod metody IGV%JKNF. RWDNKE 1DLGEV IGV%JKNF 1DLGEV RCTGPV KPV KPFGZ ] #TTC[.KUV HKGNFU  8CTKCDNG RCTGPV IGV(KGNFU  (KGNF H  (KGNF HKGNFUIGV KPFGZ  1DLGEV RCTGPV8CNWG  8CTKCDNG RCTGPV IGV8CNWG  VT[ ] TGVWTP PGY 8CTKCDNG HIGV6[RG  HIGV0COG  HIGV RCTGPV8CNWG  _ ECVEJ +NNGICN#EEGUU'ZEGRVKQP G ] TGVWTP PWNN _ _ Powy sze trzy metody udostępniają strukturę drzewa komponentowi klasy ,6TGG. Imple- mentacja pozostałych metod jest rutynowa (patrz listing 6.8). Drzewo w naszym przykładzie jest strukturą nieskończoną. Mo emy to sprawdzić, doko- nując inspekcji jednego z obiektów typu 9GCM4GHGTGPEG. Jeśli wybierzemy jego zmienną o nazwie TGHGTGPV, to powrócimy do wyjściowego obiektu. Jego poddrzewo mo emy w ten sposób rozwijać w nieskończoność. Oczywiście program nie przechowuje nieskończonego zbioru węzłów, a jedynie tworzy je na ądanie, gdy u ytkownik rozwija kolejne poddrzewa. Przykład ten kończy omawianie tematyki drzew. Przejdziemy teraz do tematu tabel, kolej- nego zło onego komponentu biblioteki Swing. Koncepcyjnie drzewa i tabele nie mają wiele wspólnego, ale w obu przypadkach wykorzystywane są te same mechanizmy modelu danych i rysowania komórek. Listing 6.8. ObjectInspectorTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCNCPITGHNGEV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  KORQTV LCXCZUYKPIVTGG
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG Y CUPGIQ OQFGNW FTGYC 9[ YKGVNC RQNC QDKGMVÎY
  •  RWDNKE ENCUU 1DLGEV+PURGEVQT6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 429 ] ,(TCOG HTCOG  PGY 1DLGEV+PURGEVQT(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC FTGYQ
  •  ENCUU 1DLGEV+PURGEVQT(TCOG GZVGPFU ,(TCOG ] RWDNKE 1DLGEV+PURGEVQT(TCOG ] UGV6KVNG 1DLGEV+PURGEVQT6GUV  UGV5KG 9+&6* *'+)*6   LCMQ RKGTYU[ KPURGMELK RQFFCP[ LGUV QDKGMV TCOMK 8CTKCDNG X  PGY 8CTKCDNG IGV%NCUU  VJKU  VJKU  1DLGEV6TGG/QFGN OQFGN  PGY 1DLGEV6TGG/QFGN  OQFGNUGV4QQV X   VYQT[ K RTGGPVWLG FTGYQ VTGG  PGY ,6TGG OQFGN  IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VTGG  $QTFGT.C[QWV%'06'4  _ RTKXCVG ,6TGG VTGG RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • /QFGN FTGYC QRKUWLæEGIQ UVTWMVWTú RQYKæC QDKGMVÎY Y Lú[MW ,CXC 9ú [ RQFTúFPG TGRTGGPVWLæ OKGPPG UM CFQYG QDKGMVW
  •  ENCUU 1DLGEV6TGG/QFGN KORNGOGPVU 6TGG/QFGN ] 
  • 6YQT[ RWUVG FTGYQ
  •  RWDNKE 1DLGEV6TGG/QFGN ] TQQV  PWNN _ 
  • 7OKGUEC OKGPPæ Y MQTGPKW FTGYC "RCTCO X OKGPPC QRKU[YCPC RTG FTGYQ
  •  RWDNKE XQKF UGV4QQV 8CTKCDNG X ] 8CTKCDNG QNF4QQV  X TQQV  X HKTG6TGG5VTWEVWTG%JCPIGF QNF4QQV  _ RWDNKE 1DLGEV IGV4QQV
  • 430 Java 2. Techniki zaawansowane ] TGVWTP TQQV _ RWDNKE KPV IGV%JKNF%QWPV 1DLGEV RCTGPV ] TGVWTP 8CTKCDNG RCTGPV IGV(KGNFU UKG  _ RWDNKE 1DLGEV IGV%JKNF 1DLGEV RCTGPV KPV KPFGZ ] #TTC[.KUV HKGNFU  8CTKCDNG RCTGPV IGV(KGNFU  (KGNF H  (KGNF HKGNFUIGV KPFGZ  1DLGEV RCTGPV8CNWG  8CTKCDNG RCTGPV IGV8CNWG  VT[ ] TGVWTP PGY 8CTKCDNG HIGV6[RG  HIGV0COG  HIGV RCTGPV8CNWG  _ ECVEJ +NNGICN#EEGUU'ZEGRVKQP G ] TGVWTP PWNN _ _ RWDNKE KPV IGV+PFGZ1H%JKNF 1DLGEV RCTGPV 1DLGEV EJKNF ] KPV P  IGV%JKNF%QWPV RCTGPV  HQT KPV K   K  P K KH IGV%JKNF RCTGPV K GSWCNU EJKNF TGVWTP K TGVWTP  _ RWDNKE DQQNGCP KU.GCH 1DLGEV PQFG ] TGVWTP IGV%JKNF%QWPV PQFG   _ RWDNKE XQKF XCNWG(QT2CVJ%JCPIGF 6TGG2CVJ RCVJ 1DLGEV PGY8CNWG ]_ RWDNKE XQKF CFF6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N ] NKUVGPGT.KUVCFF 6TGG/QFGN.KUVGPGTENCUU N  _ RWDNKE XQKF TGOQXG6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N ] NKUVGPGT.KUVTGOQXG 6TGG/QFGN.KUVGPGTENCUU N  _ RTQVGEVGF XQKF HKTG6TGG5VTWEVWTG%JCPIGF 1DLGEV QNF4QQV ] 6TGG/QFGN'XGPV GXGPV  PGY 6TGG/QFGN'XGPV VJKU PGY 1DLGEV=? ]QNF4QQV_  'XGPV.KUVGPGT=? NKUVGPGTU  NKUVGPGT.KUVIGV.KUVGPGTU 6TGG/QFGN.KUVGPGTENCUU 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 431 HQT KPV K   K  NKUVGPGTUNGPIVJ K 6TGG/QFGN.KUVGPGT NKUVGPGTU=K? VTGG5VTWEVWTG%JCPIGF GXGPV  _ RTKXCVG 8CTKCDNG TQQV RTKXCVG 'XGPV.KUVGPGT.KUV NKUVGPGT.KUV  PGY 'XGPV.KUVGPGT.KUV  _ 
  • -NCUC TGRTGGPVWLæEC OKGPPæ RQUKCFCLæEæ V[R PCYú K YCTVQ è
  •  ENCUU 8CTKCDNG ] 
  • 6YQT[ QDKGMV TGRTGGPVWLæE[ OKGPPæ "RCTCO C6[RG V[R OKGPPGL "RCTCO C0COG PCYC OKGPPGL "RCTCO C8CNWG YCTVQ è OKGPPGL
  •  RWDNKE 8CTKCDNG %NCUU C6[RG 5VTKPI C0COG 1DLGEV C8CNWG ] V[RG  C6[RG PCOG  C0COG XCNWG  C8CNWG HKGNFU  PGY #TTC[.KUV  
  • PCLFWLG YU[UVMKG RQNC LG NK OKGPPC LGUV V[RW MNCU[ PKG TQYKLCLæE LGF[PKG C EWEJÎY PCMÎY K YCTVQ EK PWNN
  •  KH V[RGKU2TKOKVKXG V[RGKU#TTC[ V[RGGSWCNU 5VTKPIENCUU XCNWG  PWNN ]  RQDKGTC RQNC MNCU[ K RQNC YU[UVMKEJ LGL MNCU DCQY[EJ HQT %NCUU E  XCNWGIGV%NCUU  E  PWNN E  EIGV5WRGTENCUU ] (KGNF=? H  EIGV&GENCTGF(KGNFU  #EEGUUKDNG1DLGEVUGV#EEGUUKDNG H VTWG   RQDKGTC YU[UVMKG RQNC MVÎTG PKG Uæ UVCV[EPG HQT KPV K   K  HNGPIVJ K KH H=K?IGV/QFKHKGTU /QFKHKGT56#6+%   HKGNFUCFF H=K?  _ _ _ 
  • <YTCEC YCTVQ è OKGPPGL "TGVWTP YCTVQ è
  •  RWDNKE 1DLGEV IGV8CNWG ] TGVWTP XCNWG _
  • 432 Java 2. Techniki zaawansowane 
  • <YTCEC YU[UVMKG RQNC OKGPPGL MVÎTG PKG Uæ UVCV[EPG "TGVWTP VCDNKEC OKGPP[EJ QRKUWLæE[EJ RQNC
  •  RWDNKE #TTC[.KUV IGV(KGNFU ] TGVWTP HKGNFU _ RWDNKE 5VTKPI VQ5VTKPI ] 5VTKPI T  V[RG PCOG KH V[RGKU2TKOKVKXG T   XCNWG GNUG KH V[RGGSWCNU 5VTKPIENCUU T   XCNWG GNUG KH XCNWG  PWNN T  PWNN  TGVWTP T _ RTKXCVG %NCUU V[RG RTKXCVG 5VTKPI PCOG RTKXCVG 1DLGEV XCNWG RTKXCVG #TTC[.KUV HKGNFU _ LCXCZUYKPIVTGG6TGG/QFGN n 1DLGEV IGV4QQV zwraca korzeń drzewa. n KPV IGV%JKNF%QWPV 1DLGEV RCTGPV zwraca liczbę węzłów podrzędnych węzła RCTGPV. n 1DLGEV IGV%JKNF 1DLGEV RCTGPV KPV KPFGZ zwraca węzeł podrzędny węzła RCTGPV o danym indeksie. n KPV IGV+PFGZ1H%JKNF 1DLGEV RCTGPV 1DLGEV EJKNF zwraca indeks węzła EJKNF. Węzeł ten musi być węzłem podrzędnym węzła RCTGPV. n DQQNGCP KU.GCH 1DLGEV PQFG zwraca wartość VTWG, jeśli węzeł PQFG jest koncepcyjnym liściem. n XQKF CFF6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N n XQKF TGOQXG6TGG/QFGN.KUVGPGT 6TGG/QFGN.KUVGPGT N Dodają i usuwają obiekty nasłuchujące powiadamiane w momencie zmiany danych modelu. n XQKF XCNWG(QT2CVJ%JCPIGF 6TGG2CVJ RCVJ 1DLGEV PGY8CNWG metoda wywoływana, gdy edytor komórki zmodyfikował węzeł. Parametry: RCVJ ście ka do zmodyfikowanego węzła, PGY8CNWG nowa wartość zwrócona przez edytor.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 433 LCXCZUYKPIGXGPV6TGG/QFGN.KUVGPGT n XQKF VTGG0QFGU%JCPIGF 6TGG/QFGN'XGPV G n XQKF VTGG0QFGU+PUGTVGF 6TGG/QFGN'XGPV G n XQKF VTGG0QFGU4GOQXGF 6TGG/QFGN'XGPV G n XQKF VTGG5VTWEVWTG%JCPIGF 6TGG/QFGN'XGPV G Wywoływane przez model drzewa, gdy jego dane uległy zmianie. LCXCZUYKPIGXGPV6TGG/QFGN'XGPV n 6TGG/QFGN'XGPV 1DLGEV GXGPV5QWTEG 6TGG2CVJ PQFG tworzy model zdarzeń drzewa. Parametry: GXGPV5QWTEG model drzewa generujący zdarzenia, PQFG ście ka do węzła, który został zmodyfikowany. Tabele Klasa komponentu ,6CDNG wyświetla dwuwymiarową siatkę obiektów. Tabele stanowią często wykorzystywany komponent interfejsu u ytkownika. Projektanci biblioteki Swing wło yli wiele wysiłku w uniwersalne zaprojektowanie komponentu tabel. Tabele są skom- plikowanym komponentem, ale w ich przypadku projektantom klasy ,6CDNG udało się ukryć tę zło oność. W pełni funkcjonalne tabele o du ych mo liwościach tworzymy ju za pomo- cą kilku linijek kodu. Oczywiście kod ten mo emy rozbudowywać, dostosowując wygląd i zachowanie tabeli do naszych specyficznych potrzeb. W podrozdziale tym przedstawimy sposób tworzenia najprostszych tabel, ich interakcje z u ytkownikiem i najczęstsze modyfikacje komponentu. Podobnie jak w przypadku in- nych zło onych komponentów biblioteki Swing, omówienie wszystkich aspektów korzy- stania z tabel przekracza mo liwości tego rozdziału. Więcej informacji na ten temat znaleźć mo na w ksią ce Core Java Foundation Classes autorstwa Kim Topley lub Graphic Java 2 napisanej przez Davida M. Geary’ego. Najprostsze tabele Podobnie jak komponent drzewa, tak e i klasa ,6CDNG nie przechowuje danych tabeli, ale uzyskuje je, korzystając z modelu tabeli. Klasa ,6CDNG dysponuje konstruktorem, który umo liwia obudowanie dwuwymiarowej tablicy obiektów za pomocą domyślnego modelu. Z takiego rozwiązania skorzystamy w naszym pierwszym przykładzie. W dalszej części rozdziału zajmiemy się innymi modelami tabel. Rysunek 6.25 przedstawia typową tabelę opisującą cechy planet układu słonecznego. (Pla- neta posiada cechę gaseous, jeśli składa się w większości z wodoru i helu. Kolumnę Color wykorzystamy dopiero w kolejnych przykładach programów).
  • 434 Java 2. Techniki zaawansowane Rysunek 6.25. Przykład najprostszej tabeli Jak mo na zauwa yć, analizując kod programu zawarty w listingu 6.9, dane tabeli prze- chowywane są za pomocą dwuwymiarowej tablicy obiektów: RTKXCVG 1DLGEV=?=? EGNNU  ] ] /GTEWT[  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _ ] 8GPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _    _ Tabela wywołuje metodę VQ5VTKPI ka dego z tych obiektów i wyświetla uzyskany rezultat. Wyjaśnia to między innymi sposób prezentacji danych w kolumnie Color w postaci LCXC YCV%QNQT=TID?. Nazwy kolumn tabeli przechowywane są w osobnej tablicy łańcuchów znaków: RTKXCVG 5VTKPI=? EQNWOP0COGU  ] 2NCPGV  4CFKWU  /QQPU  )CUGQWU  %QNQT _ Korzystając z obu przedstawionych wy ej tablic, tworzymy tabelę. Umo liwiamy następnie jej przewijanie, obudowując ją panelem klasy ,5ETQNN2CPG. ,6CDNG VCDNG  PGY ,6CDNG EGNNU EQNWOP0COGU  ,5ETQNN2CPG RCPG  PGY ,5ETQNN2CPG VCDNG  Otrzymana tabela posiada zaskakująco bogate mo liwości. Zmniejszymy jej rozmiar tak, by pokazały się paski przewijania. Zwróćmy uwagę, e podczas przewijania zawartości ta- beli nazwy kolumn pozostają na właściwym miejscu! Następnie wybierzmy jeden z nagłówków kolumn i przeciągnijmy go w lewo lub w prawo. Spowoduje to przesunięcie całej kolumny (patrz rysunek 6.26), którą umieścić mo emy w innym miejscu tabeli. Zmiana ta dotyczy jedynie widoku tabeli i pozostaje bez wpływu na dane modelu. Aby zmienić szerokość kolumny, wystarczy umieścić kursor myszy na linii oddzielającej kolumny. Kursor przybierze wtedy kształt strzałki, umo liwiając przesunięcie linii oddzie- lającej kolumny (patrz rysunek 6.27).
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 435 Rysunek 6.26. Przesunięcie kolumny Rysunek 6.27. Zmiana szerokości kolumn U ytkownik mo e wybierać wiersze tabeli za pomocą myszy. Wybrane wiersze zostają pod- świetlone. Sposób obsługi takiego zdarzenia poka emy w dalszej części rozdziału. U ytkow- nik mo e tak e wybrać komórkę tabeli i zmodyfikować ją. W bie ącym przykładzie modyfi- kacja ta nie spowoduje jeszcze zmiany danych modelu. W praktyce w programach nale y wyłączyć mo liwość edycji komórek tabeli lub obsługiwać zdarzenia edycji i odpowiednio modyfikować dane modelu. Zagadnienia te omówimy nieco później. Listing 6.9. PlanetTable.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO FGOQPUVTWLæE[ RT[M CF RTQUVGL VCDGNK
  •  RWDNKE ENCUU 2NCPGV6CDNG ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 2NCPGV6CDNG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC VCDGNú FCP[EJ RNCPGV
  •  ENCUU 2NCPGV6CDNG(TCOG GZVGPFU ,(TCOG ] RWDNKE 2NCPGV6CDNG(TCOG ]
  • 436 Java 2. Techniki zaawansowane UGV6KVNG 2NCPGV6CDNG  UGV5KG 9+&6* *'+)*6  ,6CDNG VCDNG  PGY ,6CDNG EGNNU EQNWOP0COGU  IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VCDNG  $QTFGT.C[QWV%'06'4  _ RTKXCVG 1DLGEV=?=? EGNNU  ] ] /GTEWT[  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _ ] 8GPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _ ] 'CTVJ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNWG _ ] /CTU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTTGF _ ] ,WRKVGT  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG _ ] 5CVWTP  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG _ ] 7TCPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG _ ] 0GRVWPG  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG _ ] 2NWVQ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNCEM _ _ RTKXCVG 5VTKPI=? EQNWOP0COGU  ] 2NCPGV  4CFKWU  /QQPU  )CUGQWU  %QNQT _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 437 LCXCZUYKPI,6CDNG n ,6CDNG 1DLGEV=?=? GPVTKGU 1DLGEV=? EQNWOP0COGU tworzy tabelę, wykorzystując domyślny model. Parametry: GPVTKGU komórki tabeli, EQNWOP0COGU nazwy (tytuły) kolumn tabeli. Modele tabel W poprzednim przykładzie obiekty tabeli przechowywane były za pomocą dwuwymiaro- wej tablicy. Rozwiązanie takie nie jest jednak zalecane w ka dym przypadku. 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. Implementacja własnego modelu tabeli nie jest trudna, poniewa wykorzystać mo emy klasę #DUVTCEV6CDNG/QFGN, która dostarcza implementacji większości potrzebnych metod. Sami zaimplementować musimy jedynie trzy poni sze metody: RWDNKE KPV IGV4QY%QWPV  RWDNKE KPV IGV%QNWOP%QWPV  RWDNKE 1DLGEV IGV8CNWG#V KPV TQY KPV EQNWOP  Istnieje wiele sposobów implementacji metody IGV8CNWG#V. Mo emy po prostu wyliczyć odpowiednią wartość na ądanie lub pobrać konkretną wartość z bazy danych. Przyjrzyjmy się kilku przykładom. W pierwszym z nich tabela zawierać będzie wartości, które wyliczy program. Będą one przedstawiać wzrost inwestycji w ró nych scenariuszach (patrz rysunek 6.28). Rysunek 6.28. Tabela reprezentująca wzrost inwestycji Metoda IGV8CNWG#V wyznacza odpowiednią wartość i formatuje ją: RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] FQWDNG TCVG  E OKP4CVG   KPV PRGTKQFU  T
  • 438 Java 2. Techniki zaawansowane FQWDNG HWVWTG$CNCPEG  +0+6+#.A$#.#0%'
  • /CVJRQY  TCVG PRGTKQFU  TGVWTP 0WODGT(QTOCVIGV%WTTGPE[+PUVCPEG HQTOCV HWVWTG$CNCPEG  _ Metody IGV4QY%QWPV i IGV%QNWOP%QWPV zwracają odpowiednio liczbę wierszy i kolumn tabeli. RWDNKE KPV IGV4QY%QWPV ] TGVWTP [GCTU _ RWDNKE KPV IGV%QNWOP%QWPV ] TGVWTP OCZ4CVG  OKP4CVG  _ Jeśli nie podamy nazw kolumn, to metoda IGV%QNWOP0COG klasy #DUVTCEV6CDNG/QFGN nazwie kolejne kolumny A, B, C itd. Aby zmienić nazwy kolumn, zastąpimy metodę IGV%QNWOP0C OG i wykorzystamy procentowy przyrost inwestycji jako nazwę kolumn. RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] FQWDNG TCVG  E OKP4CVG   TGVWTP 0WODGT(QTOCVIGV2GTEGPV+PUVCPEG HQTOCV TCVG  _ Kompletny kod źródłowy programu zawiera listing 6.10. Listing 6.10. InvestmentTable.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCVGZV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO VYQTæE[ VCDGNú Y QRCTEKW Q Y CUP[ OQFGN
  •  RWDNKE ENCUU +PXGUVOGPV6CDNG ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY +PXGUVOGPV6CDNG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC VCDGNú KPYGUV[ELK
  •  ENCUU +PXGUVOGPV6CDNG(TCOG GZVGPFU ,(TCOG
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 439 ] RWDNKE +PXGUVOGPV6CDNG(TCOG ] UGV6KVNG +PXGUVOGPV6CDNG  UGV5KG 9+&6* *'+)*6  6CDNG/QFGN OQFGN  PGY +PXGUVOGPV6CDNG/QFGN     ,6CDNG VCDNG  PGY ,6CDNG OQFGN  IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VCDNG  %GPVGT  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • /QFGN VCDGNK Y[NKECLæE[ YCTVQ EK MQOÎTGM PC æFCPKG 6CDGNC RQMCWLG RT[TQUV KPYGUV[ELK Y MQNGLP[EJ NCVCEJ Y TÎ P[EJ UEGPCTKWUCEJ
  •  ENCUU +PXGUVOGPV6CDNG/QFGN GZVGPFU #DUVTCEV6CDNG/QFGN ] 
  • 6YQT[ OQFGN VCDGNK KPYGUV[ELK "RCTCO [ NKEDC NCV "RCTCO T PCLPK UC UVQRC RTQEGPVQYC "RCTCO T PCLY[ UC UVQRC RTQEGPVQYC
  •  RWDNKE +PXGUVOGPV6CDNG/QFGN KPV [ KPV T KPV T ] [GCTU  [ OKP4CVG  T OCZ4CVG  T _ RWDNKE KPV IGV4QY%QWPV ] TGVWTP [GCTU _ RWDNKE KPV IGV%QNWOP%QWPV ] TGVWTP OCZ4CVG  OKP4CVG  _ RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] FQWDNG TCVG  E OKP4CVG   KPV PRGTKQFU  T FQWDNG HWVWTG$CNCPEG  +0+6+#.A$#.#0%'
  • /CVJRQY  TCVG PRGTKQFU  TGVWTP 0WODGT(QTOCVIGV%WTTGPE[+PUVCPEG HQTOCV HWVWTG$CNCPEG  _ RWDNKE 5VTKPI IGV%QNWOP0COG KPV E
  • 440 Java 2. Techniki zaawansowane ] FQWDNG TCVG  E OKP4CVG   TGVWTP 0WODGT(QTOCVIGV2GTEGPV+PUVCPEG HQTOCV TCVG  _ RTKXCVG KPV [GCTU RTKXCVG KPV OKP4CVG RTKXCVG KPV OCZ4CVG RTKXCVG UVCVKE FQWDNG +0+6+#.A$#.#0%'   _ Prezentacja rekordów bazy danych Prawdopodobnie najczęściej reprezentowaną przez komponent tabeli informacją jest zbiór rekordów pochodzących z bazy danych. Korzystając ze środowiska tworzenia aplikacji, dysponujemy prawie zawsze gotowymi komponentami JavaBeans dla wykorzystania bazy danych. Warto jednak zobaczyć, w jaki sposób sami prezentować mo emy za pomocą ta- beli dane z bazy i temu zadaniu słu y kolejny przykład. Rysunek 6.29 pokazuje efekt jego działania — wynik zapytania o wszystkie rekordy wybranej tabeli bazy danych. Rysunek 6.29. Prezentacja wyniku zapytania za pomocą tabeli Przykładowy program definiuje własny model danych za pomocą klasy 4GUWNV5GV6CDNG/Q FGN, który pobiera dane będące wynikiem zapytania do bazy danych. (Rozdział 4. poświę- cony jest dostępowi do baz danych w języku Java). Liczbę kolumn i ich nazwy uzyskujemy, korzystając z obiektu TUOF reprezentującego meta- dane opisujące zbiór rekordów:
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 441 RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] VT[ ] TGVWTP TUOFIGV%QNWOP0COG E   _ ECVEJ 53.'ZEGRVKQP G ]    _ _ RWDNKE KPV IGV%QNWOP%QWPV ] VT[ ] TGVWTP TUOFIGV%QNWOP%QWPV  _ ECVEJ 53.'ZEGRVKQP G ]    _ _ Jeśli baza danych dysponuje przewijalnymi kursorami, to wartość komórki mo emy uzy- skać bardzo łatwo, przesuwając kursor do danego wiersza i pobierając wartość kolumny. RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] VT[ ] 4GUWNV5GV TU  IGV4GUWNV5GV  TUCDUQNWVG T   TGVWTP TUIGV1DLGEV E   _ ECVEJ 53.'ZEGRVKQP G ]    _ _ Wykorzystanie w tym przypadku własnego modelu danych zamiast domyślnego modelu &GHCWNV6CDNG/QFGN posiada szczególny sens. Jeśli utworzylibyśmy własną tablicę wartości, to niepotrzebnie duplikowalibyśmy zawartość bufora sterownika bazy danych. Jeśli baza danych nie dysponuje przewijalnymi kursorami lub korzystamy ze sterownika zgodnego ze specyfikacją JDBC 1, to sami musimy buforować wynik zapytania. Program ukazany w przykładzie umo liwia zarządzanie takim buforem. Klasa %CEJKPI4GUWNV5GV6C DNG/QFGN buforuje wynik zapytania, natomiast klasa 5ETQNNKPI4GUWNV5GV6CDNG/QFGN wyko- rzystuje przewijalny kursor. Funkcjonalność wspólną dla obu klas wyodrębniliśmy w klasie 4GUWNV5GV6CDNG/QFGN. Listing 6.11. ResultSetTable.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCKQ
  •  KORQTV LCXCUSN
  • 
  • 442 Java 2. Techniki zaawansowane KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO TGRTGGPVWLæE[ Y[PKM CR[VCPKC FQ DC[ FCP[EJ C RQOQEæ MQORQPGPVW VCDGNK
  •  RWDNKE ENCUU 4GUWNV5GV6CDNG ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 4GUWNV5GV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC NKUVú TQYKLCNPæ WOQ NKYKCLæEæ Y[DÎT VCDGNK DC[ FCP[EJ K VCDGNú TGRTGGPVWLæEæ LGL TGMQTF[
  •  ENCUU 4GUWNV5GV(TCOG GZVGPFU ,(TCOG ] RWDNKE 4GUWNV5GV(TCOG ] UGV6KVNG 4GUWNV5GV  UGV5KG 9+&6* *'+)*6  
  • PCLFWLG YU[UVMKG VCDGNG DC[ FCP[EJ K WOKGUEC LG PC NK EKG TQYKLCNPGL
  •  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  VCDNG0COGU  PGY ,%QODQ$QZ  VCDNG0COGUCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXV ] VT[ ] KH UETQNN2CPG  PWNN IGV%QPVGPV2CPG TGOQXG UETQNN2CPG  5VTKPI VCDNG0COG  5VTKPI VCDNG0COGUIGV5GNGEVGF+VGO  KH TU  PWNN TUENQUG  5VTKPI SWGT[  5'.'%6
  • (41/ VCDNG0COG TU  UVCVGZGEWVG3WGT[ SWGT[  KH UETQNNKPI OQFGN  PGY 5ETQNNKPI4GUWNV5GV6CDNG/QFGN TU  GNUG OQFGN  PGY %CEJKPI4GUWNV5GV6CDNG/QFGN TU  ,6CDNG VCDNG  PGY ,6CDNG OQFGN  UETQNN2CPG  PGY ,5ETQNN2CPG VCDNG 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 443 IGV%QPVGPV2CPG CFF UETQNN2CPG $QTFGT.C[QWV%'06'4  RCEM  FQ.C[QWV  _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  _ _ _  ,2CPGN R  PGY ,2CPGN  RCFF VCDNG0COGU  EQPVGPV2CPGCFF R $QTFGT.C[QWV0146*  VT[ ] EQPP  IGV%QPPGEVKQP  &CVCDCUG/GVC&CVC OGVC  EQPPIGV/GVC&CVC  KH OGVCUWRRQTVU4GUWNV5GV6[RG 4GUWNV5GV6;2'A5%41..A+05'05+6+8' ] UETQNNKPI  VTWG UVCV  EQPPETGCVG5VCVGOGPV 4GUWNV5GV6;2'A5%41..A+05'05+6+8' 4GUWNV5GV%10%74A4'#&A10.;  _ GNUG ] UVCV  EQPPETGCVG5VCVGOGPV  UETQNNKPI  HCNUG _ 4GUWNV5GV VCDNGU  OGVCIGV6CDNGU PWNN PWNN PWNN PGY 5VTKPI=? ] 6#$.' _  YJKNG VCDNGUPGZV VCDNG0COGUCFF+VGO VCDNGUIGV5VTKPI   VCDNGUENQUG  _ ECVEJ +1'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  _ CFF9KPFQY.KUVGPGT PGY 9KPFQY#FCRVGT ] RWDNKE XQKF YKPFQY%NQUKPI 9KPFQY'XGPV GXGPV ] VT[ ] EQPPENQUG  _ ECVEJ 53.'ZEGRVKQP G
  • 444 Java 2. Techniki zaawansowane ] GRTKPV5VCEM6TCEG  _ _ _  _ 
  • 6YQT[ RQ æEGPKG FQ DC[ FCP[EJ MQT[UVCLæE Y C EKYQ EK CRKUCP[EJ Y RNKMW FCVCDCUGRTQRGTVKGU "TGVWTP RQ æEGPKG FQ DC[ FCP[EJ
  •  RWDNKE UVCVKE %QPPGEVKQP IGV%QPPGEVKQP VJTQYU 53.'ZEGRVKQP +1'ZEGRVKQP ] 2TQRGTVKGU RTQRU  PGY 2TQRGTVKGU  (KNG+PRWV5VTGCO KP  PGY (KNG+PRWV5VTGCO FCVCDCUGRTQRGTVKGU  RTQRUNQCF KP  KPENQUG  5VTKPI FTKXGTU  RTQRUIGV2TQRGTV[ LFDEFTKXGTU  KH FTKXGTU  PWNN 5[UVGOUGV2TQRGTV[ LFDEFTKXGTU  FTKXGTU  5VTKPI WTN  RTQRUIGV2TQRGTV[ LFDEWTN  5VTKPI WUGTPCOG  RTQRUIGV2TQRGTV[ LFDEWUGTPCOG  5VTKPI RCUUYQTF  RTQRUIGV2TQRGTV[ LFDERCUUYQTF  TGVWTP &TKXGT/CPCIGTIGV%QPPGEVKQP WTN WUGTPCOG RCUUYQTF  _ RTKXCVG ,5ETQNN2CPG UETQNN2CPG RTKXCVG 4GUWNV5GV6CDNG/QFGN OQFGN RTKXCVG ,%QODQ$QZ VCDNG0COGU RTKXCVG 4GUWNV5GV TU RTKXCVG %QPPGEVKQP EQPP RTKXCVG 5VCVGOGPV UVCV RTKXCVG DQQNGCP UETQNNKPI RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • -NCUC DCQYC OQFGNK VCDGN MQT[UVCLæE[EJ RTGYKLCNP[EJ MWTUQTÎY NWD DWHQTWLæE[EJ Y[PKM CR[VCPKC 2TGEJQYWLG Y[PKM CR[VCPKC K LGIQ OGVCFCPG
  •  CDUVTCEV ENCUU 4GUWNV5GV6CDNG/QFGN GZVGPFU #DUVTCEV6CDNG/QFGN ] 
  • 6YQT[ OQFGN VCDGNK "RCTCO C4GUWNV5GV DKÎT TGMQTFÎY
  •  RWDNKE 4GUWNV5GV6CDNG/QFGN 4GUWNV5GV C4GUWNV5GV ] TU  C4GUWNV5GV VT[
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 445 ] TUOF  TUIGV/GVC&CVC  _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  _ _ RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] VT[ ] TGVWTP TUOFIGV%QNWOP0COG E   _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  TGVWTP  _ _ RWDNKE KPV IGV%QNWOP%QWPV ] VT[ ] TGVWTP TUOFIGV%QNWOP%QWPV  _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  TGVWTP  _ _ 
  • 2QDKGTC DKÎT TGMQTFÎY "TGVWTP DKÎT TGMQTFÎY
  •  RTQVGEVGF 4GUWNV5GV IGV4GUWNV5GV ] TGVWTP TU _ RTKXCVG 4GUWNV5GV TU RTKXCVG 4GUWNV5GV/GVC&CVC TUOF _ 
  • -NCUC Y[MQT[UVWLæEC RTGYKLCNPG MWTUQT[ FQUVúRPG Y ,&$% 
  •  ENCUU 5ETQNNKPI4GUWNV5GV6CDNG/QFGN GZVGPFU 4GUWNV5GV6CDNG/QFGN ] 
  • 6YQT[ OQFGN VCDGNK "RCTCO C4GUWNV5GV DKÎT TGMQTFÎY
  • 
  • 446 Java 2. Techniki zaawansowane RWDNKE 5ETQNNKPI4GUWNV5GV6CDNG/QFGN 4GUWNV5GV C4GUWNV5GV ] UWRGT C4GUWNV5GV  _ RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] VT[ ] 4GUWNV5GV TU  IGV4GUWNV5GV  TUCDUQNWVG T   TGVWTP TUIGV1DLGEV E   _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  TGVWTP PWNN _ _ RWDNKE KPV IGV4QY%QWPV ] VT[ ] 4GUWNV5GV TU  IGV4GUWNV5GV  TUNCUV  TGVWTP TUIGV4QY  _ ECVEJ 53.'ZEGRVKQP G ] GRTKPV5VCEM6TCEG  TGVWTP  _ _ _ 
  • -NCUC DWHQTWLæEC DKÎT TGMQTFÎY DúFæE[ Y[PKMKGO CR[VCPKC 7 [YCPC IF[ MWTUQT[ RTGYKLCNPG Uæ PKGFQUVúRPG
  •  ENCUU %CEJKPI4GUWNV5GV6CDNG/QFGN GZVGPFU 4GUWNV5GV6CDNG/QFGN ] RWDNKE %CEJKPI4GUWNV5GV6CDNG/QFGN 4GUWNV5GV C4GUWNV5GV ] UWRGT C4GUWNV5GV  VT[ ] ECEJG  PGY #TTC[.KUV  KPV EQNU  IGV%QNWOP%QWPV  4GUWNV5GV TU  IGV4GUWNV5GV  
  • 7OKGUEC FCPG Y VCDNKE[ V[RW CTTC[ NKUV MVÎTGL GNGOGPVCOK Uæ VCDNKEG V[RW 1DLGEV=? 0KG OQ GO[ Y[MQT[UVCè VCDNKE[ 1DLGEV=?=? RQPKGYC PKG PCO[ NKED[ TGMQTFÎY
  • 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 447 YJKNG TUPGZV ] 1DLGEV=? TQY  PGY 1DLGEV=EQNU? HQT KPV L   L  TQYNGPIVJ L TQY=L?  TUIGV1DLGEV L   ECEJGCFF TQY  _ _ ECVEJ 53.'ZEGRVKQP G ] 5[UVGOQWVRTKPVNP 'TTQT G  _ _ RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] KH T  ECEJGUKG TGVWTP 1DLGEV=? ECEJGIGV T =E? GNUG TGVWTP PWNN _ RWDNKE KPV IGV4QY%QWPV ] TGVWTP ECEJGUKG  _ RTKXCVG #TTC[.KUV ECEJG _ Filtry sortujące Dwa ostatnie przykłady wykazały, e tabele nie przechowują pokazywanych za ich pomocą danych, lecz pobierają je, korzystając z modelu. Tak e i model nie musi przechowywać da- nych — mo e wyliczać ich wartości na ądania lub pobierać je z bazy danych. Wprowadzimy teraz kolejny przydatny mechanizm zwany modelem filtra, który umo liwia prezentację informacji danej tablicy w innej formie. W naszym przykładzie forma ta pole- gać będzie na posortowaniu wierszy tabeli. Po uruchomieniu programu, którego tekst źró- dłowy zawiera listing 6.12, spróbujmy kliknąć dwukrotnie jedną z kolumn tabeli. Spowo- duje to uporządkowanie tabeli według wartości wybranej kolumny (patrz rysunek 6.30). Rysunek 6.30. Sortowanie wierszy tabeli
  • 448 Java 2. Techniki zaawansowane Sortowanie tabeli nie powoduje jednak uporządkowania danych modelu. Za posortowanie danych odpowiedzialny jest bowiem model filtra. Przechowuje on referencję do modelu tabeli. Gdy komponent tabeli pobiera wiersz do pre- zentacji, to model filtra wyznacza rzeczywisty wiersz tabeli i pobiera go z modelu tabeli. Oto przykład RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] TGVWTP OQFGNIGV8CNWG TGE[YKUV[ KPFGMU YKGTUC E  _ Wywołania pozostałych metod przekazywane są po prostu do oryginalnego modelu tabeli. RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] TGVWTP OQFGN IGV%QNWOP0COG E  _ Rysunek 6.31 pokazuje sposób, w jaki model filtra współdziała z obiektem klasy ,6CDNG i rzeczywistym modelem tabeli. Rysunek 6.31. Model filtra tabeli Z implementacją takiego filtra związane są dwa zagadnienia. Po pierwsze, gdy u ytkownik kliknie dwukrotnie jedną z kolumn, to model filtra musi otrzymać informację o tym. Nie będziemy omawiać związanych z tym szczegółów implementacji. Odpowiedni kod odnaj- dziemy wewnątrz metody CFF/QWUG.KUVGPGT klasy 5QTV(KNVGT/QFGN w tekście listingu 6.12. Działa on w następujący sposób. Najpierw pobieramy komponent nagłówka tabeli i doda- jemy do niego obiekt nasłuchujący zdarzeń związanych z myszą. Kiedy wykryje on dwu- krotne kliknięcie, musi uzyskać informację o kolumnie, której ono dotyczy. Następnie przeło yć kolumnę komponentu tabeli na kolumnę modelu, poniewa u ytkownik mógł je poprzestawiać. Znając kolumnę, mo e rozpocząć sortowanie danych. Z sortowaniem danych związane jest kolejne zagadnienie. Poniewa nie chcemy sortować danych oryginalnego modelu tabeli, to musimy uzyskać sekwencję indeksów wierszy, która pozwoli na ich prezentację przez komponent w uporządkowanej kolejności. Jednak algo- rytmy sortowania dostępne w klasach #TTC[U i %QNNGEVKQPU nie udostępnią nam takiej in- formacji. Mo emy oczywiście sami zaimplementować algorytm sortowania, który pozwoli śledzić sposób uporządkowania obiektów. Istnieje jednak sprytne rozwiązanie tego proble- mu. Polega ono na dostarczeniu własnych obiektów i własnej metody porównania biblio- tecznym algorytmom sortowania. Sortować będziemy obiekty typu 4QY. Obiekt taki zawiera indeks T wiersza w modelu. Dwa takie obiekty porównywać będziemy następująco: odnajdziemy je w modelu i porównamy. Innymi słowy metoda EQORCTG6Q dla obiektów klasy 4QY zwracać będzie wynik następują- cego porównania: OQFGNIGV8CNWG#V T E EQORCTG6Q OQFGN IGV8CNWG#V T E gdzie T i T są indeksami obiektów klasy 4QY, a E jest kolumną, według której sortowana jest tabela.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 449 Jeśli wartości danej kolumny nie mo na porównać, to porównujemy reprezentujące je łań- cuchy znaków. Tym sposobem mo emy posortować tabelę tak e według kolumn zawiera- jących wartości logiczne lub definicje kolorów (choć adna z reprezentujących je klas nie implementuje interfejsu %QORCTCDNG). Klasę 4QY zdefiniujemy jako klasę wewnętrzną klasy 5QTV(KNVGT/QFGN, poniewa metoda EQO RCTG6Q klasy 4QY potrzebuje dostępu do bie ącej kolumny modelu. Poni ej przedstawiamy odpowiedni kod: ENCUU 5QTV(KNVGT/QFGN GZVGPFU #DUVTCEV6CDNG/QFGN ]    RTKXCVG ENCUU 4QY KORNGOGPVU %QORCTCDNG ] RWDNKE KPV KPFGZ RWDNKE KPV EQORCTG6Q 1DLGEV QVJGT ] 4QY QVJGT4QY  4QY QVJGT 1DLGEV C  OQFGNIGV8CNWG#V KPFGZ UQTV%QNWOP  1DLGEV D  OQFGNIGV8CNWG#V QVJGT4QYKPFGZ UQTV%QNWOP  KH C KPUVCPEGQH %QORCTCDNG TGVWTP %QORCTCDNG C EQORCTG6Q D  GNUG TGVWTP CVQ5VTKPI EQORCTG6Q DVQ5VTKPI  _ _ RTKXCVG 6CDNG/QFGN OQFGN RTKXCVG KPV UQTV%QNWOP RTKXCVG 4QY=? TQYU _ W konstruktorze tworzymy tablicę TQYU, którą inicjujemy w taki sposób, e TQYU=K?K: RWDNKE 5QTV(KNVGT/QFGN 6CDNG/QFGN O ] OQFGN  O TQYU  PGY 4QY=OQFGNIGV4QY%QWPV ? HQT KPV K   K  TQYUNGPIVJ K ] TQYU=K?  PGY 4QY  TQYU=K?KPFGZ  K _ _ Metoda UQTV korzysta z algorytmu metody #TTC[UUQTV do sortowania obiektów klasy 4QY. Poniewa metoda porównania korzysta z elementów odpowiedniej kolumny, to elementy te są uporządkowane w ten sposób, e TQY=? zawiera indeks najmniejszego elementu w ko- lumnie, TQY=? następnego najmniejszego elementu itd. Gdy tablica jest sortowana, to powiadamiamy wszystkie obiekty nasłuchujące zmian w mo- delu (w szczególności ,6CDNG), e zawartość tabeli uległa zmianie i musi zostać narysowana od nowa. RWDNKE XQKF UQTV KPV E ] UQTV%QNWOP  E
  • 450 Java 2. Techniki zaawansowane #TTC[UUQTV TQYU  HKTG6CDNG&CVC%JCPIGF  _ Poni ej prezentujemy tak e implementację metody IGV8CNWG#V klasy filtra. Tłumaczy ona wartość indeksu T na wartość indeksu modelu TQYU=T?KPFGZ: RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] TGVWTP OQFGNIGV8CNWG#V TQYU=T?KPFGZ E  _ Model filtra sortującego jest kolejnym udanym przykładem zastosowania wzorca model- widok. Poniewa oddziela on dane od sposobu ich prezentacji, to mo emy dowolnie zmie- niać ich wzajemne odwzorowanie. Listing 6.12. TableSortTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO FGOQPUVTWLæE[ UQTVQYCPKG VCDGNK YGF WI Y[DTCPGL MQNWOP[ 9 EGNW RTGUQTVQYCPKC VCDGNK PCNG [ FYWMTQVPKG MNKMPæè LGFPæ MQNWOP
  •  RWDNKE ENCUU 6CDNG5QTV6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 6CDNG5QTV(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC VCDGNú FCP[EJ Q RNCPGVCEJ
  •  ENCUU 6CDNG5QTV(TCOG GZVGPFU ,(TCOG ] RWDNKE 6CDNG5QTV(TCOG ] UGV6KVNG 6CDNG5QTV6GUV  UGV5KG 9+&6* *'+)*6   VYQT[ OQFGN VCDGNK QTC OQFGN HKNVTC &GHCWNV6CDNG/QFGN OQFGN  PGY &GHCWNV6CDNG/QFGN EGNNU EQNWOP0COGU  HKPCN 5QTV(KNVGT/QFGN UQTVGT  PGY 5QTV(KNVGT/QFGN OQFGN   RQMCWLG VCDGNú HKPCN ,6CDNG VCDNG  PGY ,6CDNG UQTVGT 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 451 IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VCDNG  $QTFGT.C[QWV%'06'4   FQFCLG QDKGMV PCU WEJWLæE[ FYWMTQVP[EJ MNKMPKúè  O[U[ Y PCI ÎYMW VCDGNK VCDNGIGV6CDNG*GCFGT CFF/QWUG.KUVGPGT PGY /QWUG#FCRVGT ] RWDNKE XQKF OQWUG%NKEMGF /QWUG'XGPV GXGPV ]  E[ FYWMTQVPG MNKMPKúEKG! KH GXGPVIGV%NKEM%QWPV   TGVWTP  URTCYFC FNC MVÎTGL MQNWOP[ KPV VCDNG%QNWOP  VCDNGEQNWOP#V2QKPV GXGPVIGV2QKPV   COKGPKC KPFGMU MQNWOP[ PC KPFGMU MQNWOP[ Y OQFGNW  K UQTVWLG Læ KPV OQFGN%QNWOP  VCDNGEQPXGTV%QNWOP+PFGZ6Q/QFGN VCDNG%QNWOP  UQTVGTUQTV OQFGN%QNWOP  _ _  _ RTKXCVG 1DLGEV=?=? EGNNU  ] ] /GTEWT[  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _ ] 8GPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY _ ] 'CTVJ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNWG _ ] /CTU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTTGF _ ] ,WRKVGT  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG _ ] 5CVWTP  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG _ ] 7TCPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG _
  • 452 Java 2. Techniki zaawansowane ] 0GRVWPG  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG _ ] 2NWVQ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNCEM _ _ RTKXCVG 5VTKPI=? EQNWOP0COGU  ] 2NCPGV  4CFKWU  /QQPU  )CUGQWU  %QNQT _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • /QFGN VCDGNK Y[MQT[UVWLæE[ QT[IKPCNP[ OQFGN VCDGNK K UQTVWLæE[ YKGTUG VCDGNK YGF WI Y[DTCPGL MQNWOP[
  •  ENCUU 5QTV(KNVGT/QFGN GZVGPFU #DUVTCEV6CDNG/QFGN ] 
  • 6YQT[ OQFGN HKNVTC UQTVWLæEGIQ "RCTCO O Y[L EKQY[ OQFGN VCDGNK
  •  RWDNKE 5QTV(KNVGT/QFGN 6CDNG/QFGN O ] OQFGN  O TQYU  PGY 4QY=OQFGNIGV4QY%QWPV ? HQT KPV K   K  TQYUNGPIVJ K ] TQYU=K?  PGY 4QY  TQYU=K?KPFGZ  K _ _ 
  • 5QTVWLG YKGTUG VCDGNK "RCTCO E MQNWOPC YGF WI MVÎTGL QFD[YC UKú UQTVQYCPKG
  •  RWDNKE XQKF UQTV KPV E ] UQTV%QNWOP  E #TTC[UUQTV TQYU  HKTG6CDNG&CVC%JCPIGF  _  &NC RQPK U[EJ OGVQF OWUK PCLRKGTY QUVCè Y[PCEQP[  QFRQYKGFPK YKGTU RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] TGVWTP OQFGNIGV8CNWG#V TQYU=T?KPFGZ E  _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 453 RWDNKE DQQNGCP KU%GNN'FKVCDNG KPV T KPV E ] TGVWTP OQFGNKU%GNN'FKVCDNG TQYU=T?KPFGZ E  _ RWDNKE XQKF UGV8CNWG#V 1DLGEV C8CNWG KPV T KPV E ] OQFGNUGV8CNWG#V C8CNWG TQYU=T?KPFGZ E  _  RQQUVC G Y[YQ CPKC OGVQF FGNGIQYCPG Uæ FQ OQFGNW Y[L EKQYGIQ RWDNKE KPV IGV4QY%QWPV ] TGVWTP OQFGNIGV4QY%QWPV  _ RWDNKE KPV IGV%QNWOP%QWPV ] TGVWTP OQFGNIGV%QNWOP%QWPV  _ RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] TGVWTP OQFGNIGV%QNWOP0COG E  _ RWDNKE %NCUU IGV%QNWOP%NCUU KPV E ] TGVWTP OQFGNIGV%QNWOP%NCUU E  _ 
  • -NCUC YGYPúVTPC RTGEJQYWLæEC KPFGMU YKGTUC Y OQFGNW 9KGTUG RQTÎYP[YCPG Uæ C RQOQEæ YCTVQ EK OQFGNW FNC Y MQNWOPKG YGF WI MVÎTGL UQTVQYCPC LGUV VCDGNC
  •  RTKXCVG ENCUU 4QY KORNGOGPVU %QORCTCDNG ] RWDNKE KPV KPFGZ RWDNKE KPV EQORCTG6Q 1DLGEV QVJGT ] 4QY QVJGT4QY  4QY QVJGT 1DLGEV C  OQFGNIGV8CNWG#V KPFGZ UQTV%QNWOP  1DLGEV D  OQFGNIGV8CNWG#V QVJGT4QYKPFGZ UQTV%QNWOP  KH C KPUVCPEGQH %QORCTCDNG TGVWTP %QORCTCDNG C EQORCTG6Q D  GNUG TGVWTP CVQ5VTKPI EQORCTG6Q DVQ5VTKPI   TGVWTP KPFGZ  QVJGT4QYKPFGZ _ _ RTKXCVG 6CDNG/QFGN OQFGN RTKXCVG KPV UQTV%QNWOP RTKXCVG 4QY=? TQYU _
  • 454 Java 2. Techniki zaawansowane LCXCZUYKPIVCDNG6CDNG/QFGN n KPV IGV4QY%QWPV n KPV IGV%QNWOP%QWPV Zwracają liczbę wierszy i kolumn w modelu tabeli. n 1DLGEV IGV8CNWG#V KPV TQY KPV EQNWOP zwraca wartość w danym wierszu i kolumnie. n XQKF UGV8CNWG#V 1DLGEV PGY8CNWG KPV TQY KPV EQNWOP nadaje wartość obiektowi w danym wierszu i kolumnie. n DQNGCP KU%GNN'FKVCDNG KPV TQY KPV EQNWOP zwraca wartość VTWG, jeśli komórka w danym wierszu i kolumnie mo e być edytowana. n 5VTKPI IGV%QNWOP0COG KPV EQNWOP zwraca nazwę (tytuł) kolumny. LCXCZUYKPIVCDNG#DUVTCEV6CDNG/QFGN n XQKF HKTG6CDNG&CVC%JCPIGF zawiadamia wszystkie obiekty nasłuchujące danego modelu tabeli o zmianie danych. LCXCZUYKPI,6CDNG n ,6CDNG*GCFGT IGV6CDNGJGCFGT zwraca komponent nagłówka danej tabeli. n KPV EQNWOP#V2QKPV 2QKPV R zwraca numer kolumny tabeli, która zawiera piksel R. n KPV EQPXGTV%QNWOP+PFGZ6Q/QFGN KPV VCDNG%QNWOP zwraca indeks kolumny w modelu dla danej kolumny w tabeli. Wartości te są ró ne, jeśli kolumny tabeli zostały poprzestawiane lub ukryte. Rysowanie i edytowanie zawartości komórek Kolejny przykład znowu będzie prezentował w tabeli dane o planetach, ale tym razem wy- posa ymy tabelę w informację o typie kolumn. Jeśli zdefiniujemy metodę %NCUU IGV%QNWOP%NCUU KPV EQNWOP+PFGZ modelu tabeli tak, by zwracała klasę opisującą typ kolumny, to klasa ,6CDNG będzie mogła wybrać właściwy obiekt rysujący dla danej klasy. Tabela 6.1 przedstawia sposób prezentacji kolumn ró nych typów przez domyślne obiekty rysujące wykorzystywane przez klasę ,6CDNG. Tabela 6.1. Domyślne obiekty rysujące Typ Reprezentacja w postaci +OCIG+EQP obrazka $QQNGCP pola wyboru 1DLGEV łańcucha znaków
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 455 Pola wyboru i obrazki w komórkach tabeli zobaczyć mo emy na rysunku 6.32 (dziękujemy w tym miejscu Jimowi Evinsowi, http://www.snaught.com/JimCoolIcons/Planets, za udo- stępnienie obrazków planet). Rysunek 6.32. Tabela wykorzystująca obiekty rysujące W przypadku innych typów dostarczyć mo emy własnych obiektów rysujących. Przypominają one w działaniu obiekty rysujące komórki drzewa, które przedstawiliśmy, omawiając kompo- nent drzewa. Implementują one interfejs 6CDNG%GNN4GPFGTGT posiadający pojedynczą metodę: %QORQPGPV IGV6CDNG%GNN4GPFGTGT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP KU5GNGEVGF DQQNGCP JCU(QEWU KPV TQY KPV EQNWOP Metoda ta wywoływana jest za ka dym razem, kiedy komórka tabeli wymaga narysowania. Zwraca komponent, którego metoda RCKPV wykorzystywana jest do narysowania komórki tabeli. Aby wyświetlić komórkę typu %QNQT, wystarczy, e zwrócimy panel, którego kolor tła usta- wiony będzie zgodnie z kolorem określonym przez obiekt %QNQT znajdujący się w komórce tabeli. Obiekt ten zostanie przekazany metodzie za pośrednictwem parametru XCNWG. ENCUU %QNQT6CDNG%GNN4GPFGTGT KORNGOGPVU 6CDNG%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV6CDNG%GNN4GPFGTGT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP KU5GNGEVGF DQQNGCP JCU(QEWU KPV TQY KPV EQNWOP ] RCPGNUGV$CEMITQWPF %QNQT XCNWG  TGVWTP RCPGN _ RTKXCVG ,2CPGN RCPGN  PGY ,2CPGN  _ Musimy jeszcze przekazać do tabeli informację, aby skorzystała z obiektu rysującego po- wy szej klasy w przypadku wszystkich komórek zawierających obiekty klasy %QNQT. U y- jemy w tym celu metody UGV&GHCWNV4GPFGTGT klasy ,6CDNG, której parametrami będą obiekt klasy %NCUU i obiekt rysujący.
  • 456 Java 2. Techniki zaawansowane VCDNGUGV&GHCWNV4GPFGTGT %QNQTENCUU PGY %QNQT6CDNG%GNN4GPFGTGT  Odtąd nowy obiekt rysujący będzie wykorzystywany dla obiektów danego typu. Często wykorzystuje się obiekty rysujące, które różnicują wygląd komórki w zależności od jej stanu (przeglądana, wybrana). W tym celu musimy dysponować rozmiarami ko- mórki oraz schematem kolorów związanym ze stanami wybrania i przeglądania kompo- nentów interfejsu. Aby uzyskać informację o rozmiarach komórki, skorzystać można z metody IGV%GNN 4GEV klasy ,6CDNG. Kolory związane z wybraniem komponentów zwracają metody IGV 5GNGEVKQP$CEMITQWPF i IGV5GNGEVKQP(QTGITQWPF. Jeśli obiekt rysujący wyświetla łańcuch znaków lub ikonę, to możemy go utworzyć, roz- szerzając klasę &GHCWNV6CDNG%GNN4GPFGTGT, która wykona działania związane z obsłu- gą stanu wyboru i przeglądania komórki. Edycja komórek Aby umo liwić edycję komórek, model tabeli musi definiować metodę KU%GNN'FKVCDNG wskazującą, czy dana komórka tabeli mo e być edytowana. Zwykle zezwala się raczej od razu na edycję całej kolumny ni poszczególnych komórek. W programie przykładowym pozwolimy na edycję komórek czterech kolumn tabeli. RWDNKE DQQNGCP KU%GNN'FKVCDNG KPV T KPV E ] TGVWTP E  0#/'A%1.7/0 ^^ E  /110A%1.7/0 ^^ E  )#5'175A%1.7/0 ^^ E  %1.14A%1.7/0 _ RWDNKE UVCVKE HKPCN KPV 0#/'A%1.7/0   RWDNKE UVCVKE HKPCN KPV /110A%1.7/0   RWDNKE UVCVKE HKPCN KPV )#5'175A%1.7/0   RWDNKE UVCVKE HKPCN KPV %1.14A%1.7/0   Klasa #DUVTCEV6CDNG/QFGN definiuje metodę KU%GNN'FKVCDNG, która zawsze zwraca wartość HCNUG. Klasa &GHCWNV6CDNG/QFGN zastępuje ją z kolei implementacją, która zawsze zwraca wartość VTWG. Jeśli uruchomimy program, którego tekst źródłowy zawiera listing 6.13, to zauwa ymy, e w kolumnie Gaseous mo emy edytować pole wyboru. Natomiast w kolumnie Moons mo- emy wybierać wartość z listy rozwijalnej (rysunek 6.33). Za chwilę poka emy, w jaki spo- sób zainstalować listę rozwijalną jako edytor wartości komórki. Wybierając komórki pierwszej kolumny tabeli, mo emy zmieniać ich zawartość, wpisując dowolny ciąg znaków.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 457 Rysunek 6.33. Edytor komórki Wszystkie powy sze przykłady stanowią odmiany klasy &GHCWNV%GNN'FKVQT. Obiekt klasy &GHCWNV%GNN'FKVQT mo e zostać utworzony po wykorzystaniu obiektu klasy ,6GZV(KGNF, ,%JGEM$QZ lub ,%QODQ$QZ. Klasa ,6CDNG sama automatycznie instaluje edytor pól wyboru dla kolumn klasy DQQNGCP oraz edytor pól tekstowych dla pozostałych typów kolumn, które nie posiadają własnego obiektu rysującego. Edytory pól tekstowych pozwalają w takim przy- padku na modyfikację łańcucha znaków będącego wynikiem zastosowania metody VQ 5VTKPI do obiektu zwróconego przez metodę IGV8CNWG#V modelu tabeli. Po zakończeniu edycji komórki edytor przekazuje rezultat z powrotem do modelu tabeli, korzystając z metody UGV8CNWG#V. Zadaniem programisty jest takie zaimplementowanie tej metody, aby jej wywołanie przez edytor spowodowało nadanie odpowiedniej wartości obiektowi w modelu tabeli. Edytor pola tekstowego może łatwo przekształcić wartość komórki w łańcuch znaków, korzystając z metody VQ5VTKPI obiektu zwróconego przez wywołanie metody IGV8CNW G#V. Jednak przekształcenie w odwrotnym kierunku spoczywa na barkach programisty. Po zakończeniu edycji komórki edytor wywoła metodę UGV8CNWG#V, której przekaże łań- cuch znaków. Metoda ta musi umieć odpowiednio sparsować ten łańcuch. Na przykład jeśli komórka zawierała numeryczną wartość całkowitą, metoda UGV8CNWG#V może wy- korzystać metodę +PVGIGTRCTUG+PV. Aby u yć w komórkach tabeli edytora listy rozwijalnej, musimy go zainstalować samo- dzielnie, poniewa klasa ,6CDNG nie mo e sama ustalić zbioru wartości dla danego typu komórki. W przypadku komórek kolumny Moons naszej tabeli umo liwimy u ytkowni- kowi wybór wartości z przedziału od 0 do 20. Poni ej fragment kodu inicjujący listę rozwijalną. ,%QODQ$QZ OQQP%QODQ  PGY ,%QODQ$QZ  HQT KPV K   K   K OQQP%QODQCFF+VGO PGY +PVGIGT K 
  • 458 Java 2. Techniki zaawansowane Następnie utworzymy obiekt klasy &GHCWNV%GNN'FKVQT, przekazując listę jako parametr jego konstruktora: 6CDNG%GNN'FKVQT OQQP'FKVQT  PGY &GHCWNV%GNN'FKVQT OQQP%QODQ  Musimy jeszcze zainstalować utworzony edytor. W przeciwieństwie do edytora kolorów nie zwią emy go z określonym typem, poniewa nie chcemy, by u ywany był przez tabelę dla wszystkich komórek typu +PVGIGT. Zamiast tego zainstalujemy go jedynie dla określo- nej kolumny tabeli. Klasa ,6CDNG przechowuje informację o kolumnach tabeli, korzystając z obiektów typu 6C DNG%QNWOP. Klasa 6CDNG%QNWOP/QFGN zarządza natomiast kolumnami. (Rysunek 6.34 przed- stawia zale ności między najwa niejszymi klasami związanymi z tabelami). Jeśli nie pla- nujemy dynamicznie umieszczać w tabeli nowych kolumn bądź usuwać istniejących, to nie musimy korzystać z usług modelu kolumn tabeli z wyjątkiem sytuacji, w której chcemy uzyskać obiekt 6CDNG%QNWOP dla pewnej kolumny: Rysunek 6.34. Zależności między klasami tabel 6CDNG%QNWOP/QFGN EQNWOP/QFGN  VCDNGIGV%QNWOP/QFGN  6CDNG%QNWOP OQQP%QNWOP  EQNWOP/QFGNIGV%QNWOP 2NCPGV6CDNG/QFGN/110A%1.7/0  Dysponując obiektem kolumny, mo emy zainstalować edytor jej komórek: OQQP%QNWOPUGV%GNN'FKVQT OQQP'FKVQT  Jeśli chcemy zmienić wysokość komórek tabeli, skorzystamy z poni szej metody. VCDNGUGV4QY*GKIJV JGKIJV  Domyślnie wszystkie wiersze tabeli posiadają tę samą wysokość. Mo emy jednak zmienić wysokość poszczególnych wierszy, psługując się wywołaniem: VCDNGUGV4QY*GKIJV TQY JGKIJV  Rzeczywista wysokość komórki pomniejszona będzie o jej margines, który domyślnie wy- nosi 1. Wielkość marginesu mo emy zmienić, u ywając poni szej metody. VCDNGUGV4QY/CTIKP OCTIKP 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 459 Tworzenie własnych edytorów Jeśli uruchomimy przykładowy program i wybierzemy za pomocą myszy komórkę zawie- rającą kolor, to otworzy się okno dialogowe wyboru koloru. U ytkownik mo e wybrać no- wy kolor i zaakceptować go przyciskiem OK, co spowoduje zmianę koloru komórki tabeli (patrz rysunek 6.35). Rysunek 6.35. Wybór koloru komórki Edytor koloru komórek nie jest standardowym edytorem tabeli. Aby utworzyć własny edytor, nale y zaimplementować interfejs 6CDNG%GNN'FKVQT. Jest to dość pracochłonne za- danie i dlatego wersja SDK 1.3 wprowadziła klasę #DUVTCEV%GNN'FKVQT zawierającą imple- mentację obsługi zdarzeń. Metoda IGV6CDNG%GNN'FKVQT%QORQPGPV interfejsu 6CDNG%GNN'FKVQT pobiera komponent rysu- jący komórkę tabeli. Jest zdefiniowana tak samo jak metoda IGV6CDNG%GNN4GPFGTGT%QORQ PGPV interfejsu 6CDNG%GNN4GPFGTGT z tą ró nicą, e nie posiada parametru JCU(QEWU. Poniewa komórka jest edytowana, to automatycznie przyjmuje się, e wartością tego parametru jest VTWG. Komponent edytora zastępuje obiekt rysujący podczas edycji komórki. W naszym przykładzie wywołanie metody zwraca pusty, niepokolorowany panel, sygnalizując w ten sposób, e komórka jest edytowana. Edytor musi rozpocząć swoje działanie po kliknięciu komórki przez u ytkownika.
  • 460 Java 2. Techniki zaawansowane Klasa ,6CDNG wywołuje edytor dla danego zdarzenia (na przykład kliknięcia myszą), aby sprawdzić, czy spowoduje ono rozpoczęcie procesu edycji. Klasa #DUVTCEV%GNN'FKVQT defi- niuje metodę akceptującą wszystkie zdarzenia. RWDNKE DQQNGCP KU%GNN'FKVCDNG 'XGPV1DLGEV CP'XGPV ] TGVWTP VTWG _ Jeśli zastąpimy tę metodę, tak by zwracała wartość HCNUG, to tabela w ogóle nie umieści kom- ponentu edytora. Po zainstalowaniu edytora wywoływana jest metoda UJQWNF5GNGEV%GNN, prawdopodobnie dla tego samego zdarzenia. Metoda ta rozpocząć powinna proces edycji, na przykład otwie- rając okno dialogowe. RWDNKE DQQNGCP UJQWNF5GNGEV%GNN 'XGPV1DLGEV CP'XGPV ] EQNQT&KCNQIUGV8KUKDNG VTWG  TGVWTP VTWG _ Jeśli proces edycji będzie musiał zostać zatrzymany lub przerwany (poniewa u ytkownik wy- brał inną komórkę tabeli), to wywołana zostanie metoda UVQR%GNN'FKVKPI lub ECPEGN%GNN'FK VKPI. Powinniśmy wtedy zamknąć okno dialogowe. Wywołanie metody UVQR%GNN'FKVKPI ozna- cza, e tabela chce zachować wartość zmodyfikowaną w procesie edycji. Metoda powinna zwrócić wartość VTWG, jeśli wartość komórki jest dozwolona. W przypadku wyboru kolorów do- zwolona będzie dowolna wartość. Jednak jeśli tworzymy edytor innych rodzajów danych, to powinniśmy zawsze sprawdzać, czy powstała w procesie edycji wartość jest dozwolona. Po zakończeniu edycji nale y tak e wywołać metodę klasy bazowej, która obsługuje dla nas zdarzenia. RWDNKE XQKF ECPEGN%GNN'FKVKPI ] EQNQT&KCNQIUGV8KUKDNG HCNUG  UWRGTECPEGN%GNN'FKVKPI  _ Musimy dostarczyć tak e metodę, która umo liwi pobranie wartości powstałej w procesie edycji: RWDNKE 1DLGEV IGV%GNN'FKVQT8CNWG ] TGVWTP EQNQT%JQQUGTIGV%QNQT  _ Podsumowując, edytor powinien: 1. rozszerzać klasę #DUVTCEV%GNN'FKVQT i implementować interfejs 6CDNG%GNN'KVQT, 2. definiować metodę IGV6CDNG%GNN'FKVQT%QORQPGPV, która zwraca nieinteraktywny komponent w przypadku gdy edytor otworzy własne okno dialogowe lub komponent umo liwiający edycję wewnątrz komórki (na przykład lista rozwijalna bądź pole tekstowe),
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 461 3. definiować metody UJQWNF5GNGEV%GNN, UVQR%GNN'FKVKPI i ECPEGN%GNN'FKVKPI obsługujące rozpoczęcie, zakończenie i przerwanie procesu edycji; metody UVQR%GNN'FKVKPI i ECPEGN%GNN'FKVKPI wywoływać powinny te same metody klasy bazowej, aby zapewnić powiadomienie obiektów nasłuchujących, 4. definiować metodę IGV%GNN'FKVQT8CNWG zwracającą nową wartość komórki powstałą w procesie edycji. Na koniec musimy jeszcze wywołać metody UVQR%GNN'FKVKPI i ECPEGN%GNN'KFVKPI, gdy u ytkownik zakończy edycję. Tworząc okno dialogowe wyboru kolorów, opracujemy tak e obiekty nasłuchujące jego przycisków, które wywołają wspomniane metody. EQNQT&KCNQI  ,%QNQT%JQQUGTETGCVG&KCNQI PWNN 2NCPGV %QNQT  HCNUG EQNQT%JQQUGT PGY #EVKQP.KUVGPGT  QDKGMV PCU WEJWLæE[ RT[EKUMW 1- ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] UVQR%GNN'FKVKPI  _ _ PGY #EVKQP.KUVGPGT  QDKGMV PCU WEJWLæE[ RT[EKUMW %CPEGN ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] ECPEGN%GNN'FKVKPI  _ _  Proces edycji powinien zostać przerwany tak e na skutek zamknięcia okna dialogowego. Osiągniemy to, instalując obiekt nasłuchujący okna: EQNQT&KCNQICFF9KPFQY.KUVGPGT PGY 9KPFQY#FCRVGT ] RWDNKE XQKF YKPFQY%NQUKPI 9KPFQY'XGPV GXGPV ] ECPEGN%GNN'FKVKPI  _ _  W ten sposób zakończyliśmy implementację własnego edytora komórek. Wiemy te , w jaki sposób umo liwić edycję komórek i zainstalować edytor. Pozostaje jesz- cze tylko powiadomienie modelu tabeli o zmianie wartości edytowanej komórki. Po zakoń- czeniu edycji komórki klasa ,6CDNG wywołuje następującą metodę modelu tabeli: XQKF UGV8CNWG#V 1DLGEV XCNWG KPV T KPV E Musimy zastąpić tę metodę, aby przekazać do modelu nową wartość. Parametr XCNWG jest obiektem zwróconym przez edytor komórki. W przypadku edytora, który sami zaimple- mentowaliśmy, znamy typ obiektu zwróconego za pomocą metody IGV%GNN'FKVQT8CNWG. W przypadku edytora klasy &GHCWNV%GNN'FKVQT istnieją natomiast trzy mo liwości. Mo e to być typ $QQNGCP, jeśli edytor był polem wyboru lub łańcuch znaków, jeśli edytorem było pole tekstowe lub obiekt wybrany przez u ytkownika z listy rozwijalnej.
  • 462 Java 2. Techniki zaawansowane Jeśli obiekt XCNWG nie posiada odpowiedniego typu, nale y go w taki przekształcić. Sytuacja taka najczęściej zdarza się, gdy liczba edytowana jest w polu tekstowym. W naszym przy- kładzie lista rozwijalna wypełniona została obiektami klasy +PVGIGT, dlatego te nie ma potrzeby konwersji typu. Listing 6.13. TableCellRenderTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG QDKGMVÎY T[UWLæE[EJ MQOÎTMK K GF[VQTÎY MQOÎTGM VCDGNK
  •  RWDNKE ENCUU 6CDNG%GNN4GPFGT6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 6CDNG%GNN4GPFGT(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC VCDGNú FCP[EJ Q RNCPGVCEJ
  •  ENCUU 6CDNG%GNN4GPFGT(TCOG GZVGPFU ,(TCOG ] RWDNKE 6CDNG%GNN4GPFGT(TCOG ] UGV6KVNG 6CDNG%GNN4GPFGT6GUV  UGV5KG 9+&6* *'+)*6  6CDNG/QFGN OQFGN  PGY 2NCPGV6CDNG/QFGN  ,6CDNG VCDNG  PGY ,6CDNG OQFGN   KPUVCNWLG QDKGMV T[UWLæE[ K GF[VQT VCDNGUGV&GHCWNV4GPFGTGT %QNQTENCUU PGY %QNQT6CDNG%GNN4GPFGTGT  VCDNGUGV&GHCWNV'FKVQT %QNQTENCUU PGY %QNQT6CDNG%GNN'FKVQT  ,%QODQ$QZ OQQP%QODQ  PGY ,%QODQ$QZ  HQT KPV K   K   K OQQP%QODQCFF+VGO PGY +PVGIGT K  6CDNG%QNWOP/QFGN EQNWOP/QFGN  VCDNGIGV%QNWOP/QFGN  6CDNG%QNWOP OQQP%QNWOP  EQNWOP/QFGNIGV%QNWOP 2NCPGV6CDNG/QFGN/110A%1.7/0  OQQP%QNWOPUGV%GNN'FKVQT PGY &GHCWNV%GNN'FKVQT OQQP%QODQ 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 463  Y[ YKGVNC VCDGNú VCDNGUGV4QY*GKIJV   IGV%QPVGPV2CPG CFF PGY ,5ETQNN2CPG VCDNG  $QTFGT.C[QWV%'06'4  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • /QFGN VCDGNK RNCPGV QMTG NCLæE[ YCTVQ EK URQUÎD T[UQYCPKC K GF[ELK FCP[EJ
  •  ENCUU 2NCPGV6CDNG/QFGN GZVGPFU #DUVTCEV6CDNG/QFGN ] RWDNKE 5VTKPI IGV%QNWOP0COG KPV E ] TGVWTP EQNWOP0COGU=E? _ RWDNKE %NCUU IGV%QNWOP%NCUU KPV E ] TGVWTP EGNNU=?=E?IGV%NCUU  _ RWDNKE KPV IGV%QNWOP%QWPV ] TGVWTP EGNNU=?NGPIVJ _ RWDNKE KPV IGV4QY%QWPV ] TGVWTP EGNNUNGPIVJ _ RWDNKE 1DLGEV IGV8CNWG#V KPV T KPV E ] TGVWTP EGNNU=T?=E? _ RWDNKE XQKF UGV8CNWG#V 1DLGEV QDL KPV T KPV E ] EGNNU=T?=E?  QDL _ RWDNKE DQQNGCP KU%GNN'FKVCDNG KPV T KPV E ] TGVWTP E  0#/'A%1.7/0 ^^ E  /110A%1.7/0 ^^ E  )#5'175A%1.7/0 ^^ E  %1.14A%1.7/0 _ RWDNKE UVCVKE HKPCN KPV 0#/'A%1.7/0   RWDNKE UVCVKE HKPCN KPV /110A%1.7/0  
  • 464 Java 2. Techniki zaawansowane RWDNKE UVCVKE HKPCN KPV )#5'175A%1.7/0   RWDNKE UVCVKE HKPCN KPV %1.14A%1.7/0   RTKXCVG 1DLGEV=?=? EGNNU  ] ] /GTEWT[  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY PGY +OCIG+EQP /GTEWT[IKH _ ] 8GPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQT[GNNQY PGY +OCIG+EQP 8GPWUIKH _ ] 'CTVJ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNWG PGY +OCIG+EQP 'CTVJIKH _ ] /CTU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTTGF PGY +OCIG+EQP /CTUIKH _ ] ,WRKVGT  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG PGY +OCIG+EQP ,WRKVGTIKH _ ] 5CVWTP  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTQTCPIG PGY +OCIG+EQP 5CVWTPIKH _ ] 7TCPWU  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG PGY +OCIG+EQP 7TCPWUIKH _ ] 0GRVWPG  PGY &QWDNG   PGY +PVGIGT   $QQNGCP647' %QNQTDNWG PGY +OCIG+EQP 0GRVWPGIKH _ ] 2NWVQ  PGY &QWDNG   PGY +PVGIGT   $QQNGCP(#.5' %QNQTDNCEM PGY +OCIG+EQP 2NWVQIKH _ _ RTKXCVG 5VTKPI=? EQNWOP0COGU  ] 2NCPGV  4CFKWU  /QQPU  )CUGQWU  %QNQT  +OCIG _ _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 465 
  • -NCUC QDKGMVW T[UWLæEGIQ MQNQTQY[ RCPGN YGYPæVT MQOÎTMK
  •  ENCUU %QNQT6CDNG%GNN4GPFGTGT KORNGOGPVU 6CDNG%GNN4GPFGTGT ] RWDNKE %QORQPGPV IGV6CDNG%GNN4GPFGTGT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP KU5GNGEVGF DQQNGCP JCU(QEWU KPV TQY KPV EQNWOP ] RCPGNUGV$CEMITQWPF %QNQT XCNWG  TGVWTP RCPGN _  YTCECP[ LGUV RCPGN MVÎTGIQ MQNQT V C  QMTG NQP[ LGUV RTG QDKGMV %QNQT MQOÎTMK RTKXCVG ,2CPGN RCPGN  PGY ,2CPGN  _ 
  • 'F[VQT QVYKGTCLæE[ QMPQ FKCNQIQYG Y[DQTW MQNQTW
  •  ENCUU %QNQT6CDNG%GNN'FKVQT GZVGPFU #DUVTCEV%GNN'FKVQT KORNGOGPVU 6CDNG%GNN'FKVQT ] %QNQT6CDNG%GNN'FKVQT ] RCPGN  PGY ,2CPGN   RT[IQVQYWLG QMPQ FKCNQIQYG EQNQT%JQQUGT  PGY ,%QNQT%JQQUGT  EQNQT&KCNQI  ,%QNQT%JQQUGTETGCVG&KCNQI PWNN 2NCPGV %QNQT  HCNUG EQNQT%JQQUGT PGY #EVKQP.KUVGPGT  QDKGMV PCU WEJWLCE[ RT[EKUMW 1- ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] UVQR%GNN'FKVKPI  _ _ PGY #EVKQP.KUVGPGT  QDKGMV PCU WEJWLæE[ RT[EKUMW %CPEGN ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] ECPEGN%GNN'FKVKPI  _ _  EQNQT&KCNQICFF9KPFQY.KUVGPGT PGY 9KPFQY#FCRVGT ] RWDNKE XQKF YKPFQY%NQUKPI 9KPFQY'XGPV GXGPV ] ECPEGN%GNN'FKVKPI  _ _  _
  • 466 Java 2. Techniki zaawansowane RWDNKE %QORQPGPV IGV6CDNG%GNN'FKVQT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP KU5GNGEVGF KPV TQY KPV EQNWOP ]  VWVCL W[UMWLGO[ DKG æEæ YCTVQ è %QNQT  2TGEJQYWLGO[ Læ Y QDKGMEKG QMPC EQNQT%JQQUGTUGV%QNQT %QNQT XCNWG  TGVWTP RCPGN _ RWDNKE DQQNGCP UJQWNF5GNGEV%GNN 'XGPV1DLGEV CP'XGPV ]  TQRQEúEKG GF[ELK EQNQT&KCNQIUGV8KUKDNG VTWG   KPHQTOWLG OGVQFú Y[YQ WLæEæ Q TQRQEúEKW GF[ELK TGVWTP VTWG _ RWDNKE XQKF ECPEGN%GNN'FKVKPI ]  GF[ELC RTGTYCPC  CO[MC QMPQ FKCNQIQYG EQNQT&KCNQIUGV8KUKDNG HCNUG  UWRGTECPEGN%GNN'FKVKPI  _ RWDNKE DQQNGCP UVQR%GNN'FKVKPI ]  GF[ELC CMQ EQPC  CO[MC QMPQ FKCNQIQYG EQNQT&KCNQIUGV8KUKDNG HCNUG  UWRGTUVQR%GNN'FKVKPI   KPHQTOWLG OGVQFú G YCTVQ è MQNQTW LGUV FQYQNQPC TGVWTP VTWG _ RWDNKE 1DLGEV IGV%GNN'FKVQT8CNWG ] TGVWTP EQNQT%JQQUGTIGV%QNQT  _ RTKXCVG %QNQT EQNQT RTKXCVG ,%QNQT%JQQUGT EQNQT%JQQUGT RTKXCVG ,&KCNQI EQNQT&KCNQI RTKXCVG ,2CPGN RCPGN _ LCXCZUYKPI,6CDNG n XQKF UGV4QY*GKIJV KPV JGKIJV nadaje wszystkim wierszom tabeli wysokość JGKIJV pikseli. n XQKF UGV4QY*GKIJV KPV TQY KPV JGKIJV nadaje danemu wierszowi tabeli wysokość JGKIJV pikseli. n XQKF UGV4QY/CTIKP KPV OCTIKP określa wolną przestrzeń między sąsiednimi wierszami.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 467 n KPV IGV4QY*GKIJV pobiera domyślną wysokość wszystkich wierszy w tabeli. n KPV IGV4QY*GKIJV KPV TQY pobiera wysokość danego wiersza tabeli. n KPV IGV4QY/CTIKP pobiera wielkość wolnej przestrzeni między sąsiednimi wierszami. n 4GEVCPING IGV%GNN4GEV KPV TQY KPV EQNWOP DQQNGCP KPENWFG5RCEKPI zwraca obszar komórki tabeli. Parametry: TQY, EQNWOP wiersz i kolumna tabeli, KPENWFG5RCEKPI wartość VTWG, jeśli obszar uwzględniać ma marginesy. n %QNQT IGV5GNGEVKQP$CEMITQWPF n %QNQT IGV5GNGEVKQP(QTGITQWPF Zwracają kolory u ywane dla prezentacji komórki wybranej przez u ytkownika. LCXCZUYKPIVCDNG6CDNG/QFGN n %NCUU IGV%QNWOP%NCUU KPV EQNWOP+PFGZ zwraca klasę obiektów danej kolumny. Informacja ta wykorzystywana jest przez obiekty rysujące i komórki. LCXCZUYKPIVCDNG6CDNG%GNN4GPFGTGT n %QORQPGPV IGV6CDNG%GNN4GPFGTGT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP UGNGEVGF DQQNGCP JCU(QEWU KPV TQY KPV EQNWOP zwraca komponent, którego metoda RCKPV wywoływana jest w celu narysowania komórki tabeli. Parametry: VCDNG tabela zawierająca rysowaną komórkę, XCNWG obiekt rysowanej komórki, UGNGEVGF wartość VTWG, jeśli komórka jest wybrana, JCU(QEWU wartość VTWG, jeśli komórka jest przeglądana, TQY, EQNWOP wiersz i kolumna komórki. LCXCZUYKPIVCDNG6CDNG%QNWOP/QFGN n 6CDNG%QNWOP IGV%QNWOP KPV KPFGZ zwraca obiekt kolumny tabeli o danym indeksie. LCXCZUYKPIVCDNG6CDNG%QNWOP n XQKF UGV%GNN'FKVQT 6CDNG%GNN'FKVQT GFKVQT n XQKF UGV%GNN4GPFGTGT 6CDNG%GNN4GPFGTGT TGPFGTGT Instalują edytor i obiekt rysujący dla wszystkich komórek danej kolumny.
  • 468 Java 2. Techniki zaawansowane LCXCZUYKPI&GHCWNV%GNN'FKVQT n &GHCWNV%GNN'FKVQT ,%QODQ$QZ EQODQ$QZ tworzy edytor komórek wykorzystujący listę rozwijalną do wyboru wartości. LCXCZUYKPI%GNN'FKVQT n DQQNGCP KU%GNN'FKVCDNG 'XGPV1DLGEV GXGPV zwraca wartość VTWG, jeśli zdarzenie rozpocznie proces edycji komórki. n DQQNGCP UJQWNF5GNGEV%GNN 'XGPV1DLGEV CP'XGPV rozpoczyna proces edycji. Zwraca wartość VTWG, jeśli edytowana komórka powinna zostać wybrana. Wartość HCNUG powinna być zwrócona, jeśli nie chcemy, by proces edycji zmieniał wybór komórek. n XQKF ECPEGN%GNN'FKVKPI przerywa proces edycji. Wartość powstała na skutek edycji mo e być porzucona. n DQQNGCP UVQR%GNN'FKVKPI kończy proces edycji. Wartość powstała na skutek edycji mo e być wykorzystana. Zwraca wartość VTWG, jeśli wartość powstała na skutek edycji jest dozwolona i mo e być pobrana. n 1DLGEV IGV%GNN'FKVQT8CNWG zwraca edytowaną wartość. n XQKF CFF%GNN'FKVQT.KUVGPGT %GNN'FKVQT.KUVGPGT N n XQKF TGOQXG%GNN'FKVQT.KUVGPGT %GNN'FKVQT.KUVGPGT N Dodają i usuwają obowiązkowy obiekt nasłuchujący edytora. LCXCZUYKPIVCDNG6CDNG%GNN'FKVQT n %QORQPGPV IGV6CDNG%GNN'FKVQT%QORQPGPV ,6CDNG VCDNG 1DLGEV XCNWG DQQNGCP UGNGEVGF KPV TQY KPV EQNWOP zwraca komponent, którego metoda RCKPV wywoływana jest w celu narysowania komórki tabeli. Parametry: VCDNG tabela zawierająca rysowaną komórkę, XCNWG obiekt rysowanej komórki, UGNGEVGF wartość VTWG, jeśli komórka jest wybrana, TQY, EQNWOP wiersz i kolumna komórki. LCXCZUYKPI,%QNQT%JQQUGT n ,%QNQT%JQQUGT tworzy obiekt wyboru koloru. Początkowo wybrany jest kolor biały. n %QNQT IGV%QNQT n XQKF UGV%QNQT %QNQT E Pobierają i ustawiają kolor wybrany przez obiekt wyboru.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 469 n UVCVKE ,&KCNQI ETGCVG&KCNQI %QORQPGPV RCTGPV 5VTKPI VKVNG DQQNGCP OQFCN ,%QNQT%JQQUGT EJQQUGT #EVKQP.KUVGPGT QM.KUVGPGT #EVKQP.KUVGPGT ECPEGN.KUVGPGT tworzy okno dialogowe wyboru koloru. Parametry: RCTGPV komponent, nad którym pojawić ma się okno dialogowe, VKVNG tytuł okna dialogowego, OQFCN wartość VTWG, jeśli okno blokować ma wykonanie aplikacji do momentu jego zamknięcia, EJQQUGT obiekt wyboru koloru, QM.KUVGPGT, obiekty nasłuchujące przycisków OK i Cancel. ECPEGN.KUVGPGT n UVCVKE %QNQT UJQY&KCNQI %QORQPGPV EQORQPGPV 5VTKPI VKVNG %QNQT KPKVKCN%QNQT tworzy i wyświetla modalne okno dialogowe wyboru koloru. Parametry: EQORQPGPV komponent, nad którym pojawić ma się okno dialogowe, VKVNG tytuł okna dialogowego, KPKVKCN%QNQT początkowo wybrany kolor. Operacje na wierszach i kolumnach W podrozdziale tym poka emy, w jaki sposób wykonywać operacje na wierszach i kolum- nach tabeli. Podczas lektury tego materiału musimy pamiętać przede wszystkim, e tabele biblioteki Swing są asymetryczne, czyli na wierszach mo na wykonywać inne operacje ni na kolumnach. Komponent tabeli zaprojektowano z myślą o prezentacji informacji w po- staci wierszy o tej samej strukturze, takich jak na przykład rekordy będące wynikiem za- pytania do bazy danych, a nie dla prezentacji dowolnej dwuwymiarowej siatki obiektów. Zmiana szerokości kolumn Klasa 6CDNG%QNWOP udostępnia metody umo liwiające nadzór nad zmianami szerokości ko- lumny wykonywanymi przez u ytkownika. Programista mo e określić preferowaną, naj- mniejszą i największą szerokość kolumny, korzystając z poni szych metod. XQKF UGV2TGHGTTGF9KFVJ KPV YKFVJ XQKF UGV/KP9KFVJ KPV YKFVJ XQKF UGV/CZ9KFVJ KPV YKFVJ Informacja ta wykorzystywana jest przez komponent tabeli podczas jej wyświetlania. Metoda XQKF UGV4GUKCDNG DQQNGCP TGUKCDNG zezwala lub zabrania u ytkownikowi zmieniać szerokość kolumny. Szerokość kolumny mo na tak e zmieniać programowo, korzystając z poni szej metody. XQKF UGV9KFVJ KPV YKFVJ
  • 470 Java 2. Techniki zaawansowane Gdy zmieniana jest szerokość kolumny, to domyślnie całkowita szerokość tabeli nie ulega zmianie. Oznacza to, e zmiana szerokości kolumny spowoduje tak e zmianę szerokości kolumn tabeli, le ących od niej na prawo. Zachowanie takie jest o tyle rozsądne, e po- zwala u ytkownikowi dostosować szerokość kolejnych kolumn, poruszając się od lewej strony tabeli ku prawej. Zachowanie to mo emy zmienić na jedno z wymienionych w tabeli 6.2 za pomocą metody XQKF UGV#WVQ4GUKG/QFG KPV OQFG udostępnianej przez klasę ,6CDNG. Tabela 6.2. Tryby zmiany szerokości kolumn Tryb Zachowanie #761A4'5+<'A1(( Nie zmienia szerokości innych kolumn, ale szerokość całej tabeli. #761A4'5+<'A0':6A%1.7/0 Zmienia jedynie szerokość następnej kolumny. #761A4'5+<'A57$5'37'06A%1.7/05 Zmienia równo szerokość wszystkich następnych kolumn. Zachowanie domyślne. #761A4'5+<'A.#56A%1.7/0 Zmienia jedynie szerokość ostatniej kolumny. #761A4'5+<'A#..A%1.7/05 Zmienia szerokość wszystkich kolumn tabeli. Zachowanie to najczęściej nie jest właściwe, poniewa uniemo liwia u ytkownikowi określenie szerokości więcej ni jednej kolumny. Wybór wierszy, kolumn i komórek W zale ności od trybu wyboru u ytkownik wybierać mo e wiersze, kolumny bądź komórki tabeli. Domyślnym trybem wyboru jest tryb zezwalający na wybór wierszy tabeli. Wybra- nie komórki powoduje automatycznie wybranie całego wiersza (patrz rysunek 6.36). Wy- wołanie VCDNGUGV4QY5GNGEVKQP#NNQYGF HCNUG wyłącza mo liwość wyboru wierszy. Rysunek 6.36. Wybór wiersza tabeli
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 471 Jeśli tryb wyboru wierszy jest włączony, to mo emy określić, czy u ytkownikowi wolno wybrać pojedynczy wiersz, ciągły zakres wierszy bądź dowolny zbiór wierszy. W tym celu musimy pobrać model wyboru i skorzystać z jego metody UGV5GNGEVKQP/QFG: VCDNGIGV5GNGEVKQP/QFGN UGV5GNGEVKQP/QFG OQFG  Parametr OQFG przyjmować mo e jedną z trzech wartości: .KUV5GNGEVKQP/QFG5+0).'A5'.'%6+10 .KUV5GNGEVKQP/QFG5+0).'A+06'48#.A5'.'%6+10 .KUV5GNGEVKQP/QFG/7.6+2.'A+06'48#.A5'.'%6+10 Wybór kolumn jest domyślnie zabroniony. Mo emy go umo liwić, wywołując VCDNGUGV%QNWOP5GNGEVKQP#NNQYGF VTWG Zezwolenie na równoczesny wybór wierszy i kolumn oznacza mo liwość wyboru komórek tabeli. U ytkownik mo e wtedy wybierać zakresy komórek, jak pokazano na rysunku 6.37. Wybór komórek umo liwić mo emy tak e, korzystając z metody VCDNGUGV%GNN5GNGEVKQP'PCDNGF VTWG Rysunek 6.37. Wybór zakresu komórek tabeli We wczesnych wersjach biblioteki Swing dopuszczenie równoczesnego wyboru wierszy i kolumn powodowało, że wybranie komórki powodowało automatycznie wybranie za- wierającego ją wiersza i kolumny. Informację o wybranych wierszach i kolumnach mo emy uzyskać, wywołując metody IGV 5GNGEVGF4QYU i IGV5GNGEVGF%QNWOPU. Metody te zwracają tablice KPV=? zawierające indeksy wybranych wierszy bądź kolumn. Program, którego kod źródłowy zawiera listing 6.14, umo liwia obserwację sposobu wybo- ru elementów tabeli. Jego menu umo liwia włączanie lub wyłączanie mo liwości wyboru wierszy, kolumn i komórek tabeli. Ukrywanie kolumn Metoda TGOQXG%QNWOP klasy ,6CDNG usuwa kolumnę z widoku tabeli. Dane kolumny nie są usuwane z modelu tabeli, a jedynie ukrywane przed jej widokiem. Parametrem metody
  • 472 Java 2. Techniki zaawansowane TGOQXG%QNWOP jest obiekt klasy 6CDNG%QNWOP . Jeśli dysponujemy numerem kolumny (na przykład zwróconym przez metodę IGV5GNGEVGF%QNWOPU), to musimy najpierw pobrać od modelu kolumn tabeli odpowiedni obiekt reprezentujący kolumnę: 6CDNG%QNWOP/QFGN EQNWOP/QFGN  VCDNGIGV%QNWOP/QFGN  6CDNG%QNWOP EQNWOP  EQNWOP/QFGNIGV%QNWOP  VCDNGTGOQXG%QNWOP EQNWOP  Jeśli zapamiętamy obiekt kolumny, to mo emy później wstawić go z powrotem do tabeli: VCDNGCFF%QNWOP EQNWOP  Wywołanie tej metody spowoduje dodanie kolumny jako ostatniej kolumny tabeli. Jeśli chcemy ją umieścić w innym miejscu tabeli, to musimy skorzystać jeszcze z metody OQXG%QNWOP. Nową kolumnę mo emy dodać tak e, tworząc nowy obiekt klasy 6CDNG%QNWOP o indeksie odpowiadającym numerowi kolumny w modelu. VCDNGCFF%QNWOP PGY 6CDNG%QNWOP OQFGN%QNWOP+PFGZ  Mo emy utworzyć wiele obiektów tej klasy, które stanowić będą reprezentacje jednej i tej samej kolumny modelu. Klasa ,6CDNG nie dysponuje metodami, które umo liwiałyby wstawienie lub usunięcie ko- lumny z modelu. A tak e metodami, które umo liwiałyby ukrycie wierszy. Jeśli chcemy ukrywać wiersze tabeli, musimy utworzyć model filtra podobny do pokazanego wcześniej modelu filtra sortującego. Dodawanie i usuwanie wierszy w domyślnym modelu tabeli Klasa &GHCWNV6CDNG/QFGN jest klasą konkretną implementującą interfejs 6CDNG/QFGN. Prze- chowuje ona dwuwymiarową siatkę obiektów. Jeśli posiadamy ju dane zorganizowane w postaci tabelarycznej, to oczywiście nie ma sensu kopiować ich do domyślnego modelu tabeli. Jego zastosowanie jest jednak bardzo wygodne, jeśli musimy szybko utworzyć ta- belę reprezentującą niewielki zbiór danych. Klasa &GHCWNV6CDNG/QFGN dysponuje przy tym metodami umo liwiającymi dodawanie wierszy oraz kolumn, a tak e usuwanie wierszy. Metody CFF4QY i CFF%QNWOP dodają odpowiednio nowy wiersz lub kolumnę. Przekazujemy im tablicę 1DLGEV=? lub wektor zawierający nowe dane. Metodzie CFF%QNWOP musimy prze- kazać tak e nazwę nowej kolumny. Obie metody umieszczają nowe elementy tabeli na końcu siatki. Aby wstawić wiersz pomiędzy wiersze ju istniejące w tabeli, mo emy sko- rzystać z metody KPUGTV4QY. Niestety dla kolumn nie jest dostępna analogiczna metoda. Metoda TGOQXG4QY usuwa wiersz z modelu tabeli. Równie w tym przypadku nie istnieje ta- ka metoda dla kolumn. Poniewa obiekt klasy ,6CDNG rejestruje się jako obiekt nasłuchujący modelu tabeli, to wi- dok tabeli jest powiadamiany za ka dym razem, gdy wstawiane są lub usuwane dane z mo- delu. Umo liwia to aktualizację widoku tabeli.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 473 Program, którego kod źródłowy zamieszczamy w listingu 6.14, stanowi ilustrację operacji wyboru i edycji tabeli. W modelu tabeli umieściliśmy prosty zbiór danych (tabliczkę mno- enia). Menu Edit programu umo liwia: n ukrycie wszystkich wybranych kolumn, n przywrócenie wszystkich kolumn, które zostały kiedykolwiek ukryte, n usunięcie wybranych wierszy z tabeli, n dodanie wiersza danych na końcu danych modelu. Przykład ten kończy omówienie komponentu tabel. Zrozumienie sposobów wykorzystania tabel jest nieco łatwiejsze ni w przypadku drzew, poniewa prezentowany za pomocą tabeli model danych jest prostszy koncepcyjnie. Jednak sama implementacja komponentu tabeli jest w rzeczywistości bardziej skomplikowana ni w przypadku komponentu drzewa. Przy- czyniają się do tego mo liwości zmiany szerokości kolumn, dodawania własnych obiektów rysujących i edytorów. W rozdziale tym skoncentrowaliśmy się na zagadnieniach, które po- siadają największą przydatność w praktyce programisty, a więc prezentacji tabel bazy da- nych za pomocą komponentu tabeli, sortowaniu tabel oraz wykorzystaniu własnych obiek- tów rysujących i edytorów. Jeśli potrzebować będziemy informacji dotyczących bardziej zaawansowanych lub nietypowych zastosowań tabeli, to po raz kolejny wrócimy do ksią ek Core Java Foundation Classes autorstwa Kim Topley oraz Graphic Java 2 napisanej przez Davida Geary’ego. Listing 6.14. TableSelectionTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCVGZV
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIVCDNG
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[DÎT FQFCYCPKG K WUWYCPKG YKGTU[ QTC MQNWOP VCDGNK
  •  RWDNKE ENCUU 6CDNG5GNGEVKQP6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 6CDNG5GNGEVKQP(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC VCDNKEMú OPQ GPKC K RQUKCFCLæEC OGPW WOQ NKYKCLæEG QMTG NGPKG VT[DW Y[DQTW YKGTUGMQNWOP[MQOÎTMK QTC FQFCYCPKG K WUWYCPKG YKGTU[ K MQNWOP
  •  ENCUU 6CDNG5GNGEVKQP(TCOG GZVGPFU ,(TCOG ]
  • 474 Java 2. Techniki zaawansowane RWDNKE 6CDNG5GNGEVKQP(TCOG ] UGV6KVNG 6CDNG5GNGEVKQP6GUV  UGV5KG 9+&6* *'+)*6   VYQT[ VCDNKEMú OPQ GPKC OQFGN  PGY &GHCWNV6CDNG/QFGN    HQT KPV K   K  OQFGNIGV4QY%QWPV  K HQT KPV L   L  OQFGNIGV%QNWOP%QWPV  L OQFGNUGV8CNWG#V PGY +PVGIGT K 
  • L   K L  VCDNG  PGY ,6CDNG OQFGN  %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF PGY ,5ETQNN2CPG VCDNG  %GPVGT  TGOQXGF%QNWOPU  PGY #TTC[.KUV   VYQT[ OGPW ,/GPW$CT OGPW$CT  PGY ,/GPW$CT  UGV,/GPW$CT OGPW$CT  ,/GPW UGNGEVKQP/GPW  PGY ,/GPW 5GNGEVKQP  OGPW$CTCFF UGNGEVKQP/GPW  HKPCN ,%JGEM$QZ/GPW+VGO TQYU+VGO  PGY ,%JGEM$QZ/GPW+VGO 4QYU  HKPCN ,%JGEM$QZ/GPW+VGO EQNWOPU+VGO  PGY ,%JGEM$QZ/GPW+VGO %QNWOPU  HKPCN ,%JGEM$QZ/GPW+VGO EGNNU+VGO  PGY ,%JGEM$QZ/GPW+VGO %GNNU  TQYU+VGOUGV5GNGEVGF VCDNGIGV4QY5GNGEVKQP#NNQYGF  EQNWOPU+VGOUGV5GNGEVGF VCDNGIGV%QNWOP5GNGEVKQP#NNQYGF  EGNNU+VGOUGV5GNGEVGF VCDNGIGV%GNN5GNGEVKQP'PCDNGF  TQYU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VCDNGENGCT5GNGEVKQP  VCDNGUGV4QY5GNGEVKQP#NNQYGF TQYU+VGOKU5GNGEVGF  EGNNU+VGOUGV5GNGEVGF VCDNGIGV%GNN5GNGEVKQP'PCDNGF  _ _  UGNGEVKQP/GPWCFF TQYU+VGO  EQNWOPU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 475 ] VCDNGENGCT5GNGEVKQP  VCDNGUGV%QNWOP5GNGEVKQP#NNQYGF EQNWOPU+VGOKU5GNGEVGF  EGNNU+VGOUGV5GNGEVGF VCDNGIGV%GNN5GNGEVKQP'PCDNGF  _ _  UGNGEVKQP/GPWCFF EQNWOPU+VGO  EGNNU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VCDNGENGCT5GNGEVKQP  VCDNGUGV%GNN5GNGEVKQP'PCDNGF EGNNU+VGOKU5GNGEVGF  TQYU+VGOUGV5GNGEVGF VCDNGIGV4QY5GNGEVKQP#NNQYGF  EQNWOPU+VGOUGV5GNGEVGF VCDNGIGV%QNWOP5GNGEVKQP#NNQYGF  _ _  UGNGEVKQP/GPWCFF EGNNU+VGO  ,/GPW VCDNG/GPW  PGY ,/GPW 'FKV  OGPW$CTCFF VCDNG/GPW  ,/GPW+VGO JKFG%QNWOPU+VGO  PGY ,/GPW+VGO *KFG %QNWOPU  JKFG%QNWOPU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] KPV=? UGNGEVGF  VCDNGIGV5GNGEVGF%QNWOPU  6CDNG%QNWOP/QFGN EQNWOP/QFGN  VCDNGIGV%QNWOP/QFGN   WUWYC MQNWOP[ YKFQMW VCDGNK RQEæYU[ QF  PCLY[ UGIQ KPFGMUW CD[ PKG OKGPKCè PWOGTÎY MQNWOP HQT KPV K  UGNGEVGFNGPIVJ   K   K ] 6CDNG%QNWOP EQNWOP  EQNWOP/QFGNIGV%QNWOP UGNGEVGF=K?  VCDNGTGOQXG%QNWOP EQNWOP   RTGEJQYWLG WMT[VG MQNWOP[ FQ RQPQYPGL RTGGPVCELK TGOQXGF%QNWOPUCFF EQNWOP  _ _ _  VCDNG/GPWCFF JKFG%QNWOPU+VGO 
  • 476 Java 2. Techniki zaawansowane ,/GPW+VGO UJQY%QNWOPU+VGO  PGY ,/GPW+VGO 5JQY %QNWOPU  UJQY%QNWOPU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ]  RT[YTCEC YU[UVMKG WUWPKúVG FQVæF MQNWOP[ HQT KPV K   K  TGOQXGF%QNWOPUUKG  K VCDNGCFF%QNWOP 6CDNG%QNWOP TGOQXGF%QNWOPUIGV K  TGOQXGF%QNWOPUENGCT  _ _  VCDNG/GPWCFF UJQY%QNWOPU+VGO  ,/GPW+VGO CFF4QY+VGO  PGY ,/GPW+VGO #FF 4QY  CFF4QY+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ]  FQFCLG PQY[ YKGTU VCDNKEMK OPQ GPKC FQ OQFGNW +PVGIGT=? PGY%GNNU  PGY +PVGIGT=OQFGNIGV%QNWOP%QWPV ? HQT KPV K   K  PGY%GNNUNGPIVJ K PGY%GNNU=K?  PGY +PVGIGT K 
  • OQFGNIGV4QY%QWPV   OQFGNCFF4QY PGY%GNNU  _ _  VCDNG/GPWCFF CFF4QY+VGO  ,/GPW+VGO TGOQXG4QYU+VGO  PGY ,/GPW+VGO 4GOQXG 4QYU  TGOQXG4QYU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] KPV=? UGNGEVGF  VCDNGIGV5GNGEVGF4QYU   WUWYC YKGTUG OQFGNW TQRQE[PCLæE QF PCLY[ UGIQ KPFGMUW  CD[ PKG OKGPKCè PWOGTÎY YKGTU[ HQT KPV K  UGNGEVGFNGPIVJ   K   K OQFGNTGOQXG4QY UGNGEVGF=K?  _ _  VCDNG/GPWCFF TGOQXG4QYU+VGO  ,/GPW+VGO ENGCT%GNNU+VGO  PGY ,/GPW+VGO %NGCT %GNNU  ENGCT%GNNU+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ]
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 477  PCFCLG Y[DTCP[O MQOÎTMQO YCTVQ è  HQT KPV K   K  VCDNGIGV4QY%QWPV  K HQT KPV L   L  VCDNGIGV%QNWOP%QWPV  L KH VCDNGKU%GNN5GNGEVGF K L VCDNGUGV8CNWG#V PGY +PVGIGT   K L  _ _  VCDNG/GPWCFF ENGCT%GNNU+VGO  _ RTKXCVG &GHCWNV6CDNG/QFGN OQFGN RTKXCVG ,6CDNG VCDNG RTKXCVG #TTC[.KUV TGOQXGF%QNWOPU RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ LCXCZUYKPI,6CDNG n XQKF UGV#WVQ4GUKG/QFG KPV OQFG określa tryb zmiany szerokości kolumn. Parametry: OQFG jedna z wartości #761A4'5+<'A1((, #761A4'5+<'A 0':6A%1.7/0, #761A4'5+<'A57$5'37'06A%1.7/05, #761A4'5+<'A.#56A%1.7/0, #761A4'5+<'A#..A%1.7/05. n .KUV5GNGEVKQP/QFGN IGV5GNGEVKQP/QFGN zwraca model wyboru, który umo liwia następnie określenie trybu wyboru. n XQKF UGV4QY5GNGEVKQP#NNQYGF DQQNGCP D , jeśli D posiada wartość VTWG, to kliknięcie komórki tabeli powoduje wybranie całego wiersza. n XQKF UGV%QNWOP5GNGEVKQP#NNQYGF DQQNGCP D , jeśli D posiada wartość VTWG, to kliknięcie komórki tabeli powoduje wybranie całej kolumny. n XQKF UGV4QY5GNGEVKQP'PCDNGF DQQNGCP D , jeśli D posiada wartość VTWG, to mo liwy jest wybór poszczególnych komórek tabeli. Taki sam rezultat daje wywołanie kolejno metod UGV4QY5GNGEVKQP#NNQYGF D i UGV%QNWOP5GNGEVKQP#NNQYGF D . n DQQNGCP IGV4QY5GNGEVKQP#NNQYGF zwraca wartość VTWG, jeśli dozwolony jest wybór wierszy tabeli. n DQQNGCP IGV%QNWOP5GNGEVKQP#NNQYGF zwraca wartość VTWG, jeśli dozwolony jest wybór kolumn tabeli. n DQQNGCP IGV%GNN5GNGEVKQP'PCDNGF zwraca wartość VTWG, jeśli dozwolony wybór wierszy i kolumn tabeli. n XQKF CFF%QNWOP 6CDNG%QNWOP EQNWOP dodaje kolumnę do widoku tabeli. n XQKF OQXG%QNWOP KPV HTQO KPV VQ przesuwa kolumnę o indeksie HTQO w taki sposób, e jej indeksem staje się VQ. Operacja ta dotyczy jedynie widoku tabeli. n XQKF TGOQXG%QNWOP 6CDNG%QNWOP EQNWOP usuwa kolumnę z widoku tabeli.
  • 478 Java 2. Techniki zaawansowane LCXCZUYKPIVCDNG6CDNG%QNWOP n 6CDNG%QNWOP KPV OQFGN%QNWOP+PFGZ tworzy obiekt reprezentujący kolumnę tabeli o danym indeksie. n XQKF UGV2TGHGTTGF9KFVJ KPV YKFVJ n XQKF UGV/KP9KFVJ KPV YKFVJ n XQKF UGV/CZ9KFVJ KPV YKFVJ Określają preferowaną, najmniejszą i największą szerokość danej kolumny. n XQKF UGV9KFVJ KPV YKFVJ ustawia bie ącą szerokość danej kolumny. n XQKF UGV4GUKCDNG DQQNGCP D , jeśli D posiada wartość VTWG, to u ytkownik mo e zmieniać szerokość kolumny. LCXCZUYKPI.KUV5GNGEVKQP/QFGN n XQKF UGV5GNGEVKQP/QFG KPV OQFG określa tryb wyboru. Parametry: OQFG jedna z wartości 5+0).'A5'.'%6+10, 5+0).'A+06'48#.A 5'.'%6+10 i /7.6+2.'A+06'48#.A5'.'%6+10. LCXCZUYKPIVCDNG&GHCWNV6CDNG/QFGN n XQKF CFF4QY 1DLGEV=? TQY&CVC n XQKF CFF%QNWOP 1DLGEV EQNWOP0COG 1DLGEV=? EQNWOP&CVC Dodaje wiersz lub kolumnę na końcu modelu danych. n XQKF KPUGTV4QY KPV TQY 1DLGEV=? TQY&CVC dodaje wiersz danych na pozycji o indeksie TQY. n XQKF TGOQXG4QY KPV TQY usuwa wiersz z modelu. n XQKF OQXG4QY KPV UVCTV KPV GPF KPV VQ przesuwa wszystkie wiersze o indeksach z przedziału od UVCTV do GPF na nowe pozycje zaczynające się od indeksu VQ. Komponenty formatujące tekst W ksią ce Java 2. Podstawy omówiliśmy podstawowe komponenty związane z edycją tek- stu, takie jak ,6GZV(KGNF i ,6GZV#TGC. Klasy te są przydatne do pobierania tekstu wprowa- dzanego przez u ytkownika. Istnieje tak e klasa ,'FKVQT2CPG, która wyświetla i umo liwia edycję tekstu zapisanego w formatach RTF i HTML. (Format RTF u ywany jest przez sze- reg aplikacji firmy Microsoft do wymiany dokumentów. Jest słabo udokumentowany i nawet aplikacje firmy Microsoft mają problemy z jego prawidłowym wykorzystaniem. W ksią ce tej nie będziemy zajmować się wykorzystaniem tego formatu. Sama firma Sun twierdzi, e obsługa tego formatu w bibliotekach Java jest jedynie fragmentaryczna. Nie zdziwimy się więc, jeśli w kolejnych wersjach zostanie w ogóle usunięta. Zwłaszcza e po- prawa wsparcia formatu HTML będzie kosztować jeszcze sporo wysiłku).
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 479 Musimy przyznać, e mo liwości klasy ,'FKVQT2CPG są w obecnym stanie dość ograniczo- ne. Potrafi ona wyświetlić proste strony w formacie HTML, ale z większością stron, które mo emy spotkać obecnie w sieci, Internet ma problemy. Równie edytor HTML nie posia- da du ych mo liwości, ale to akurat nie jest du ym ograniczeniem, poniewa rzadko która aplikacja wymaga od u ytkownika edytowania pliku w formacie HTML. Dobrym zastosowaniem klasy ,'FKVQT2CPG mo e być wyświetlanie zawartości systemu pomocy zapisanej w formacie HTML. Poniewa korzystamy wtedy z własnych plików źró- dłowych HTML, to mo emy unikać w nich konstrukcji, z którymi klasa ,'FKVQT2CPG obec- nie sobie nie radzi. Więcej informacji na temat tworzenia systemów pomocy dla profesjonalnych aplikacji znajdziemy pod adresem http://java.sun.com/products/javahelp/index.html. Klasa pochodna ,6GZV2CPG klasy ,'FKVQT2CPG umożliwia przechowywanie i edycję tek- stu sformatowanego przy użyciu różnych czcionek z możliwością umieszczania w nim różnych komponentów. Jeśli będziemy chcieli utworzyć aplikację umożliwiającą użyt- kownikowi formatowanie tekstu, to powinniśmy najpierw zapoznać się z programem demonstracyjnym StylePad dołączonym do SDK. Program, którego kod zamieszczamy w listingu 6.15, korzysta z panelu edytora w celu wy- świetlenia zawartości strony w języku HTML. W dolnej części jego okna umieszczone jest pole tekstowe, w którym wprowadzić nale y adres URL. Musi ona zaczynać się od JVVR lub HKNG. Wybranie przycisku Load spowoduje wyświetlenie w panelu edytora strony o podanym adresie (patrz rysunek 6.38). Rysunek 6.38. Panel edytora wyświetlający stronę HTML Hiperłącza na wyświetlonej stronie są aktywne i wybranie jednego z nich spowoduje zała- dowanie kolejnej strony. Przycisk Back umo liwia powrót do poprzedniej strony. Program ten jest właściwie prostą przeglądarką stron internetowych. Oczywiście nie posia- da on mo liwości komercyjnie dostępnych przeglądarek, takich jak listy zakładek czy bufo- rowanie stron. Panel edytora nie umo liwia te wyświetlania apletów.
  • 480 Java 2. Techniki zaawansowane Jeśli zaznaczymy pole wyboru Editable, to panel edytora umo liwi nam edycję załadowa- nej strony. Mo emy wpisywać w nim tekst lub usuwać go, korzystając z klawisza Backspa- ce. Panel edytora obsługuje tak e kombinacje klawiszy Ctrl+X, Ctrl+C, Ctrl+V umo li- wiające wycinanie, kopiowanie i wklejanie tekstu. Jednak umo liwienie formatowania tekstu wymagałoby jeszcze sporo pracy. Gdy panel edytora umo liwia edycję strony, to umieszczone na niej hiperłącza nie są aktyw- ne. Dla niektórych stron edytor pokazuje tak e teksty etykiet HTML, komentarze i polecenia języka Javascript (patrz rysunek 6.39). Jest to przydatne do sprawdzenia mo liwości kompo- nentu klasy ,'FKVQT2CPG, ale nie powinno być udostępniane w zwykłych programach. Rysunek 6.39. Panel edytora w trybie edycji Domyślnie komponent klasy ,'FKVQT2CPG znajduje się w stanie edycji. Możemy to zmienić, wywołując metodę GFKVQT2CPGUGV'FKVCDNG HCNUG . Przedstawione mo liwości panelu edytora dają się łatwo wykorzystać. Do załadowania no- wego dokumentu u ywamy metody UGV2CIG. Jej parametrem jest łańcuch znaków bądź obiekt klasy 74.. Klasa ,'FKVQT2CPG jest klasą pochodną klasy ,6GZV%QORQPGPV. Dlatego mo emy te u yć metody UGV6GZV, jeśli chcemy umieścić w panelu zwykły, a nie sforma- towany tekst. Aby nasłuchiwać zdarzeń wyboru hiperłącza, tworzymy obiekt implementujący interfejs *[RGTNKPM.KUVGPGT. Interfejs ten zawiera tylko jedną metodę, J[RGTNKPM7RFCVG, która wy- woływana jest, gdy u ytkownik przesuwa kursor myszy ponad hiperłączem lub wybiera je. Metoda posiada parametr typu *[RGTNKPM'XGPV. Aby dowiedzieć się o rodzaju zdarzenia, musimy wywołać metodę IGV'XGPV6[RG, która zwrócić mo e jedną z trzech poni szych wartości: *[RGTNKPM'XGPV'XGPV6[RG#%6+8#6'& *[RGTNKPM'XGPV'XGPV6[RG'06'4'& *[RGTNKPM'XGPV'XGPV6[RG':+6'&
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 481 Pierwsza z wartości oznacza, e u ytkownik kliknął łącze. W takiej sytuacji zwykle bę- dziemy chcieli załadować nową stronę. Pozostałe wartości mo emy wykorzystać na przy- kład do wyświetlania wskazówek, gdy u ytkownik przemieszcza kursor ponad łączem. Pozostaje dla nas tajemnicą powód, dla którego w interfejsie *[RGTNKPM.KUVGPGT nie zdefiniowano osobnych metod w celu obsługi różnych rodzajów zdarzeń. Metoda IGV74. klasy *[RGTNKPM'XGPV zwraca adres URL dla hiperłącza. Poni ej przykład kodu obiektu nasłuchującego hiperłącza, który umo liwia przeglądanie stron ładowanych przez u ytkownika przy u yciu hiperłącza. GFKVQT2CPGCFF*[RGTNKPM.KUVGPGT PGY *[RGTNKPM.KUVGPGT ] RWDNKE XQKF J[RGTNKPM7RFCVG *[RGTNKPM'XGPV GXGPV ] KH GXGPVIGV'XGPV6[RG  *[RGTNKPM'XGPV'XGPV6[RG#%6+8#6'& ] VT[ ] GFKVQT2CPGUGV2CIG GXGPVIGV74.  _ ECVEJ +1'ZEGRVKQP G ] GFKVQT2CPGUGV6GZV 'ZEGRVKQP G  _ _ _ _  Metoda obsługi zdarzenia pobiera po prostu odpowiedni adres URL i aktualizuje zawartość panelu edytora. Metoda UGV2CIG mo e wyrzucić wyjątek +1'ZEGRVKQP. W takiej sytuacji wyświetlamy w panelu edytora informację o błędzie w postaci zwykłego tekstu. Program, którego tekst źródłowy zawiera listing 6.15, wykorzystuje wszystkie mo liwo- ści klasy ,'FKVQT2CPG, które przydatne są do zbudowania systemu pomocy opartego o pliki w formacie HTML. Implementacja klasy ,'FKVQT2CPG jest bardziej skomplikowana ni w przypadku komponentów drzewa bądź tabeli. Jeśli jednak nie wykorzystujemy tej kla- sy do tworzenia własnego edytora tekstu, to szczegółami tej implementacji nie musimy się interesować. Listing 6.15. EditorPaneTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCKQ
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[ YKGVNCPKG UVTQP *6/. C RQOQEæ RCPGNW GF[VQTC
  • 482 Java 2. Techniki zaawansowane
  •  RWDNKE ENCUU 'FKVQT2CPG6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 'FKVQT2CPG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC RCPGN GF[VQTC RQNG VGMUVQYG K RT[EKUM .QCF WOQ NKYKCLæEG YRTQYCFGPKG CFTGUW 74. K C CFQYCPKG UVTQP[ C VCM G RT[EKUM $CEM WOQ NKYKCLæE[ RQYTÎV FQ RQRTGFPKGL UVTQP[
  •  ENCUU 'FKVQT2CPG(TCOG GZVGPFU ,(TCOG ] RWDNKE 'FKVQT2CPG(TCOG ] UGV6KVNG 'FKVQT2CPG6GUV  UGV5KG 9+&6* *'+)*6  HKPCN 5VCEM WTN5VCEM  PGY 5VCEM  HKPCN ,'FKVQT2CPG GFKVQT2CPG  PGY ,'FKVQT2CPG  HKPCN ,6GZV(KGNF WTN  PGY ,6GZV(KGNF    KPUVCNWLG QDKGMV PCU WEJWLæE[ JKRGT æEC GFKVQT2CPGUGV'FKVCDNG HCNUG  GFKVQT2CPGCFF*[RGTNKPM.KUVGPGT PGY *[RGTNKPM.KUVGPGT ] RWDNKE XQKF J[RGTNKPM7RFCVG *[RGTNKPM'XGPV GXGPV ] KH GXGPVIGV'XGPV6[RG  *[RGTNKPM'XGPV'XGPV6[RG#%6+8#6'& ] VT[ ]  CRCOKúVWLG CFTGU 74. FNC RQVTGD RT[EKUMW $CEM WTN5VCEMRWUJ GXGPVIGV74. VQ5VTKPI   RTGGPVWLG CFTGU 74. Y RQNW VGMUVQY[O WTNUGV6GZV GXGPVIGV74. VQ5VTKPI  GFKVQT2CPGUGV2CIG GXGPVIGV74.  _ ECVEJ +1'ZEGRVKQP G ] GFKVQT2CPGUGV6GZV 'ZEGRVKQP G  _ _ _ _   RQNG Y[DQTW WOQ NKYKCLæEG Y æEGPKG VT[DW GF[ELK HKPCN ,%JGEM$QZ GFKVCDNG  PGY ,%JGEM$QZ  GFKVCDNGCFF#EVKQP.KUVGPGT PGY
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 483 #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] GFKVQT2CPGUGV'FKVCDNG GFKVCDNGKU5GNGEVGF  _ _   VYQT[ QDKGMV PCU WEJWLæE[ RT[EKUMW .QCF #EVKQP.KUVGPGT NKUVGPGT  PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VT[ ]  CRCOKúVWLG CFTGU 74. FNC RQVTGD RT[EKUMW $CEM WTN5VCEMRWUJ WTNIGV6GZV  GFKVQT2CPGUGV2CIG WTNIGV6GZV  _ ECVEJ +1'ZEGRVKQP G ] GFKVQT2CPGUGV6GZV 'ZEGRVKQP G  _ _ _ ,$WVVQP NQCF$WVVQP  PGY ,$WVVQP .QCF  NQCF$WVVQPCFF#EVKQP.KUVGPGT NKUVGPGT  WTNCFF#EVKQP.KUVGPGT NKUVGPGT   VYQT[ QDKGMV PCU WEJWLæE[ RT[EKUMW $CEM ,$WVVQP DCEM$WVVQP  PGY ,$WVVQP $CEM  DCEM$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] KH WTN5VCEMUKG   TGVWTP VT[ ]  RQDKGTC CFTGU 74. WTN5VCEMRQR   RTGGPVWLG CFTGU 74. Y RQNW VGMUVQY[O 5VTKPI WTN5VTKPI  5VTKPI WTN5VCEMRGGM  WTNUGV6GZV WTN5VTKPI  GFKVQT2CPGUGV2CIG WTN5VTKPI  _ ECVEJ +1'ZEGRVKQP G ] GFKVQT2CPGUGV6GZV 'ZEGRVKQP G  _ _ _ 
  • 484 Java 2. Techniki zaawansowane %QPVCKPGT EQPVGPV2CPG  IGV%QPVGPV2CPG  EQPVGPV2CPGCFF PGY ,5ETQNN2CPG GFKVQT2CPG  $QTFGT.C[QWV%'06'4   WOKGUEC YU[UVMKG MQORQPGPV[ PC I ÎYP[O RCPGNW QMPC ,2CPGN RCPGN  PGY ,2CPGN  RCPGNCFF PGY ,.CDGN 74.  RCPGNCFF WTN  RCPGNCFF NQCF$WVVQP  RCPGNCFF DCEM$WVVQP  RCPGNCFF PGY ,.CDGN 'FKVCDNG  RCPGNCFF GFKVCDNG  EQPVGPV2CPGCFF RCPGN $QTFGT.C[QWV5176*  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ LCXCZUYKPI,'FKVQT2CPG n XQKF UGV2CIG 74. WTN ładuje stronę o adresie WTN do panelu edytora. n XQKF CFF*[RGTNKPM.KUVGPGT *[RGTNKPM.KUVGPGT NKUVGPGT instaluje obiekt nasłuchujący panelu edytora. LCXCZUYKPIGXGPV*[RGTNKPM.KUVGPGT n XQKF J[RGTNKPM7RFCVG *[RGTNKPM'XGPV GXGPV wywoływana, gdy hiperłącze zostanie wybrane. LCXCZUYKPI*[RGTNKPM'XGPV n 74. IGV74. zwraca adres URL dla wybranego hiperłącza. Organizatory komponentów Omówienie zaawansowanych mo liwości biblioteki Swing zakończymy przedstawie- niem komponentów, które pomagają programiście w organizacji innych komponentów. Nale ą do nich panele dzielone umo liwiające podział ich obszaru na wiele części, któ- rych rozmiary mo na regulować, panele z zakładkami pozwalające na przeglądanie wielu paneli i panele pulpitu ułątwiające implementację aplikacji posiadających wiele ramek wewnętrznych.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 485 Panele dzielone Panele dzielone umo liwiają podział ich obszaru na dwie części. Linia podziału panelu mo- e być zmieniana. Rysunek 6.40 pokazuje ramkę zawierającą dwa panele dzielone. Panel zewnętrzny podzielony został poziomo, w jego dolnej części umieszczono obszar tekstowy, a w górnej — kolejny panel dzielony. Ten ostatni podzielony został pionowo. W jego lewej części umieszczono listę, a w prawej — etykietę zawierającą obrazek. Rysunek 6.40. Ramka zawierająca dwa zagnieżdżone panele Tworząc panel dzielony, musimy określić sposób jego podziału i dostarczyć komponenty, które umieszczone zostaną w poszczególnych częściach panelu. ,5RNKV2CPG KPPGT2CPG  PGY ,5RNKV2CPG ,5RNKV2CPG*14+<106#.A52.+6 RNCPGV.KUV RNCPGV+OCIG  I to wszystko. Mo emy jeszcze dodać do linii podziału ikony, które umo liwią maksymali- zację obszaru wybranej części panelu. Ikony te widać w górnej części linii podziału na ry- sunku 6.40. W przypadku wyglądu Metal są one reprezentowane za pomocą trójkątów. Wybranie jednego z nich powoduje maksymalizację obszaru części panelu w kierunku wskazywanym przez wierzchołek trójkąta. Dodanie tej właściwości linii podziału mo liwe jest za pomocą poni szej metody. KPPGT2CPGUGV1PG6QWEJ'ZRCPFCDNG VTWG  Inna mo liwość polega na włączeniu odrysowywania zawartości części paneli podczas prze- suwania linii podziału. Jest to przydatne w niektórych sytuacjach, ale zawsze powoduje spo- wolnienie działania linii podziału. Mo liwość tę mo emy włączyć za pomocą wywołania: KPPGT2CPGUGV%QPVKPWQWU.C[QWV VTWG  W naszym przykładowym programie dolna linia podziału posiada domyślne właściwości (brak ciągłego odrysowywania). Jej przeciąganie powoduje jedynie przesuwanie się ciem- nej linii. Dopiero jej docelowe ustawienie powoduje odrysowanie komponentów. Działanie programu z listingu 6.16 jest bardzo proste. Wypełnia on komponent listy na- zwami planet. Wybór jednej z nich sprawia, e w prawej części panelu wyświetlany jest ob- razek planety, a w dolnej — jej opis. Polecamy wypróbowanie i porównanie działania obu linii podziału.
  • 486 Java 2. Techniki zaawansowane Listing 6.16. SplitPaneTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG MQORQPGPVW RCPGNW FKGNQPGIQ
  •  RWDNKE ENCUU 5RNKV2CPG6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 5RNKV2CPG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC FYC RCPGNG FKGNQPG Y[ YKGVNCLæEG QRKU RNCPGV
  •  ENCUU 5RNKV2CPG(TCOG GZVGPFU ,(TCOG ] RWDNKE 5RNKV2CPG(TCOG ] UGV6KVNG 5RNKV2CPG6GUV  UGV5KG 9+&6* *'+)*6   VYQT[ MQORQPGPV[ FNC RTGGPVCELK PCY K QRKUW RNCPGV  QTC KEJ QDTCMÎY HKPCN ,.KUV RNCPGV.KUV  PGY ,.KUV RNCPGVU  HKPCN ,.CDGN RNCPGV+OCIG  PGY ,.CDGN  HKPCN ,6GZV#TGC FGUETKRVKQP  PGY ,6GZV#TGC  RNCPGV.KUVCFF.KUV5GNGEVKQP.KUVGPGT PGY .KUV5GNGEVKQP.KUVGPGT ] RWDNKE XQKF XCNWG%JCPIGF .KUV5GNGEVKQP'XGPV GXGPV ] 2NCPGV XCNWG  2NCPGV RNCPGV.KUVIGV5GNGEVGF8CNWG   CMVWCNKWLG QDTCGM K QRKU RNCPGV+OCIGUGV+EQP XCNWGIGV+OCIG  FGUETKRVKQPUGV6GZV XCNWGIGV&GUETKRVKQP  _ _   VYQT[ RCPGNG FKGNQPG ,5RNKV2CPG KPPGT2CPG  PGY ,5RNKV2CPG ,5RNKV2CPG*14+<106#.A52.+6 RNCPGV.KUV RNCPGV+OCIG 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 487 KPPGT2CPGUGV%QPVKPWQWU.C[QWV VTWG  KPPGT2CPGUGV1PG6QWEJ'ZRCPFCDNG VTWG  ,5RNKV2CPG QWVGT2CPG  PGY ,5RNKV2CPG ,5RNKV2CPG8'46+%#.A52.+6 KPPGT2CPG FGUETKRVKQP  IGV%QPVGPV2CPG CFF QWVGT2CPG $QTFGT.C[QWV%'06'4  _ RTKXCVG 2NCPGV=? RNCPGVU  ] PGY 2NCPGV /GTEWT[     PGY 2NCPGV 8GPWU     PGY 2NCPGV 'CTVJ     PGY 2NCPGV /CTU     PGY 2NCPGV ,WRKVGT     PGY 2NCPGV 5CVWTP     PGY 2NCPGV 7TCPWU     PGY 2NCPGV 0GRVWPG     PGY 2NCPGV 2NWVQ     _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ 
  • -NCUC TGRTGGPVWLæEC RNCPGV[
  •  ENCUU 2NCPGV ] 
  • 6YQT[ QDKGMV TGRTGGPVWLæE[ RNCPGVú "RCTCO P PCYC RNCPGV[ "RCTCO T RTQOKG RNCPGV[ "RCTCO O NKEDC MUKú [EÎY
  •  RWDNKE 2NCPGV 5VTKPI P FQWDNG T KPV O ] PCOG  P TCFKWU  T OQQPU  O KOCIG  PGY +OCIG+EQP PCOG IKH  _ RWDNKE 5VTKPI VQ5VTKPI ] TGVWTP PCOG _ 
  • 2QDKGTC QRKU RNCPGV[ "TGVWTP QRKU
  •  RWDNKE 5VTKPI IGV&GUETKRVKQP ] TGVWTP 4CFKWU TCFKWU >P/QQPU OQQPU >P  _ 
  • 488 Java 2. Techniki zaawansowane 2QDKGTC QDTCGM RNCPGV[ "TGVWTP QDTCGM
  •  RWDNKE +OCIG+EQP IGV+OCIG ] TGVWTP KOCIG _ RTKXCVG 5VTKPI PCOG RTKXCVG FQWDNG TCFKWU RTKXCVG KPV OQQPU RTKXCVG +OCIG+EQP KOCIG _ LCXCZUYKPI,5RNKV2CPG n ,5RNKV2CPG n ,5RNKV2CPG KPV FKTGEVKQP n ,5RNKV2CPG KPV FKTGEVKQP DQQNGCP EQPVKPWQWU.C[QWV n ,5RNKV2CPG KPV FKTGEVKQP %QORQPGPV HKTUV %QORQPGPV UGEQPF n ,5RNKV2CPG KPV FKTGEVKQP DQQNGCP EQPVKPWQWU.C[QWV %QORQPGPV HKTUV %QORQPGPV UGEQPF Tworzą nowy panel dzielony. Parametry: FKTGEVKQP jedna z wartości ,5RNKV2CPG*14+<106#.A52.+6 lub ,5RNKV2CPG8'46+%#.A52.+6, EQPVKPWQWU.C[QWV wartość VTWG, jeśli komponenty mają być odrysowywane podczas przesuwania linii podziału, HKTUV, UGEQPF komponenty, które mają być umieszczone w częściach panelu. n DQQNGCP KU1PG6QWEJ'ZRCPFCDNG n XQKF UGV1PG6QWEJ'ZRCPFCDNG DQQNGCP D Umo liwiają sprawdzenie oraz włączenie właściwości linii podziału polegającej na mo liwości maksymalizacji części panelu. n DQQNGCP KU%QPVKPWQWU.C[QWV n XQKF UGV%QPVKPWQWU.C[QWV DQQNGCP D Umo liwiają sprawdzenie oraz włączenie właściwości linii podziału polegającej na odrysowywaniu zawartości komponentów panelu podczas przesuwania linii podziału. n XQKF UGV.GHV%QORQPGPV %QORQPGPV E n XQKF UGV6QR%QORQPGPV %QORQPGPV E Obie metody dają ten sam efekt — umieszczają komponent E w pierwszej części panelu.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 489 n XQKF UGV4KIJV%QORQPGPV %QORQPGPV E n XQKF UGV$QVVQO%QORQPGPV %QORQPGPV E Obie metody dają ten sam efekt — umieszczają komponent E w drugiej części panelu. Panele z zakładkami Panele z zakładkami umo liwiają uporządkowanie zawartości zło onych okien dialogo- wych. Pozwalają tak e na przeglądanie zestawu dokumentów lub obrazów (patrz rysunek 6.41). Takie będzie te ich zastosowanie w naszym przykładowym programie. Rysunek 6.41. Panel z zakładkami Tworząc panel z zakładkami, konstruujemy najpierw obiekt klasy ,6CDDGF2CPG, a następnie dodajemy do niego zakładki. ,6CDDGF2CPG VCDDGF2CPG  PGY ,6CDDGF2CPG  VCDDGF2CPGCFF6CD VKVNG KEQP EQORQPGPV  Ostatni parametr metody CFF jest komponentem, który umieszczony zostanie na zakładce. Jeśli chcemy, by zakładka zawierała wiele komponentów, to najpierw musimy umieścić je w kontenerze, na przykład klasy ,2CPGN. Ikona zakładki jest opcjonalna. Istnieje wersja metody CFF, która nie wymaga tego parametru: VCDDGF2CPGCFF6CD VKVNG EQORQPGPV  Nową zakładkę mo emy tak e umieścić między ju istniejącymi, korzystając z metody KP UGTV6CD: VCDDGF2CPGKPUGTV6CD VKVNG KEQP EQORQPGPV KPFGZ  Natomiast poni sze wywołanie spowoduje usunięcie zakładki: VCDDGF2CPGTGOQXG6CD#V KPFGZ  Umieszczenie w panelu nowej zakładki nie powoduje, e staje się ona automatycznie wi- doczna. W tym celu musimy wybrać ją za pomocą metody UGV5GNGEVGF+PFGZ. Poni sze wywołanie pokazuje, w jaki sposób spowodować wyświetlenie dodanej właśnie zakładki: VCDDGF2CPG UGV5GNGEVGF+PFGZ VCDDGF2CPGIGV6CD%QWPV   
  • 490 Java 2. Techniki zaawansowane Jeśli panel zawiera większą liczbę zakładek, to mogą one zajmować zbyt du o miejsca. Dlatego te w SDK 1.4 wprowadzono mo liwość przewijania pojedynczego wiersza zakła- dek (patrz rysunek 6.42). Rysunek 6.42. Panel z przewijaniem zakładek Mo emy wybrać uło enie wszystkich zakładek w kilku wierszach bądź przewijanie ich w jednym wierszu, wywołując odpowiednio: VCDDGF2CPGUGV6CD.C[QWV2QNKE[ ,6CDDGF2CPG94#2A6#$A.#;176  lub VCDDGF2CPGUGV6CD.C[QWV2QNKE[ ,6CDDGF2CPG5%41..A6#$A.#;176  Program przykładowy pokazuje zastosowanie pewnej techniki przydatnej w przypadku pa- neli z zakładkami. Polega ona na umieszczeniu komponentu na zakładce, dopiero w mo- mencie gdy ma zostać ona pokazana. W naszym programie oznacza to, e obrazek planety zostanie umieszczony na zakładce dopiero po jej wybraniu. Aby uzyskać powiadomienie o wyborze zakładki, musimy zainstalować obiekt nasłuchujący %JCPIG.KUVGPGT. Zwróćmy uwagę, e obiekt ten instalujemy dla panelu, a nie dla jednego z jego komponentów. VCDDGF2CPGCFF%JCPIG.KUVGPGT NKUVGPGT  Gdy u ytkownik wybierze zakładkę, to wywołana zostanie metoda UVCVG%JCPIGF obiektu nasłuchującego. Korzystając z metody IGV5GNGEVGF+PFGZ, mo emy dowiedzieć się, która zakładka została wybrana: RWDNKE XQKF UVCVG%JCPIGF %JCPIG'XGPV GXGPV ] KPV P  VCDDGF2CPGIGV5GNGEVGF+PFGZ     _ W programie z listingu 6.17 wszystkie komponenty zakładek mają na początku wartość PWNN. Kiedy zakładka jest wybierana, to sprawdzamy, czy jej komponent nadal jest warto- ścią PWNN. Jeśli tak, to ładujemy obrazek. (Dzieje się to, zanim wybrana zakładka zostanie pokazana i wobec tego u ytkownik nie zobaczy pustej zakładki). Zmieniamy tak e ikonę zakładki z ółtej na czerwoną, aby zaznaczyć, które zakładki były ju przeglądane.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 491 Listing 6.17. TabbedPaneTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ CUVQUQYCPKG RCPGNW CM CFMCOK
  •  RWDNKE ENCUU 6CDDGF2CPG6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY 6CDDGF2CPG(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC CYKGTCLæEC RCPGN CM CFMCOK QTC RT[EKUMK WOQ NKYKCLæEG RTG æECPKG URQUQDW RTGGPVCELK CM CFGM
  •  ENCUU 6CDDGF2CPG(TCOG GZVGPFU ,(TCOG ] RWDNKE 6CDDGF2CPG(TCOG ] UGV6KVNG 6CDDGF2CPG6GUV  UGV5KG 9+&6* *'+)*6  HKPCN ,6CDDGF2CPG VCDDGF2CPG  PGY ,6CDDGF2CPG   C CFQYCPKG MQORQPGPVÎY CM CFGM QFM CFCO[  FQ OQOGPVW KEJ RKGTYUGL RTGGPVCELK +OCIG+EQP KEQP  PGY +OCIG+EQP [GNNQYDCNNIKH  VCDDGF2CPGCFF6CD /GTEWT[  KEQP PWNN  VCDDGF2CPGCFF6CD 8GPWU  KEQP PWNN  VCDDGF2CPGCFF6CD 'CTVJ  KEQP PWNN  VCDDGF2CPGCFF6CD /CTU  KEQP PWNN  VCDDGF2CPGCFF6CD ,WRKVGT  KEQP PWNN  VCDDGF2CPGCFF6CD 5CVWTP  KEQP PWNN  VCDDGF2CPGCFF6CD 7TCPWU  KEQP PWNN  VCDDGF2CPGCFF6CD 0GRVWPG  KEQP PWNN  VCDDGF2CPGCFF6CD 2NWVQ  KEQP PWNN  IGV%QPVGPV2CPG CFF VCDDGF2CPG %GPVGT  VCDDGF2CPGCFF%JCPIG.KUVGPGT PGY %JCPIG.KUVGPGT ] RWDNKE XQKF UVCVG%JCPIGF %JCPIG'XGPV GXGPV ]
  • 492 Java 2. Techniki zaawansowane  URTCYFC E[ PC CM CFEG WOKGUEQP[ LGUV LW MQORQPGPV KH VCDDGF2CPGIGV5GNGEVGF%QORQPGPV  PWNN ]  CFWLG QDTCGM KPV P  VCDDGF2CPGIGV5GNGEVGF+PFGZ  5VTKPI VKVNG  VCDDGF2CPGIGV6KVNG#V P  +OCIG+EQP RNCPGV+EQP  PGY +OCIG+EQP VKVNG IKH  VCDDGF2CPGUGV%QORQPGPV#V P PGY ,.CDGN RNCPGV+EQP   CPCEC G CM CFMC D[ C LW RTGINæFCPC VCDDGF2CPGUGV+EQP#V P PGY +OCIG+EQP TGFDCNNIKH  _ _ _  ,2CPGN DWVVQP2CPGN  PGY ,2CPGN  $WVVQP)TQWR DWVVQP)TQWR  PGY $WVVQP)TQWR  ,4CFKQ$WVVQP YTCR$WVVQP  PGY ,4CFKQ$WVVQP 9TCR VCDU  YTCR$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VCDDGF2CPGUGV6CD.C[QWV2QNKE[ ,6CDDGF2CPG94#2A6#$A.#;176  _ _  DWVVQP2CPGNCFF YTCR$WVVQP  DWVVQP)TQWRCFF YTCR$WVVQP  YTCR$WVVQPUGV5GNGEVGF VTWG  ,4CFKQ$WVVQP UETQNN$WVVQP  PGY ,4CFKQ$WVVQP 5ETQNN VCDU  UETQNN$WVVQPCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VCDDGF2CPGUGV6CD.C[QWV2QNKE[ ,6CDDGF2CPG5%41..A6#$A.#;176  _ _  DWVVQP2CPGNCFF UETQNN$WVVQP  DWVVQP)TQWRCFF UETQNN$WVVQP  IGV%QPVGPV2CPG CFF DWVVQP2CPGN $QTFGT.C[QWV5176*  _ RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 493 LCXCZUYKPI,6CDDGF2CPG n ,6CDDGF2CPG n ,6CDDGF2CPG KPV RNCEGOGPV Tworzą panel z zakładkami. Parametry: RNCEGOGPV jedna z wartości 5YKPI%QPUVCPVU612, 5YKPI%QPUVCPVU.'(6, 5YKPI%QPUVCPVU4+)*6 lub 5YKPI%QPUVCPVU$1661/. n XQKF CFF6CD 5VTKPI VKVNG %QORQPGPV EQORQPGPV n XQKF CFF6CD 5VTKPI VKVNG +EQP KEQP %QORQPGPV E n XQKF CFF6CD 5VTKPI VKVNG +EQP KEQP %QORQPGPV E 5VTKPI VQQN6KR Dodają zakładkę do panelu. n XQKF KPUGTV6CD 5VTKPI VKVNG +EQP KEQP %QORQPGPV E 5VTKPI VQQN6KR KPV KPFGZ umieszcza nową zakładkę na pozycji o podanym indeksie. n XQKF TGOQXG6CD#V KPV KPFGZ usuwa zakładkę o podanym indeksie. n XQKF UGV5GNGEVGF+PFGZ KPV KPFGZ wybiera zakładkę o podanym indeksie. n KPV IGV5GNGEVGF+PFGZ zwraca indeks wybranej zakładki. n %QORQPGPV IGV5GNGEVGF%QORQPGPV zwraca komponent wybranej zakładki. n 5VTKPI IGV6KVNG#V KPV KPFGZ n XQKF UGV6KVNG#V KPV KPFGZ 5VTKPI VKVNG n +EQP IGV+EQP#V KPV KPFGZ n XQKF UGV+EQP#V KPV KPFGZ +EQP KEQP n %QORQPGPV IGV%QORQPGPV#V KPV KPFGZ n XQKF UGV%QORQPGPV#V KPV KPFGZ %QORQPGPV E Pobierają lub ustawiają tytuł, ikonę lub komponent zakładki o danym indeksie. n KPV KPFGZ1H6CD +EQP KEQP n KPV KPFGZ1H6CD 5VTKPI VKVNG n KPV KPFGZ1H6CD %QORQPGPV E Zwracają indeks zakładki o danym tytule, ikonie bądź komponencie. n KPV IGV6CD%QWPV zwraca liczbę zakładek panelu. n XQKF UGV6CD.C[QWV2QNKE[ KPV RQNKE[ ustala sposób prezentacji zakładek — w wielu wierszach lub jednym przewijanym. Parametry: RQNKE[ jedna z wartości ,6CDDGF2CPG94#2A6#$A.#;176 lub ,6CDDGF2CPG5%41..A6#$A.#;176. n XQKF CFF%JCPIG.KUVGPGT %JCPIG.KUVGPGT NKUVGPGT instaluje obiekt nasłuchujący powiadamiany w momencie wybrania przez u ytkownika zakładki.
  • 494 Java 2. Techniki zaawansowane Panele pulpitu i ramki wewnętrzne Aplikacje często prezentują informacje, korzystając z wielu okien umieszczonych we wspól- nej ramce. Zwinięcie takiej ramki do ikony równoznaczne jest z ukryciem zawartości wszyst- kich jej okien. W środowisku Windows ten sposób działania interfejsu u ytkownika nazwany został MDI (Multiple Document Interface). Rysunek 6.43 pokazuje typową aplikację korzy- stającą z interfejsu MDI. Rysunek 6.43. Aplikacja korzystająca z MDI Do niedawna był to jeden z popularniejszych sposobów tworzenia interfejsu aplikacji, ale ostatnio wykorzystywany jest rzadziej. Większość przeglądarek internetowych otwiera strony internetowe, u ywając ramek tego samego poziomu co główna ramka programu. (Wyjątkiem jest tutaj przeglądarka Opera pokazana na rysunku 6.43). Który ze sposobów organizacji interfejsu u ytkownika jest lepszy? Oba posiadają zalety i wady. Wykorzystanie MDI pozwala ograniczyć natłok okien otwieranych przez ró ne programy. Natomiast u y- cie wielu okien programu umo liwia posłu enie się przyciskami i kombinacjami klawiszy udostępnianymi przez system okienkowy do przełączania się pomiędzy oknami. W przypadku aplikacji w języku Java, z natury niezale nych od platformy, nie mo emy polegać na usługach systemu okienkowego, a więc zarządzanie własnymi oknami przez samą aplikację ma większy sens. Rysunek 6.44 pokazuje aplikację Java, której okno zawiera trzy wewnętrzne ramki. Dwie z nich posiadają ikony umo liwiające ich maksymalizację bądź zwinięcie do ikony. Trzecia została zwinięta do ikony. W przypadku wyglądu komponentów Metal ramki wewnętrzne posiadają wyró niony ob- szar, który umo liwia ich „uchwycenie” i przesuwanie. Uchwycenie naro nika ramki umo liwia natomiast zmianę jej rozmiarów.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 495 Rysunek 6.44. Aplikacja w języku Java posiadająca trzy wewnętrzne ramki Aby skorzystać z mo liwości zarządzania wewnętrznymi ramkami nale y kolejno wykonać następujące kroki. 1. Tworzymy dla aplikacji zwykłą ramkę klasy ,(TCOG. 2. Umieszczamy w niej panel klasy ,&GUMVQR2CPG. FGUMVQR  PGY ,&GUMVQR2CPG  UGV%QPVGPV2CPG FGUMVQR  3. Tworzymy obiekty klasy ,+PVGTPCN(TCOG reprezentujące wewnętrzne ramki, podając przy tym, czy mają zawierać ikony zmiany rozmiarów i zamknięcia. Zwykle będziemy chcieli, by ramki posiadały wszystkie te ikony. ,+PVGTPCN(TCOG KHTCOG  PGY ,+PVGTPCN(TCOG VKVNG VTWG  OKCPC TQOKCTÎY VTWG  OQ NKYQ è COMPKúEKC VTWG  OCMU[OCNKCELC VTWG   YKPKúEKG FQ KMQP[ 4. Umieszczamy komponenty w ramkach wewnętrznych. KHTCOGIGV%QPVGPV2CPG CFF E  5. Przypisujemy ramkom wewnętrznym ikonę, która pokazywana będzie w lewym górnym rogu ramki. KHTCOGUGV(TCOG+EQP KEQP  W obecnej wersji implementacji wyglądu Metal ikona ramki nie jest wyświetlana, gdy ramka jest zwinięta.
  • 496 Java 2. Techniki zaawansowane 6. Określamy rozmiary wewnętrznych ramek. Podobnie jak w przypadku zwykłych ramek, ich początkowy rozmiar wynosi 0 na 0 pikseli. Poniewa nie chcemy, by ramki wewnętrzne przykrywały się wzajemnie, to powinniśmy wybrać dla nich tak e ró ne pozycje początkowe. Metoda TGUJCRG umo liwia określenie początkowej pozycji i rozmiarów ramki: KHTCOGTGUJCRG PGZV(TCOG: PGZV(TCOG; YKFVJ JGKIJV  7. Podobnie jak w przypadku zwykłych ramek, musimy jeszcze je pokazać. KHTCOGUGV8KUKDNG VTWG  We wczesnych wersjach biblioteki Swing ramki wewnętrzne były pokazywane automa- tycznie i wywołanie metody UGV8KUKDNG nie było konieczne. 8. Dodajemy ramki do panelu ,&GUMVQR2CPG: FGUMVQRCFF KHTCOG  9. Wybieramy jedną z dodanych ramek. W przypadku ramek wewnętrznych tylko wybrana ramka otrzymuje informacje o stanie klawiatury. Wygląd Metal wyró nia wybraną ramkę za pomocą niebieskiego paska tytułu, podczas gdy w pozostałych ramkach ma on kolor szary. Metoda UGV5GNGEVGF(TCOG umo liwia wybranie ramki. Jednak wywołanie tej metody mo e zostać „zawetowane” przez aktualnie wybraną ramkę. Spowoduje to wyrzucenie przez metodę UGV5GNGEVGF(TCOG wyjątku 2TQRGTV[8GVQ'ZEGRVKQP, który musimy obsłu yć. VT[ ] KHTCOGUGV5GNGEVGF VTWG  _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]  RTÎDC Y[DQTW QUVC C CYGVQYCPC _ 10. Umieszczamy kolejną ramkę poni ej, tak by nie zasłaniała istniejącej ramki. Właściwą odległością będzie zwykle wysokość paska tytułowego ramki, którą mo emy uzyskać w poni szy sposób: KPV HTCOG&KUVCPEG  KHTCOGIGV*GKIJV KHTCOGIGV%QPVGPV2CPG IGV*GKIJV  11. Wykorzystujemy wyliczoną odległość w celu ustalenia pozycji kolejnej ramki. PGZV(TCOG:  HTCOG&KUVCPEG PGZV(TCOG;  HTCOG&KUVCPEG KH PGZV(TCOG: YKFVJ FGUMVQRIGV9KFVJ PGZV(TCOG:   KH PGZV(TCOG; JGKIJV FGUMVQRIGV*GKIJV PGZV(TCOG;  
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 497 Rozmieszczenie kaskadowe i sąsiadujące W systemie Windows istnieją standardowe komendy umo liwiające uzyskanie rozmiesz- czenia kaskadowego lub sąsiadującego okien (patrz rysunki 6.45 i 6.46). Klasy ,&GUMVQR 2CPG i ,+PVGTPCN(TCOG biblioteki Swing nie udostępniają niestety odpowiednich metod. Program, którego tekst źródłowy umieściliśmy w listingu 6.18, pokazuje sposób samodzielnej implementacji takich metod. Rysunek 6.45. Rozmieszczenie kaskadowe ramek wewnętrznych Rysunek 6.46. Rozmieszczenie sąsiadujące ramek wewnętrznych Rozmieszczenie kaskadowe charakteryzuje się jednakowym rozmiarem okien i przesunię- ciem ich pozycji. Metoda IGV#NN(TCOGU klasy ,&GUMVQR2CPG zwraca tablicę wszystkich we- wnętrznych ramek. ,+PVGTPCN(TCOG=? HTCOGU  FGUMVQRIGV#NN(TCOGU 
  • 498 Java 2. Techniki zaawansowane Musimy jednak zwrócić uwagę na stan, w jakim one się znajdują. Ramka wewnętrzna mo e znajdować się w jednym z trzech stanów. Oto one: n ikona, n pośredni, umo liwiający zmianę rozmiarów ramki, n w pełni rozwinięty. Korzystając z metody KU+EQP, mo emy dowiedzieć się, które ramki zwinięte są do ikony i pominąć je podczas rozmieszczania. Jeśli ramka znajduje się w stanie w pełni rozwinię- tym, to musimy najpierw sprowadzić ją do stanu pośredniego, wywołując UGV/CZKOWO HCNUG . Jest to kolejna metoda, której wywołanie mo e zostać zawetowane. Trzeba więc obsłu yć wyjątek 2TQRGTV[8GVQ'ZEGRVKQP. Poni sza pętla rozmieszcza kaskadowo wszystkie wewnętrzne ramki panelu pulpitu: HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU+EQP ] VT[ ]  RTÎDWLG RTGRTQYCFKè TCOMK FQ UVCPW RQ TGFPKGIQ  EQ OQ G QUVCè CYGVQYCPG HTCOGU=K?UGV/CZKOWO HCNUG  HTCOGU=K?TGUJCRG Z [ YKFVJ JGKIJV  Z  HTCOG&KUVCPEG [  HTCOG&KUVCPEG  CYKLC FQQMQ C DTGIW RWNRKVW KH Z YKFVJ FGUMVQRIGV9KFVJ Z   KH [ JGKIJV FGUMVQRIGV*GKIJV [   _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ Uzyskanie rozmieszczenia sąsiadującego okazuje się nieco bardziej skomplikowane, szcze- gólnie jeśli liczba ramek nie jest kwadratem innej liczby. Najpierw musimy uzyskać liczbę ramek, które nie są zwinięte do ikony. Następnie obliczyć liczbę kolumn jako KPV EQNU  KPV /CVJUSTV HTCOG%QWPV  oraz liczbę wierszy jako KPV TQYU  HTCOG%QWPV  EQNU z tym wyjątkiem, e ostatnia kolumna GZVTC  HTCOG%QWPV EQNU posiadać będzie TQYU  wierszy. Poni sza pętla rozmieszcza sąsiadująco wszystkie wewnętrzne ramki panelu pulpitu: KPV YKFVJ  FGUMVQRIGV9KFVJ  EQNU KPV JGKIJV  FGUMVQRIGV*GKIJV  TQYU KPV T  
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 499 KPV E   HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU+EQP ] VT[ ] HTCOGU=K?UGV/CZKOWO HCNUG  HTCOGU=K?TGUJCRG E
  • YKFVJ T
  • JGKIJV YKFVJ JGKIJV  T  KH T  TQYU ] T   E  KH E  EQNU  GZVTC ]  TQRQE[PC FQFCVMQY[ YKGTU TQYU  JGKIJV  FGUMVQRIGV*GKIJV  TQYU _ _ _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ Przykładowy program prezentuje tak e inną typową operację związana z ramkami: wybór kolejnych ramek, które nie są zwinięte do ikony. Klasa ,&GUMVQR2CPG nie udostępnia meto- dy zwracającej wybraną ramkę. Musimy więc sami wywołać metodę KU5GNGEVGF dla wszyst- kich ramek tak długo, a znajdziemy tę wybraną. Następnie wyszukujemy kolejną ramkę, która nie jest zwinięta do ikony i próbujemy ją wybrać. HTCOGU=PGZV?UGV5GNGEVGF VTWG  Tak e i to wywołanie mo e wyrzucić wyjątek 2TQRGTV[8GVQ'ZEGRVKQP. W takim przypadku musimy kontynuować poszukiwanie kolejnej ramki. Jeśli wrócimy w ten sposób do ramki wyjściowej, oznacza to, e adna inna ramka nie mogła być wybrana. Poni ej kompletna pętla realizująca opisane działanie: HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU5GNGEVGF ]  PCLFWLG TCOMú MVÎTC PKG LGUV YKPKúVC FQ KMQP[  K OQ G QUVCè Y[DTCPC VT[ ] KPV PGZV  K  HTCOGUNGPIVJ YJKNG PGZV  K HTCOGU=PGZV?KU+EQP PGZV  PGZV  HTCOGUNGPIVJ KH PGZV  K TGVWTP  RQQUVC G TCOMK Uæ YKPKúVG FQ KMQP NWD I QUK [ YGVQ FQ Y[DQTW HTCOGU=PGZV?UGV5GNGEVGF VTWG  HTCOGU=PGZV?VQ(TQPV  TGVWTP
  • 500 Java 2. Techniki zaawansowane _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ Zgłaszanie weta do zmiany właściwości Po lekturze poprzednich przykładów mo emy zastanawiać się, w jaki sposób ramka zgłasza weto. Klasa ,+PVGTPCN(TCOG wykorzystuje ogólny mechanizm JavaBeans w celu monitorowania zmian właściwości. Mechanizm ten omawiamy szczegółowo w rozdziale 8. Teraz będziemy chcieli jedynie pokazać, w jaki sposób ramki mogą zgłaszać weto do zmian ich właściwości. Zwykle ramki nie zgłaszają weta, aby oprotestować zwinięcie ich do ikony bądź utratę wybo- ru. Typową sytuacją dla takiego zachowania będzie natomiast zamknięcie ramki. Ramkę za- mykamy, korzystając z metody UGV%NQUGF klasy ,+PVGTPCN(TCOG. Poniewa mo e ona zostać zawetowana, to wywołuje najpierw wszystkie obiekty nasłuchujące weta zmiany. Umo liwia to tym obiektom wyrzucenie wyjątku 2TQRGTV[8GVQ'ZEGRVKQP i tym samym zakończenie wy- konywania metody, zanim podejmie ona działania zmierzające do zamknięcia ramki. W przykładowym programie próba zamknięcia ramki powoduje pojawienie się okna dialo- gowego w celu potwierdzenia zamknięcia ramki przez u ytkownika (patrz rysunek 6.47). Jeśli u ytkownik nie zgodzi się, to ramka pozostanie otwarta. Rysunek 6.47. Użytkownik może zawetować zamknięcie ramki A oto sposób uzyskania takiego powiadomienia. 1. Do ka dej ramki dodajemy obiekt nasłuchujący. Obiekt ten musi nale eć do klasy implementującej interfejs 8GVQCDNG%JCPIG.KUVGPGT. Najlepiej dodać go zaraz po utworzeniu ramki. W przykładowym programie tworzymy go i dodajemy w klasie ramki. Inną mo liwością jest wykorzystanie anonimowej klasy wewnętrznej. KHTCOGCFF8GVQCDNG%JCPIG.KUVGPGT NKUVGPGT 
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 501 2. Implementujemy metodę XGVQCDNG%JCPIG, która jest jedyną metodą definiowaną przez interfejs 8GVQCDNG%JCPIG.KUVGPGT. Jej parametrem jest obiekt klasy 2TQRGTV[%JCPIG'XGPV. Korzystając z jego metody IGV2TQRGTV[0COG, uzyskujemy nazwę właściwości, która ma zostać zmieniona — na przykład ENQUGF , jeśli wetowane jest wywołanie metody UGV%NQUGF VTWG . Jak poka emy w rozdziale 8., nazwa właściwości uzyskiwana jest przez usunięcie prefiksu UGV z nazwy metody i zmianę wielkości następnej litery nazwy. Metodę IGV0GY8CNWG wykorzystujemy w celu uzyskania proponowanej wartości właściwości. 5VTKPI PCOG  GXGPVIGV2TQRGTV[0COG  1DLGEV XCNWG  GXGPVIGV0GY8CNWG  KH PCOGGSWCNU ENQUGF XCNWGGSWCNU $QQNGCP647' ] RTQUK W [VMQYPKMC Q RQVYKGTFGPKG COMPKúEKC TCOMK _ 3. Wyrzucamy wyjątek 2TQRGTV[8GVQ'ZEGRVKQP, aby uniemo liwić zmianę właściwości lub w przeciwnym razie oddajemy sterowanie. ENCUU &GUMVQR(TCOG GZVGPFU ,(TCOG KORNGOGPVU 8GVQCDNG%JCPIG.KUVGPGT ]    RWDNKE XQKF XGVQCDNG%JCPIG 2TQRGTV[%JCPIG'XGPV GXGPV VJTQYU 2TQRGTV[8GVQ'ZEGRVKQP ]    KH PQV QM VJTQY PGY 2TQRGTV[8GVQ'ZEGRVKQP TGCUQP  GXGPV   QFFCLG UVGTQYCPKG LG NK QM _ _ Okna dialogowe ramek wewnętrznych W przypadku ramek wewnętrznych nie powinniśmy korzystać z klasy ,&KCNQI w celu two- rzenia okien dialogowych, poniewa : n ich otwarcie wią e się ze znacznym nakładem i utworzeniem nowej ramki systemu okienkowego, n system okienkowy nie potrafi określić właściwej pozycji okna dialogowego w stosunku do ramki, która je otworzyła. Dlatego te dla prostych okien dialogowych wykorzystywać będziemy metodę UJQY+PVGT PCN:ZZ&KCNQI klasy ,1RVKQP2CPG. Działa ona dokładnie tak jak metoda UJQY:ZZ&KCNQI, ale tworzy proste okno dialogowe nad właściwą ramką wewnętrzną. W przypadku bardziej zło onych okien dialogowych mo emy skorzystać z klasy ,+PVGT PCN(TCOG, która nie umo liwia jednak tworzenia okien modalnych.
  • 502 Java 2. Techniki zaawansowane W naszym programie korzystamy z okna dialogowego w celu potwierdzenia przez u yt- kownika zamknięcia ramki. KPV TGUWNV  ,1RVKQP2CPGUJQY+PVGTPCN%QPHKTO&KCNQI KHTCOG 1- VQ ENQUG!  Jeśli chcemy zostać po prostu powiadomieni o zamknięciu okna, to nie musimy korzy- stać z mechanizmu zgłaszania weta. Wystarczy jedynie zainstalować obiekt nasłuchujący klasy +PVGTPCN(TCOG.KUVGPGT. Zachowuje się on podobnie do obiektu nasłuchującego klasy 9KPFQY.KUVGPGT. Gdy zamykana jest wewnętrzna ramka, to wywoływana jest jego metoda KPVGTPCN(TCOG%NQUKPI będąca odpowiednikiem metody YKPFQY%NQUKPI. Pozo- stałe sześć powiadomień o zmianach ramki wewnętrznej (otwarcie (zamknięcie), zwinię- cie do ikony (rozwinięcie), aktywacja (deaktywacja)) również odpowiada znanym metodom obiektów nasłuchujących zwykłych okien. Przeciąganie zarysu ramki Często krytykowaną cechą wewnętrznych ramek jest niska efektywność odrysowywania ich zawartości. Ujawnia się ona zwłaszcza podczas przeciągania ramek o zło onej zawartości. Podobny efekt uzyskamy tak e dla zwykłych okien w przypadku kiepsko zaimplemento- wanego sterownika ekranu. Z reguły jednak przeciąganie zwykłych okien nawet z bardzo skomplikowaną zawartością jest efektywne, poniewa obsługiwane jest sprzętowo. Aby poprawić działanie przeciągania ramek wewnętrznych, mo emy skorzystać z ich wła- ściwości umo liwiającej przeciąganie jedynie zarysu ramki. Zawartość ramki jest w takim przypadku odrysowywana dopiero po jej umieszczeniu na pulpicie. Podczas przeciągania odrysowywany jest jedynie zarys ramki. Aby włączyć mo liwość przeciągania zarysu, wywołujemy poni szą metodę. FGUMVQRUGV&TCI/QFG ,&GUMVQR2CPG176.+0'A&4#)A/1&'  Mo liwość ta stanowi odpowiednik odrysowywania linii podziału komponentów klasy ,5RNKV 2CPG. We wczesnych wersjach biblioteki Swing odrysowywanie zawartości ramek podczas przeciągania należało wyłączyć za pomocą poniższego wywołania. FGUMVQRRWV%NKGPV2TQRGTV[ ,&GUMVQR2CPGFTCI/QFG  QWVNKPG  Nasz przykładowy program umo liwia zarządzanie odrysowywaniem zawartości ramek za pomocą pozycji menu Window/Drag Outline. Ramki wewnętrzne pulpitu zarządzane są przez klasę &GUMVQR/CPCIGT. Instalując inne- go menedżera pulpitu, możemy zaimplementować odmienne zachowanie pulpitu. Moż- liwości tej nie będziemy jednak omawiać w naszej książce.
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 503 Program z listingu 6.18 otwiera na pulpicie ramki zawierające strony HTML. Wybranie z menu opcji File/Open umo liwia umieszczenie zawartości wybranego pliku HTML w nowej ramce. Wybranie hiperłącza na stronie w ramce powoduje otwarcie nowej strony w osobnej ramce. Po- zycje menu Window/Cascade i Window/Tile umo liwiają uzyskanie ró nych rozmieszczeń ra- mek na pulpicie. Listing 6.18 kończy omówienie zaawansowanych mo liwości pakietu Swing. Listing 6.18. InternalFrameTest.java KORQTV LCXCCYV
  •  KORQTV LCXCCYVGXGPV
  •  KORQTV LCXCDGCPU
  •  KORQTV LCXCKQ
  •  KORQTV LCXCPGV
  •  KORQTV LCXCWVKN
  •  KORQTV LCXCZUYKPI
  •  KORQTV LCXCZUYKPIGXGPV
  •  
  • 2TQITCO FGOQPUVTWLæE[ Y[MQT[UVCPKG TCOGM YGYPúVTP[EJ
  •  RWDNKE ENCUU +PVGTPCN(TCOG6GUV ] RWDNKE UVCVKE XQKF OCKP 5VTKPI=? CTIU ] ,(TCOG HTCOG  PGY &GUMVQR(TCOG  HTCOGUGV&GHCWNV%NQUG1RGTCVKQP ,(TCOG':+6A10A%.15'  HTCOGUJQY  _ _ 
  • 4COMC RWNRKVW CYKGTCLæEC RCPGNG Y[ YKGVNCLæEG CYCTVQ è RNKMÎY *6/.
  •  ENCUU &GUMVQR(TCOG GZVGPFU ,(TCOG ] RWDNKE &GUMVQR(TCOG ] UGV6KVNG +PVGTPCN(TCOG6GUV  UGV5KG 9+&6* *'+)*6  FGUMVQR  PGY ,&GUMVQR2CPG  UGV%QPVGPV2CPG FGUMVQR   VYQT[ OGPW ,/GPW$CT OGPW$CT  PGY ,/GPW$CT  UGV,/GPW$CT OGPW$CT  ,/GPW HKNG/GPW  PGY ,/GPW (KNG  OGPW$CTCFF HKNG/GPW  ,/GPW+VGO QRGP+VGO  PGY ,/GPW+VGO 1RGP  QRGP+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] QRGP(KNG 
  • 504 Java 2. Techniki zaawansowane _ _  HKNG/GPWCFF QRGP+VGO  ,/GPW+VGO GZKV+VGO  PGY ,/GPW+VGO 'ZKV  GZKV+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] 5[UVGOGZKV   _ _  HKNG/GPWCFF GZKV+VGO  ,/GPW YKPFQY/GPW  PGY ,/GPW 9KPFQY  OGPW$CTCFF YKPFQY/GPW  ,/GPW+VGO PGZV+VGO  PGY ,/GPW+VGO 0GZV  PGZV+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] UGNGEV0GZV9KPFQY  _ _  YKPFQY/GPWCFF PGZV+VGO  ,/GPW+VGO ECUECFG+VGO  PGY ,/GPW+VGO %CUECFG  ECUECFG+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] ECUECFG9KPFQYU  _ _  YKPFQY/GPWCFF ECUECFG+VGO  ,/GPW+VGO VKNG+VGO  PGY ,/GPW+VGO 6KNG  VKNG+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] VKNG9KPFQYU  _ _  YKPFQY/GPWCFF VKNG+VGO  HKPCN ,%JGEM$QZ/GPW+VGO FTCI1WVNKPG+VGO  PGY ,%JGEM$QZ/GPW+VGO &TCI 1WVNKPG  FTCI1WVNKPG+VGOCFF#EVKQP.KUVGPGT PGY #EVKQP.KUVGPGT ] RWDNKE XQKF CEVKQP2GTHQTOGF #EVKQP'XGPV GXGPV ] FGUMVQRUGV&TCI/QFG FTCI1WVNKPG+VGOKU5GNGEVGF ! ,&GUMVQR2CPG176.+0'A&4#)A/1&'  ,&GUMVQR2CPG.+8'A&4#)A/1&'  _ _  YKPFQY/GPWCFF FTCI1WVNKPG+VGO  _
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 505 
  • 6YQT[ YGYPúVTPæ TCOMú RWNRKVW "RCTCO E MQORQPGPV YGYPæVT TCOMK YGYPúVTPGL "RCTCO V V[VW TCOMK YGYPúVTPGL
  •  RWDNKE XQKF ETGCVG+PVGTPCN(TCOG %QORQPGPV E 5VTKPI V ] HKPCN ,+PVGTPCN(TCOG KHTCOG  PGY ,+PVGTPCN(TCOG V VTWG  OKCPC TQOKCTÎY VTWG  OQ NKYQ è COMPKúEKC VTWG  OCMU[OCNKCELC VTWG   YKPKúEKG FQ KMQP[ KHTCOGIGV%QPVGPV2CPG CFF E  FGUMVQRCFF KHTCOG  KHTCOGUGV(TCOG+EQP PGY +OCIG+EQP FQEWOGPVIKH   FQFCLG QDKGMV PCU WEJWLæE[ CD[ RQVYKGTFKè COMPKúEKG TCOMK KHTCOGCFF8GVQCDNG%JCPIG.KUVGPGT PGY 8GVQCDNG%JCPIG.KUVGPGT ] RWDNKE XQKF XGVQCDNG%JCPIG 2TQRGTV[%JCPIG'XGPV GXGPV VJTQYU 2TQRGTV[8GVQ'ZEGRVKQP ] 5VTKPI PCOG  GXGPVIGV2TQRGTV[0COG  1DLGEV XCNWG  GXGPVIGV0GY8CNWG   URTCYFC V[NMQ RTÎD[ COMPKúEKC TCOMK KH PCOGGSWCNU ENQUGF XCNWGGSWCNU $QQNGCP647' ]  RTQUK W [VMQYPKMC Q RQVYKGTFGPKG COMPKúEKC TCOMK KPV TGUWNV  ,1RVKQP2CPGUJQY+PVGTPCN%QPHKTO&KCNQI KHTCOG 1- VQ ENQUG!   LG NK W [VMQYPKM UKú PKG IQFK VQ I CUC YGVQ KH TGUWNV  ,1RVKQP2CPG;'5A126+10 VJTQY PGY 2TQRGTV[8GVQ'ZEGRVKQP 7UGT ECPEGNGF ENQUG  GXGPV  _ _ _   WUVCNC RQ[ELG TCOMK KPV YKFVJ  FGUMVQRIGV9KFVJ   KPV JGKIJV  FGUMVQRIGV*GKIJV   KHTCOGTGUJCRG PGZV(TCOG: PGZV(TCOG; YKFVJ JGKIJV  KHTCOGUJQY   Y[DÎT TCOMK  OQ G QUVCè CYGVQYCP[ VT[ ] KHTCOGUGV5GNGEVGF VTWG  _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G
  • 506 Java 2. Techniki zaawansowane ]_ 
  • LG NK RKGTYU[ TC VQ QDNKEC QFNGI Q è RQOKúF[ TCOMCOK TQOKGUEQP[OK MCUMCFQYQ
  •  KH HTCOG&KUVCPEG   HTCOG&KUVCPEG  KHTCOGIGV*GKIJV  KHTCOGIGV%QPVGPV2CPG IGV*GKIJV   Y[PCEC RQ[ELú MQNGLPGL TCOMK PGZV(TCOG:  HTCOG&KUVCPEG PGZV(TCOG;  HTCOG&KUVCPEG KH PGZV(TCOG: YKFVJ FGUMVQRIGV9KFVJ PGZV(TCOG:   KH PGZV(TCOG; JGKIJV FGUMVQRIGV*GKIJV PGZV(TCOG;   _ 
  • 4QOKGUEC MCUMCFQYQ VG TCOMK RWNRKVW MVÎTG PKG Uæ YKPKúVG FQ KMQP[
  •  RWDNKE XQKF ECUECFG9KPFQYU ] ,+PVGTPCN(TCOG=? HTCOGU  FGUMVQRIGV#NN(TCOGU  KPV Z   KPV [   KPV YKFVJ  FGUMVQRIGV9KFVJ   KPV JGKIJV  FGUMVQRIGV*GKIJV   HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU+EQP ] VT[ ]  RTÎDWLG RTGRTQYCFKè TCOMK FQ UVCPW RQ TGFPKGIQ  EQ OQ G QUVCè CYGVQYCPG HTCOGU=K?UGV/CZKOWO HCNUG  HTCOGU=K?TGUJCRG Z [ YKFVJ JGKIJV  Z  HTCOG&KUVCPEG [  HTCOG&KUVCPEG  CYKLC FQQMQ C DTGIW RWNRKVW KH Z YKFVJ FGUMVQRIGV9KFVJ Z   KH [ JGKIJV FGUMVQRIGV*GKIJV [   _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ _ 
  • 4QOKGUEC UæUKCFWLæEQ VG TCOMK RWNRKVW MVÎTG PKG Uæ YKPKGVG FQ KMQP[
  •  RWDNKE XQKF VKNG9KPFQYU ]
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 507 ,+PVGTPCN(TCOG=? HTCOGU  FGUMVQRIGV#NN(TCOGU   NKEC TCOMK MVÎTG PKG Uæ YKPKúVG FQ KMQP[ KPV HTCOG%QWPV   HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU+EQP HTCOG%QWPV  _ KPV TQYU  KPV /CVJUSTV HTCOG%QWPV  KPV EQNU  HTCOG%QWPV  TQYU KPV GZVTC  HTCOG%QWPV TQYU  NKEDC MQNWOP FQFCVMQY[O YKGTUGO KPV YKFVJ  FGUMVQRIGV9KFVJ  EQNU KPV JGKIJV  FGUMVQRIGV*GKIJV  TQYU KPV T   KPV E   HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU+EQP ] VT[ ] HTCOGU=K?UGV/CZKOWO HCNUG  HTCOGU=K?TGUJCRG E
  • YKFVJ T
  • JGKIJV YKFVJ JGKIJV  T  KH T  TQYU ] T   E  KH E  EQNU  GZVTC ]  TQRQE[PC FQFCVMQY[ YKGTU TQYU  JGKIJV  FGUMVQRIGV*GKIJV  TQYU _ _ _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ _ 
  • 9[DKGTC TCOMú
  •  RWDNKE XQKF UGNGEV0GZV9KPFQY ] ,+PVGTPCN(TCOG=? HTCOGU  FGUMVQRIGV#NN(TCOGU  HQT KPV K   K  HTCOGUNGPIVJ K ] KH HTCOGU=K?KU5GNGEVGF ]
  • 508 Java 2. Techniki zaawansowane  PCLFWLG TCOMú MVÎTC PKG LGUV YKPKúVC FQ KMQP[  K OQ G QUVCè Y[DTCPC VT[ ] KPV PGZV  K  HTCOGUNGPIVJ YJKNG PGZV  K HTCOGU=PGZV?KU+EQP PGZV  PGZV  HTCOGUNGPIVJ KH PGZV  K TGVWTP  RQQUVC G TCOMK Uæ YKPKúVG FQ KMQP NWD I QUK [ YGVQ FQ Y[DQTW HTCOGU=PGZV?UGV5GNGEVGF VTWG  HTCOGU=PGZV?VQ(TQPV  TGVWTP _ ECVEJ 2TQRGTV[8GVQ'ZEGRVKQP G ]_ _ _ _ 
  • 2TQUK W [VMQYPKMC Q QVYCTEKG RNKMW *6/.
  •  RWDNKE XQKF QRGP(KNG ]  RQYCNC W [VMQYPKMQYK Y[DTCè RNKM ,(KNG%JQQUGT EJQQUGT  PGY ,(KNG%JQQUGT  EJQQUGTUGV%WTTGPV&KTGEVQT[ PGY (KNG   EJQQUGTUGV(KNG(KNVGT PGY LCXCZUYKPIHKNGEJQQUGT(KNG(KNVGT ] RWDNKE DQQNGCP CEEGRV (KNG H ] 5VTKPI HPCOG  HIGV0COG VQ.QYGT%CUG  TGVWTP HPCOGGPFU9KVJ JVON ^^ HPCOGGPFU9KVJ JVO ^^ HKU&KTGEVQT[  _ RWDNKE 5VTKPI IGV&GUETKRVKQP ] TGVWTP *6/. (KNGU  _ _  KPV T  EJQQUGTUJQY1RGP&KCNQI VJKU  KH T  ,(KNG%JQQUGT#22418'A126+10 ]  QVYKGTC Y[DTCP[ RNKM 5VTKPI HKNGPCOG  EJQQUGTIGV5GNGEVGF(KNG IGV2CVJ  VT[ ] 74. HKNG7TN  PGY 74. HKNG HKNGPCOG  ETGCVG+PVGTPCN(TCOG ETGCVG'FKVQT2CPG HKNG7TN  HKNGPCOG  _ ECVEJ /CNHQTOGF74.'ZEGRVKQP G ]
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 509 _ _ _ 
  • 6YQT[ RCPGN GF[VQTC "RCTCO W CFTGU 74. FQMWOGPVW *6/.
  •  RWDNKE %QORQPGPV ETGCVG'FKVQT2CPG 74. W ]  VYQT[ RCPGN GF[VQTC WOQ NKYKCLæE[ RQTWUCPKG UKú RQ JKRGT æECEJ ,'FKVQT2CPG GFKVQT2CPG  PGY ,'FKVQT2CPG  GFKVQT2CPGUGV'FKVCDNG HCNUG  GFKVQT2CPGCFF*[RGTNKPM.KUVGPGT PGY *[RGTNKPM.KUVGPGT ] RWDNKE XQKF J[RGTNKPM7RFCVG *[RGTNKPM'XGPV GXGPV ] KH GXGPVIGV'XGPV6[RG  *[RGTNKPM'XGPV'XGPV6[RG#%6+8#6'& ETGCVG+PVGTPCN(TCOG ETGCVG'FKVQT2CPG GXGPVIGV74.  GXGPVIGV74. VQ5VTKPI  _ _  VT[ ] GFKVQT2CPGUGV2CIG W  _ ECVEJ +1'ZEGRVKQP G ] GFKVQT2CPGUGV6GZV 'ZEGRVKQP G  _ TGVWTP PGY ,5ETQNN2CPG GFKVQT2CPG  _ RTKXCVG ,&GUMVQR2CPG FGUMVQR RTKXCVG KPV PGZV(TCOG: RTKXCVG KPV PGZV(TCOG; RTKXCVG KPV HTCOG&KUVCPEG RTKXCVG UVCVKE HKPCN KPV 9+&6*   RTKXCVG UVCVKE HKPCN KPV *'+)*6   _ LCXCZUYKPI,&GUMVQR2CPG n ,+PVGTPCN(TCOG=? IGV#NN(TCOGU zwraca wszystkie ramki wewnętrzne panelu pulpitu. n XQKF UGV&TCI/QFG KPV OQFG określa sposób zachowania ramek wewnętrznych panelu podczas przeciągania (tylko zarys bądź tak e zawartość ramki). Parametry: OQFG jedna z wartości ,&GUMVQR2CPG.+8'A&4#)A/1&' lub ,&GUMVQR2CPG176.+0'A&4#)A/1&'.
  • 510 Java 2. Techniki zaawansowane LCXCZUYKPI,+PVGTPCN(TCOG n ,+PVGTPCN(TCOG n ,+PVGTPCN(TCOG 5VTKPI VKVNG n ,+PVGTPCN(TCOG 5VTKPI VKVNG DQQNGCP TGUKCDNG n ,+PVGTPCN(TCOG 5VTKPI VKVNG DQQNGCP TGUKCDNG DQQNGCP ENQUCDNG n ,+PVGTPCN(TCOG 5VTKPI VKVNG DQQNGCP TGUKCDNG DQQNGCP ENQUCDNG DQQNGCP OCZKOKCDNG n ,+PVGTPCN(TCOG 5VTKPI VKVNG DQQNGCP TGUKCDNG DQQNGCP ENQUCDNG DQQNGCP OCZKOKCDNG DQQNGCP KEQPKHKCDNG Tworzą nową ramkę wewnętrzną. Parametry: VKVNG tytuł ramki, TGUKCDNG wartość VTWG, jeśli rozmiary ramki mogą być zmieniane, ENQUCDNG wartość VTWG, jeśli ramka mo e być zamykana, OCZKOKCDNG wartość VTWG, jeśli ramka mo e być maksymalizowana, KEQPKHKCDNG wartość VTWG, jeśli ramka mo e być zwijana do ikony, n DQQNGCP KU4GUKCDNG n DQQNGCP KU%NQUCDNG n DQQNGCP KU/CZKOKCDNG n DQQNGCP KU+EQPKHKCDNG Sprawdzają odpowiednie właściwości ramki. Jeśli właściwość posiada wartość VTWG, oznacza to tak e obecność odpowiedniej ikony w pasku tytułu ramki. n DQQNGCP KU+EQP n XQKF UGV+EQP DQQNGCP D n DQQNGCP KU/CZKOWO n XQKF UGV/CZKOWO DQQNGCP D n DQQNGCP KU%NQUGF n XQKF UGV%NQUGF DQQNGCP D Sprawdzają lub ustawiają właściwości ramki. Jeśli właściwość posiada wartość VTWG, oznacza to, e ramka jest zwinięta do ikony, zmaksymalizowana bądź zamknięta. n DQQNGCP KU5GNGEVGF n XQKF UGV5GNGEVGF DQQNGCP D Sprawdza lub ustawia właściwość wyboru ramki. Jeśli właściwość posiada wartość VTWG, oznacza to, e ramka jest wybraną ramką pulpitu. n XQKF OQXG6Q(TQPV
  • Rozdział 6. n Zaawansowane mo liwości pakietu Swing 511 n XQKF OQXG6Q$CEM Umieszcza ramkę na wierzchu lub spodzie pulpitu. n XQKF TGUJCRG KPV Z KPV [ KPV YKFVJ KPV JGKIJV przesuwa ramkę i zmienia jej rozmiar. Parametry: Z, [ nowe współrzędne lewego górnego naro nika ramki, YKFVJ, JGKIJV szerokość i wysokość ramki. n %QPVCKPGT IGV%QPVGPV2CPG n XQKF UGV%QPVGPV2CPG %QPVCKPGT E Pobierają i zwracają panel ramki wewnętrznej. n ,&GUMVQR2CPG IGV&GUMVQR2CPG pobiera pulpit dla danej ramki wewnętrznej. n +EQP IGV(TCOG+EQP n XQKF UGV(TCOG+EQP +EQP KEQP Pobierają i nadają ikonę ramki umieszczoną w jej pasku tytułowym. n DQQNGCP KU8KUKDNG n XQKF UGV8KUKDNG DQQNGCP D Sprawdzają i ustawiają właściwość „widoczności” ramki. n XQKF UJQY sprawia, e ramka staje się widoczna i pojawia się na wierzchu pulpitu. LCXCZUYKPI,%QORQPGPV n XQKF CFF8GVQCDNG%JCPIG.KUVGPGT 8GVQCDNG%JCPIG.KUVGPGT NKUVGPGT instaluje obiekt nasłuchujący zmiany, która mo e zostać zawetowana. Jest on zawiadamiany, gdy ma miejsce próba zmiany ograniczonej właściwości. LCXCDGCPU8GVQCDNG%JCPIG.KUVGPGT n XQKF XGVQCDNG%JCPIG 2TQRGTV[%JCPIG'XGPV GXGPV metoda wywoływana, gdy metoda UGV ograniczonej właściwości zawiadamia obiekt nasłuchujący zmiany, która mo e być zawetowana. LCXCDGCPU2TQRGTV[%JCPIG'XGPV n 5VTKPI IGV2TQRGTV[0COG zwraca nazwę zmienianej właściwości. n 1DLGEV IGV0GY8CNWG zwraca proponowaną nową wartość właściwości. LCXCDGCPU2TQRGTV[8GVQ'ZEGRVKQP n 2TQRGTV[8GVQ'ZEGRVKQP 5VTKPI TGCUQP 2TQRGTV[%JCPIG'XGPV GXGPV tworzy wyjątek weta zmiany właściwości. Parametry: TGCUQP powód weta, GXGPV wetowane zdarzenie.