Programowanie w języku Java WYKŁAD

Podobne dokumenty
Programowanie zdarzeniowe

Architektura interfejsu użytkownika

Programowanie obiektowe

Podstawy Swing. Tomasz Borzyszkowski

Podstawy Języka Java

Programowanie w Javie Wykład 6 Okienka w Javie (AWT)

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java - interfejs graficzny

Informatyka I. Interfejs GUI wysokiego poziomu. Biblioteka Swing. Programowanie zdarzeniowe. Politechnika Warszawska Wydział Transportu 2018

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Tworzenie prezentacji w MS PowerPoint

GUI - projektowanie interfejsów cz. II

Kompleksowe tworzenie aplikacji klasy Desktop z wykorzystaniem SWT i

Tworzenie elementów graficznych

Programowanie zdarzeniowe

Informatyka Arkusz kalkulacyjny Excel 2010 dla WINDOWS cz. 1

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science

Programowanie graficznego interfejsu użytkownika. Wykład 8. Maciej Wołoszyn 10 maja 2006

Programowanie graficznych interfejsów użytkownika

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science

Aplikacje w Javie wykład 12 Programowanie GUI

Informatyka Arkusz kalkulacyjny Excel 2010 dla WINDOWS cz. 1

Dodanie nowej formy do projektu polega na:

Celem ćwiczenia jest zapoznanie się z podstawowymi funkcjami i pojęciami związanymi ze środowiskiem AutoCAD 2012 w polskiej wersji językowej.

Programowanie Obiektowe GUI

Java Podstawy. Michał Bereta

Compas 2026 Vision Instrukcja obsługi do wersji 1.07

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.3

I Tworzenie prezentacji za pomocą szablonu w programie Power-Point. 1. Wybieramy z górnego menu polecenie Nowy a następnie Utwórz z szablonu

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.3

Graphic User Interfaces pakiet Swing

Język JAVA podstawy. Wykład 5, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

I. Spis treści I. Spis treści... 2 II. Kreator szablonów Tworzenie szablonu Menu... 4 a. Opis ikon Dodanie nowego elementu...

Laboratorium z Grafiki InŜynierskiej CAD. Rozpoczęcie pracy z AutoCAD-em. Uruchomienie programu

Słowa kluczowe Sterowanie klawiaturą, klawiatura, klawisze funkcyjne, przesuwanie obiektów ekranowych, wydawanie poleceń za pomocą klawiatury

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.1

1. Umieść kursor w miejscu, w którym ma być wprowadzony ozdobny napis. 2. Na karcie Wstawianie w grupie Tekst kliknij przycisk WordArt.

Zadanie 1. Stosowanie stylów

Programowanie obiektowe

Programowanie w środowisku graficznym- wykład 9 Programowanie GUI cz1

BAZY DANYCH Formularze i raporty

Ćwiczenia 9 - Swing - część 1

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.

1. Przypisy, indeks i spisy.

Edytor tekstu MS Office Word

Wypożyczalnia VIDEO. Technologie obiektowe

Edytor tekstu MS Word podstawy

UNIWERSYTET RZESZOWSKI KATEDRA INFORMATYKI

Nr: 15. Tytuł: Kancelaris w systemie Windows 8 i Windows 8.1. Data modyfikacji:

LABORATORIUM 7 Cel: 1_1

Budowa aplikacji z graficznym interfejsem użytkownika - GUI (Graphic User Interface)

Utworzenie aplikacji mobilnej Po uruchomieniu Visual Studio pokazuje się ekran powitalny. Po lewej stronie odnośniki do otworzenia lub stworzenia

Kurs programowania 2 - listy

Edytor tekstu OpenOffice Writer Podstawy

Grafika i komunikacja człowiek komputer Laboratorium. Część 1: Wstęp do grafiki

CZĘŚĆ A PIERWSZE KROKI Z KOMPUTEREM

Tworzenie okna dialogowego w edytorze raportu SigmaNEST. część 1

ROZDZIAŁ I. BUDOWA I FUNKCJONOWANIE KOMPUTERA PC

Visual Studio instalacja

Adobe InDesign lab.1 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Podstawy pracy z aplikacją Układ strony... 2.

Systemy operacyjne na platformach mobilnych

Wymagania edukacyjne z informatyki dla klasy szóstej szkoły podstawowej.

Aktywności są związane z ekranem i definiują jego wygląd. Dzieje się to poprzez podpięcie do aktywności odpowiedniego widoku.

Sekretne menu Start. Przycisk pulpitu

Dodawanie grafiki i obiektów

Wzorce projektowe cz. II. Wzorce projektowe cz. II 1/35

Techniki wstawiania tabel

Podręcznik użytkownika programu. Ceremonia 3.1

Przypisy i przypisy końcowe

Forum Client - Spring in Swing

Język Java część 2 (przykładowa aplikacja)

Kurs programowania aplikacji bazodanowych

Klasy abstrakcyjne. Klasę abstrakcyjną tworzymy przy pomocy modyfikatora abstract

Systemy wirtualnej rzeczywistości. Komponenty i serwisy

Język Java część 2 (przykładowa aplikacja)

Tworzenie bazy danych na przykładzie Access

Podstawy technologii cyfrowej i komputerów

Java biblioteka Swing

SWING. dr Jarosław Skaruz

E-geoportal Podręcznik użytkownika.

Komputery I (2) Panel sterowania:

Informatyka Edytor tekstów Word 2010 dla WINDOWS cz.1

na podstawie modelu 3D

Prezentacja multimedialna MS PowerPoint 2010 (podstawy)

Kraków, ver

1. Dockbar, CMS + wyszukiwarka aplikacji Dodawanie portletów Widok zawartości stron... 3

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL III TI 4 godziny tygodniowo (4x30 tygodni =120 godzin ),

Lokalizacja jest to położenie geograficzne zajmowane przez aparat. Miejsce, w którym zainstalowane jest to urządzenie.

Podstawy technologii WWW

Cel: Przypisujemy przyciskom określone funkcje panel górny (Panel1)

Rozdział II. Praca z systemem operacyjnym

Expo Composer Garncarska Szczecin tel.: info@doittechnology.pl. Dokumentacja użytkownika

5. Kliknij teraz na ten prostokąt. Powinieneś w jego miejsce otrzymać napis. Jednocześnie została wywołana kolejna pozycja menu.

4.2. Ustawienia programu

MS Word Długi dokument. Praca z długim dokumentem. Kinga Sorkowska

Ćwiczenia nr 2. Edycja tekstu (Microsoft Word)

MS Access formularze

Lp. Nazwisko Wpłata (Euro)

Czcionki bezszeryfowe

PWŚG Ćwiczenia 13. Ukończoną pracę należy przesłać na adres lub

Transkrypt:

Programowanie w języku Java WYKŁAD dr inż. Piotr Zabawa Certyfikowany Konsultant IBM/Rational e-mail: pzabawa@pk.edu.pl www: http://www.pk.edu.pl/~pzabawa 12.05.2014

WYKŁAD 11 GUI w Swing cz. 2 Wykład został w znacznej mierze opracowany na podstawie: http://edu.pjwstk.edu.pl/wyklady/poj/scb/prggui1/prggui1.html#prggui1 http://edu.pjwstk.edu.pl/wyklady/poj/scb/rozswi/rozswi.html#rozswi http://edu.pjwstk.edu.pl/wyklady/poj/scb/mvc/mvc.html#mvc

GUI w Swing Zakład Inżynierii Oprogramowania Zasady działania na komponentach GUI: Komponenty tworzymy za pomocą wyrażenia new wywołującego odpowiedni konstruktor klasy komponentu, któremu podajemy argumenty, określające niektóre właściwości komponentu (np. tekst/ikonę na przycisku). Komponenty mają właściwości (np. kolory, pismo tekstu na przycisku), które możemy ustalać (lub pobierać) za pomocą metod z odpowiednich klas komponentów (metody setnnn(...), getnnn(...), isnnn(...), gdzie NNN nazwa właściwości). Większość właściwości komponentów jest reprezentowane przez obiekty odpowiednich klas (np. pismo klasa Font, kolor klasa Color) Komponenty, które mogą zawierać inne komponenty nazywają się kontenerami. Do kontenerów dodajemy inne komponenty (w tym inne kontenery) Z każdym kontenerem związany jest określony zarządca rozkładu, który określa układ komponentów w kontenerze i ich zachowanie (zmiany rozmiarów i położenia) przy zmianie rozmiarów kontenera. Inaczej: rozkład jest jedną z właściwości kontenera. Zarządcy rozkładu są obiektami odpowiednich klas

GUI w Swing Zakład Inżynierii Oprogramowania Dla każdego kontenera możemy ustalić wybranego zarządcę rozkładu Aplikacja komunikuje się z użytkownikiem za pomocą okna lub wielu okien Okna AWT są kontenerami, do których dodajemy komponenty wizualnej interakcji z użytkownikiem (w tym inne kontenery) Okna Swingu zawierają tzw. contentpane, który jest kontenerem do którego domyślnie dodajemy komponenty wizualnej interakcji (w tym inne kontenery). Okna (w tym "okno" apletu) są zawsze kontenerami najwyższego poziomu w hierarchii zawierania się komponentów Współdziałanie użytkownika z aplikacją odbywa się na zasadzie obsługi zdarzeń (np. zdarzenia kliknięcia w przycisk). Obsługą zdarzeń zarządza specjalny, równolegle z naszym programem wykonujący się kod w JVM wątek obsługi zdarzeń. O obsłudze zdarzeń w następnym wykładzie.

GUI w Swing AWT/Swing Ograniczenia AWT, dla których pokonania opracowano Swing: ubogie możliwości graficzne i interakcyjne komponentów, brak komponentów istotnych dla oprogramowania nowoczesnych GUI (np. tabel) zależny od platformy systemowej wygląd komponentów Umiejscowienie pakietu AWT: java.awt Kolejny ważny problem AWT, to fakt, że komponenty końcowe (powoływane do życia w aplikacjach) są komponentami ciężkimi.

GUI w Swing AWT/Swing Zalety Swing: Rozbudowanie istniejących komponentów AWT Wprowadzenie nowych komponentów AWT Odpowiednie rozdzielone hierarchie zostaną pokazane dalej. Umiejscowienie pakietu Swing: javax.swing Kolejna cech charakterystyczna Swing, to fakt, że wszystkie komponenty Swing z wyjątkiem znajdujących się najwyżej w hierarchii są komponentami lekkimi.

GUI w Swing AWT/Swing Komponenty ciężkie są realizowane poprzez użycie graficznych bibliotek GUI systemu operacyjnego. Komponenty lekkie są natomiast rysowane za pomocą kodu Javy w obszarze jakiegoś komponentu ciężkiego znajdującego się wyżej w hierarchii zawierania się komponentów (zwykle jest to kontener najwyższego poziomu).

GUI w Swing AWT/Swing Znaczenie tego gdzie lepiej w hierarchii umieścić klasy lekkie a gdzie ciężkie można prawidłowo i ogólnie zrozumieć studiując wzorce projektowe: Strategia Dekorator

GUI w Swing AWT/Swing Zatem komponenty lekkie: mogą być przezroczyste, a zatem mogą przybierać wizualnie dowolne kształty mają wygląd niezależny od platformy. Lekkie komponenty Swingu spełniają oba te warunki, a architektura klas Swingu pozwala wybierać wygląd jego lekkich komponentów (pluggable look and feel).

GUI w Swing AWT/Swing UWAGA: da się mieszać ze sobą komponenty ciężkie AWT i lekkie Swing poprzez umieszczenie ich w tym samym kontenerze, ale nie jest to zalecane. Powoduje to problemy z prawidłową obsługą kolejności nakładania na siebie elementów GUI w osi Z (Z-order). Ze względu na ten problem zdecydowano się opracować dość złożoną strukturę okien w Swing. Dlatego w Swing należy dodawać komponenty do ContentPane okna JFrame.

GUI w Swing AWT/Swing Poniżej przedstawiono na diagramie klas związki między AWT i Swing.

GUI w Swing AWT/Swing Komponenty Swingu o rozbudowanych możliwosciach w stosunku do AWT (AWT ma swoje odpowiedniki) [Źródło: Magellan Institute Swing Short Course.]

GUI w Swing AWT/Swing Hierarchia klas komponentów Swingu, nie mających odpowiedników w AWT [Żródło: Magellan Institute Swing Short Course.]

GUI w Swing kontenery Panel: klasa JPanel służy do grupowania komponentów Panel dzielony: klasa JSplitPane podział kontenera na dwie części (poziomo lub pionowo) z możliwością przesuwania belki podziału dla ustalenia rozmiarów widoków części Panel zakładkowy: klasa JTabbedPane zakładki służą do wybierania komponentów, które mają być uwidocznione w panelu

GUI w Swing kontenery Panel przewijany: klasa JScrollPane służy do pokazywania komponentów, które nie mieszczą się w polu widoku; suwaki umożliwiają "przewijanie" widoku komponentu, tak, by odsłaniać kolejne jego fragmenty. JTextArea i JList powinny być umieszczane w JScrollPane, jeśli ich zawartość (wiersze tekstu, elementy listy) może się powiększać. Pasek narzędzi: klasa JToolBar

GUI w Swing komponenty Lista własności wszystkich komponentów Swing: rozmiar (Size) szerokość (Width) wysokość (Height) położenie (Location) rozmiar i położenie (Bounds) minimalny rozmiar (MinimumSize) preferowany rozmiar (PreferredSize) mksymalny rozmiar (MaximumSize) wyrównanie po osi X (AlignmentX) wyrównanie po osi Y (AlignmentY)

GUI w Swing komponenty pismo (Font) kolor tła (Background) kolor pierwszego planu (Foreground) rodzic (Parent) nazwa (Name) widzialność (Visible) lekkość (LigthWeight) przezrosczystość (Opaque) dostępność (Enabled).

GUI w Swing Zakład Inżynierii Oprogramowania UWAGI: Rozmiary komponentów znane są dopiero po spakowaniu metodą pack() okna zawierającego te komponenty Położenie komponentu określane jest przez współrzędne (x,y), a punkt (0,0) oznacza lewy górny róg obszaru w którym znajduje się komponent Zmiana położenia i rozmiarów za pomocą metod set ma w zasadzie sens tylko dla komponentów znajdujących się w kontenerach bez zarządcy rozkładu lub dla komponentów-okien.

GUI w Swing Zakład Inżynierii Oprogramowania Pismo jest obiektem klasy Font, tworzonym za pomocą konstruktora Font(nazwa_pisma, styl, rozmiar) gdzie: nazwa_pisma - jest łańcuchem znakowym, określającym rodzaj pisma (np. "Dialog") styl - jest jedną ze stałych statycznych typu int z klasy Font: Font.BOLD Font.ITALIC Font.PLAIN (kombinacje uzyskujemy np. jako Font.BOLD Font.ITALIC) rozmiar - liczba całkowita określająca rozmiar pisma w punktach.

GUI w Swing Zakład Inżynierii Oprogramowania Kolor jest obiektem klasy Color, która ma kilka konstruktorów oraz udostępnia stałe statyczne typu Color z predefiniowanymi kolorami, np. Color.red, Color.blue, Color.white... Kolory przycisku możemy więc ustalić za pomocą takich konstrukcji: b.setbackground(color.blue); b.setforeground(color.white); albo: int r, g, b; r = 200; g = 200; b = 255; b.setbackground(new Color(r,g,b));

GUI w Swing Zakład Inżynierii Oprogramowania Zablokowanie/odblokowanie komponentu b.setenabled(false); // zablokowanie b.setenabled(true); // odblokowanie Zablokowanie komponentu powoduje, że nie jest on zdolny do przyjmowania zdarzeń.

GUI w Swing Zakład Inżynierii Oprogramowania Ukrywanie/uwidacznianie komponentów b.setvisible(false); // stanie się niewidoczny b.setvisible(true); // stanie się widoczny Komponent po ukryciu staje się niewidoczny na ekranie. Wszystkie komponenty z wyjątkiem wywodzących się z klasy Window są domyślnie widoczne. Dodanie komponentu do wcześniej uwidocznionego kontenera powoduje pojawienie się tego komponentu.

GUI w Swing Zakład Inżynierii Oprogramowania Ustawianie/wyłączanie przeźroczystości Wszystkie komponenty AWT są nieprzeźroczyste. Przeźroczystością wszystkich komponentów Swing można sterować. Wszystkie komponenty Swing z wyjątkiem JLabel są domyślnie nieprzeźroczyste. setopaque(true); // komponent stanie się nieprzeźroczysty setopaque(false); // komponent stanie się przeźroczysty

GUI w Swing Zakład Inżynierii Oprogramowania Odświeżanie komponentu Swing Jest ono realizowane za pomocą odwołań zwrotnych (callback) inicjowanych przez JVM a skierowanych do metody paint() komponentu zaimplementowanej w klasie JComponent. Metody tej nie wolno wywoływać z kodu aplikacji, można ją jedynie przesłonić własną implementacją. Jeśli istnieje konieczność odrysowania komponentu przez aplikację, to należy użyć metody repaint(...). Przedefiniowanie metod paint(): w AWT należy przedefiniować public void paint(graphics), w Swingu metodę public void paintcomponent(graphics). Ostatnie z powyższych rozwiązań jest jednak nieeleganckie.

GUI w Swing Zakład Inżynierii Oprogramowania W metodzie paint() jednym z argumentów jest referencja do obiektu klasy Graphics. Obiekt ten reprezentuje tzw. kontekst graficzny danego komponentu. Kontekst graficzny jest swoistym logicznym "urządzeniem wyjściowym". Zwykle jest to ekran komputera, ale może to być np. wydruk lub bufor w pamięci. Logiczny kontekst graficzny może więc być związany z różnymi "urządzeniami wyjściowymi" na których "rysowany" jest komponent. Aby zagwarantować odpowiedni wygląd i funkcjonalność gotowych komponentów, których klasy dziedziczymy, w przedefiniowywanej metodzie paintcomponent należy na początku wywołać metodę paintcomponent z nadklasy.

GUI w Swing Zakład Inżynierii Oprogramowania Wyprowadzanie napisów w Swing

GUI w Swing - grafika Rysowanie obrazu z pliku Dostęp do obrazu z pliku możemy uzyskać za pomocą odwołania: Image img = Toolkit.getDefaultToolkit().getImage(nazwa_pliku); Wykreślaniem obrazu w obszarze komponentu wizualnego zajmuje się metoda drawimage z klasy Graphics. Ładowanie i wyświetlanie dużych obrazów w Swing wygląda nieładnie dług trwa i obraz ładuje się etapami. Wprowadzono więc dwie klasy: ImageObsrever MediaTracker

GUI w Swing okna okno wtórne (secondary window, child window) = okno które ma właściciela - inne okno okno pierwotne, właściciel innych okien (owner) = okno, które jest właścicielem innych okien Skutki prawa własności: zamknięcie okna pierwotnego powoduje zamknięcie okien wtórnych, które są jego własnością, minimalizacja okna pierwotnego powoduje minimalizację okien wtórnych, przesunięcie okna pierwotnego powoduje przesunięcie okien wtórnych (nie na wszystkich platformach) Okno wtórne może być oknem modalnym lub nie. Modalność oznacza, iż interakcja z oknem pierwotnym jest zablokowana do chwili zamknięcia okna wtórnego. Przy niemodalnym oknie wtórnym - możemy dalej działać na oknie pierwotnym. Z - order = uporządkowanie okien "po osi Z" (czyli jak się okna na siebie nakładają).

GUI w Swing okna Klasy okien: JWindow może zostać użyte do utworzenia skastomizowanych okien o następujących cechach: okno bez ramki, menu i tytułu ma właściciela - inne okno nie podlega przesunięciom wraz z właścicielem nie jest modalne JFrame - może zostać użyte do skonstruowania okien, które: nie mają właściciela nie są modalne Zwykle jest nim główne okno aplikacji (nie ma właściciela!).

GUI w Swing okna JDialog służy do konstruowania okien o następujących cechach: ma ramkę ma tytuł ma właściciela nie może mieć paska menu może, ale nie musi być modalne Przeznaczone jest wyłącznie do tworzenia okienek dialogowych. JInternalFrame okna wewnętrzne są lekkimi komponetami o funkcjonalności okien ramowych (JFrame). Cechy charakterystyczne: niezależny od platformy wygląd muszą być dodawane do innych kontenerów dodatkowe możliwości programistyczne (np. dynamicznych zmian właściwości takich jak możliwość zmiany rozmiaru, możliwość maksymalizacji itp.)

GUI w Swing okna Operacja zamknięcia okna może mieć różne skutki zdefiniowane za pomocą następujących stałych: DO_NOTHING_ON_CLOSE HIDE_ON_CLOSE - operacja domyślna (chowa okno, ale nie likwiduje go) DISPOSE_ON_CLOSE - usunięcie okna EXIT_ON_CLOSE - powoduje zamknięcie aplikacji

GUI w Swing rozkłady Rozkłady (Layouts) Metody: pack() wywoływana na rzecz kontenera; wywołuje metody układania komponentów przez zarządców rozkładu (Layout Managers) dla wszystkich kontenerów w hierarchii zawierania się komponentów w oknie revalidate() wywoływana na rzecz zmienionego komponentu, którego rozmiary uległy zmianie; jej wywołanie powoduje ponowne ułożenie komponentów w kontenerze przez zarządcę rozkładu repaint() wywoływana na rzecz zmienionego komponentu, którego rozmiary uległy zmianie; uwidacznia zmiany wynikające z wcześniejszego wywołania revalidate()

GUI w Swing rozkłady Menadżerowie rozkładu ingerują w rozkład komponentów w obszarze Content Pane okna a nie w całym oknie. Proste rozkłady: FlowLayout BorderLayout GridLayout Złożone rozkłady: GridBagLayout elastyczny ale trudny w użyciu CardLayout rzadko się przydaje GroupLayout stosowany w edytorach GUI

GUI w Swing rozkłady Najbardziej przydatne rozkłady z biblioteki Swing: BoxLayout prosty i bardzo elastyczny Bardzo przydatne rozkłady opracowane poza Swingiem: TableLayout MigLayout Można albo pisać własne Layout Managery, albo wyłączyć je i ustawiać kontrolki ręcznie: kontener.setlayout(null); setbounds(x,y,w,h), gdzie x, y - współrzędne położenia komponentu, w,h - szerokość i wysokość.

GUI w Swing rozkłady W celu zapewnienia atrakcyjnego wyglądu GUI w praktyce układa się za pomocą jednych rozkładów panele zagnieżdżając je w sobie, a dopiero w nich umieszcza się w różnych rozkładach kontrolki.

GUI w Swing wielowątkowość Tworzenie i odwoływanie się do komponentów Swingu (odczytywanie i zmiana ich właściwości) winno odbywać się wyłącznie w wątku obsługi zdarzeń. Wątek zdarzeń należy wykorzystać we własnej aplikacji za pomocą metod zdefiniowanych w java.awt.eventqueue ale dostępnych również z poziomu javax.swing.swingutilities: SwingUtilities.invokeLater() kod implementacji interfejsu Runnable zostanie przekazany do wykonania wątkowi obsługi zdarzeń, a wykonanie bieżącego wątku będzie kontynuowane SwingUtilities.invokeAndWait() j.w., ale wykonanie bieżącego wątku zostanie wstrzymane do chwili wykonania przekazanego kodu przez wątek obsługi zdarzeń

GUI w Swing wielowątkowość Przyjmuje się zasadę, że wszelkie działania na GUI (tworzenie komponentów, dodawanie komponentów do kontenerów, ustalanie właściwości komponentów wizualnych) winny być wykonywane w wątku obsługi zdarzeń. Możliwe jest też stosowanie osłabionej wersji powyższej zasady Swingu - dopiero po realizacji komponentów - czyli spakowaniu i/lub uwidocznieniu okna - wszelkie na nich działania muszą odbywać się w wątku obsługi zdarzeń, jednak nie jest to dobra praktyka ze względu na brak gwarancji poprawnego działania. UWAGA: w przykładzie załączonym do poprzedniego wykładu skorzystano oczywiście z zasady Swingu w poprawnej postaci. Z kodu przekazanego do wątku obsługi zdarzeń nie wolno wywoływać metody invokeandwait(), gdyż zablokuje to GUI.

GUI w Swing - komponenty Cechy wspólne komponentów Swing: są komponentami lekkimi o niezależnym od platformy systemowej wyglądzie (ale zależnym od dobieranych przez programistę ustaleń - "Look and Feel") możemy ustalać czy mają być przezroczyste, czy nie, istnieje możliwość zewnętrznego ustalania ich preferowanych, maksymalnych i minimalnych rozmiarów (metody setpreferredsize, setmaximumsize, setminimumsize), oraz ich wyrównania względem innych komponentów (metody setalignmentx, setalignmenty) mogą mieć ramki o dowolnie ustalanej formie (klasa BorderFactory), mogą mieć podpowiedzi ( "dymki" pomocy - fly-over help, tooltips) mogą być uaktywniane z klawiatury (operowanie na GUI za pomocą klawiatury, nie tylko myszki) mogą mieć przypisaną dodatkową informację (w postaci tablicy asocjacyjnej, kojarzącej obiekty-klucze i obiekty-wartości)

GUI w Swing - komponenty Przykład zawansowanych możliwości tworzenia ramek złożonych z kilku: comp.setborder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.blue), comp.getborder()); Można tworzyć własne ramki implementując metody paintborder() i getborderinsets() we własnej klasie dziedziczącej z AbstractBorder.

GUI w Swing komponenty Podpowiedzi: JButton b = new JButton("Commit"); b.settolltiptext("zapisz zmiany w bazie danych"); Tekst podpowiedzi może być napisem HTML.

GUI w Swing komponenty Ikony: Mogą zostać pobrane metodą getimage() z pliku graficznego zapisanego w jednym z następujących formatów: GIF, JPG/JPEG, PNG lub mogą zostać narysowane metodą painticon().

GUI w Swing - komponenty Przyciski Dostępne są następujące rodzaje: JButton JToggleButton (też nadklasa dla kolejnych dwóch) JCheckBox JradioButton Do grupowania przycisków typu "radio" (a więc wzajemnie wykluczających się zaznaczeń) służy klasa ButtonGroup. Po stworzeniu obiektu tej klasy, za pomocą metody add dodajemy do niego przyciski JRadioButton. Od tej chwili tylko jeden z dodanych przycisków może być aktualnie "zaznaczony". Uwaga: ButtonGroup nie jest kontenerem!

GUI w Swing komponenty Dla każdego rodzaju przycisku za pomocą metody setmnemonic(int c); możemy ustalić mnemonikę czyli literę (znak), który wciśnięty wraz z klawiszem alt spowoduje "kliknięcie" w przycisk. Znak ten jest podkreślony w tekście na przycisku.

GUI w Swing menu Hierarchia klas menu pokazana została na następnym slajdzie

GUI w Swing menu Możliwości dodawania skrótów klawiszowych do menu: setmnemonic(int) obsługuje pojedynczy klawisz skrótu setaccelerator(keystroke) obsługuje sekwencje klawiszy Istnieje też możliwość dodawania kleju pomiędzy elementy menu w celu rozsuwania ich pozycji, np. przesunięcia pozycji Help w menu bar do prawej strony. Można również modyfikować layout menu, gdyż jest ono kontenerem(!).

GUI w Swing okna Wszystkie okna w Swing, jako jedyny rodzaj komponentów są komponentami ciężkimi (z wyjątkiem lekkiego JInternalFrame). Struktura okna:

GUI w Swing okna Kontener layeredpane umożliwia operowanie warstwami komponentów. Są dwa rodzaje uporządkowania: warstw, głębokość których określa obiekt typu Integer (numer warstwy). Im wyższy numer, tym warstwa bliższa przedniego planu (Z-order), Np. komponent dodany do warstwy 1 będzie zasłaniany przez komponent dodany do warstwy 2 pozycji komponentów (na osi Z) umieszczonych w jednej warstwie; tutaj porządek jest odwrotny: komponent o wyższej pozycji jest przykrywany przez komponent o niższej pozycji Można też używać własnych warstw i dodawać do nich komponenty.

GUI w Swing okna Odniesienie do kontenera layeredpane okna frame możemy uzyskać poprzez: JLayeredPane lp = frame.getlayeredpane(); Dodanie komponentu comp do warstwy n (liczba całkowita): lp.add(comp, new Integer(n)); Dodanie komponentu comp do warstwy n na pozycji m (liczba całkowita): lp.add(comp, new Integer(n), m); Oprócz tego dostępne są metody klasy JLayeredPane, które dynamicznie zmieniają położenie komponentów w ramach warstwy i pomiędzy warstwami: lp.movetofront(comp) lp.movetoback(comp); lp.setlayer(comp, n); lp.setlayer(comp, n, m);

GUI w Swing okna Szyba Jest zawarta w rootpane i przykrywa cały rootpane. Domyślnie jest niewidoczna. Można ją jednak uaktywnić poprzez uwidocznienie: Component g = frame.getglasspane(); g.setvisible(true); Po uwidocznieniu oddziela ona nas od okna. Operacje możliwe do wykonywania na szybie: przechwytywanie zdarzeń wejściowych (mysz i klawiatura) rysowanie

GUI w Swing okna Można też stworzyć własną szybę, co jest szczególnie użyteczne, gdy na szybie chcemy coś rysować. Wtedy utworzoną przez nas szybę podstawiamy na miejsce standardowej za pomocą metody: setglasspane()

GUI w Swing okna Okna wewnętrzne (JInternalFrame) są lekkimi komponentami o funkcjonalności okien ramowych. Podstawowe różnice wobec zwykłych okien ramowych (JFrame): niezależny od platformy wygląd, muszą być dodawane do innych kontenerów, dodatkowe możliwości programistyczne (np. dynamicznych zmian właściwości takich jak możliwość zmiany rozmiaru, możliwość maksymalizacji itp.). Ponieważ okna wewnętrzne zawarte są zawsze w jakimś kontenerze, to stanowią one okna na wirtualnym pulpicie (nie mogą "wyjść" poza pulpit). Pulpitem (kontenerem zawierającym okna wewnętrzne) jest zwykle obiekt typu JDesktopPane, choć może to być i jakiś inny kontener.

GUI w Swing okna Okna klasy JInternalFrame nie generują zdarzeń typu WindowEvent. Zamiast tego dostępne są zdarzenia typu InternalFrameEvent, a do ich obsługi służą metody z interfejsu InternalFrameListener

GUI w Swing kontenery Każdy komponent Swing jest jednocześnie kontenerem. Nie należy jednak nadużywać możliwości traktowania wszystkich komponentów Swingu jako kontenerów. Swing dostarcza bowiem lepszych sposobów grupowania komponentów w wyspecjalizowanych panelach: JPanel - najprostszy panel, różniący się od panelu AWT tym, że jest J- komponentem (ze wszystkimi, omawianymi wcześniej konsekwencjami) JSplitPane - panel składających się z dwóch rozdzielonych paskiem podziału części, w których mogą być umieszczone dowolne komponenty (w tym oczywiście - kontenery) JTabbedPane - panel z zakładkami. Każda z zakładek daje dostęp do innego komponentu (zwykle kontenera) po kliknięciu w zakładkę wypełniającego cały panel, JScrollPane - panel przewijany, z suwakami; odpowiednik ScrollPane z AWT, ale o rozbudowanych możliwościach, JToolBar - pasek narzędzi, zawierający dowolne komponenty (zwykle przyciski obrazkowe)

GUI w Swing kontenery JTabbedPane Panel zakładkowy udostępnia zakładki (tekst, tekst i ikona lub sama ikona, możliwe jest również ustalenie jako zakładki dowolnego komponentu). Z każdą zakładką związany jest inny komponent, który po kliknięciu w zakładkę wypełnia panel. Zakładki mogą być ulokowane u góry, u dołu, po lewej lub po prawej stronie panelu. JScrollPane Komponenty mogące mieć paski przewijania powinny zostać umieszczone w kontenerze JScroll Pane, aby ich paski przewijania zostały uwidocznione. JScrollPane ma złożoną budowę - zarządza aż dziewięcioma komponentami.

GUI w Swing Zakład Inżynierii Oprogramowania JToolbar Od zwykłych kontenerów JToolBar różni się tym, że: może być przesywany myszką i doczepiany do dowolnego brzegu okna lub całkiem od okna odczepiony (właściwość "floatable") można do niego dodać separator za pomocą metody addseparator, można do niego dodawać obiekty typu Action (metoda add(action a)) ma domyślny rozkład BoxLayout.

GUI w Swing akcje Jeśli mamy kilka komponentów (np. przycisk na pasku narzędzi, element menu rozwijalnego lub element menu kontekstowego), które powinny mieć tę samą funkcjonalność, to możemy w łatwy sposób, jednokrotnie, funkcjonalność tę zdefiniować i łatwo przypisać ją tym komponentom. Służą do tego obiekty implementujące interfejs Action. Atrakcyjność obiektu-akcji polega na tym, iż po jego utworzeniu może on być równolegle dodany: do paska narzędzi (klasa JToolBar ma metodę add(action)), do menu rozwijalnego (klasa JMenu ma metodę add(action)), do menu kontekstowego

GUI w Swing akcje Mapy akcji i mapy klawiaturowe są bardziej ogólnym mechanizmem wiązania skrótów klawiszowych z akcjami (za pomocą nazw) niż mechanizmy omówione wcześniej (KeyListener, mnemoniki, akceleratory).

GUI w Swing akcje

GUI w Swing akcje Mapę klawiaturową J-komponentu comp można uzyskać za pomocą odwołania: InputMap imap = comp.getinputmap(int rodzaj); gdzie: rodzaj - rodzaj mapy: WHEN_FOCUSED, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN _IN_FOCUSED_WINDOW. Mapę akcji komponentu comp można uzyskać poprzez: ActionMap amap = comp.getactionmap(); Można też użyć odpowiednich metod setinputmap(...) i setactionmap(...). do ustalania map dla komponentów. Mapowanie odbywa się za pomocą wywołań metody: put(keystroke, Object)

GUI w Swing akcje Aby uzyskać obiekt klasy KeyStroke, reprezentujący skrót klawiaturowy stosujemy statyczmną metodę tej klasy: KeyStroke getkeystroke(string) której argumentem jest napis, oznaczający skrót klawiaturowy, np. "control D". Wiązanie odbywa się za pomocą wywołań metody: put(object, Action)

GUI w Swing obieralny wygląd W Swing można dynamicznie ustalać wygląd i zachowanie. Zarządzaniem wyglądem komponentów zajmuje się klasa UIManager. Można też korzystać z gotowych menadżerów wyglądu oferowanych poza Swingiem, np. : JGoodies elegancki UIManager.setLookAndFeel( "com.jgoodies.looks.plastic.plasticxplookandfeel"); Substance bardzo elastyczny i konfigurowalny UIManager.setLookAndFeel(new SubstanceLookAndFeel()); SubstanceLookAndFeel.setCurrentTheme(new SubstanceSteelBlueTheme()); Nimbus bardzo elegancki UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");

GUI w Swing integracja z pulpitem Istnieje możliwość integrowania aplikacji desktopowej Java opartej o Swing z pulpitami systemów operacyjnych. Rozwiązani te nie zostaną jednak tu omówione.

GUI w Swing czynności długotrwałe Czynności długotrwałe realizowane z poziomu GUI w Swing mogą być długotrwałe. Ich normalne wykonanie w wątku obsługi zdarzeń zablokowałoby możliwość korzystania z GUI na czas wykonania tych czynności. Długotrwałe czynności nie mogą być wykonywane w wątku obsługi zdarzeń (Event Dispatching Thread - EDT). Do rozwiązywania tych problemów służy klasa SwingWorker. Klasę tę wykorzystuje się przez dziedziczenie z niej. Dostępne metody: doinbackground() execute() done() get()

GUI w Swing czynności długotrwałe Klasa ta pozwala również uzyskiwać wyniki pośrednie długotrwałych operacji, co pozwala na aktualizowanie danych w GUI w celu wizualizacji postępów w wykonywaniu długotrwałego zadnia.

GUI w Swing MVC Architektura Swinga jest oparta o wzorzec architektoniczny MVC (Model-View-Controler). Zastosowanie tego wzorca służy m.in. ułatwieniu wprowadzania zmian do kodu źródłowego dzięki ograniczeniu zasięgu tych zmian. W ramach tego wzorca: model - określa dane związane z komponentem lub stany komponentu, widok (view) - określa wizualną reprezentację danych lub stanów, sterownik (controller) - zapewnia interakcję użytkownika z widokiem i wynikające stąd modyfikacje modelu.

GUI w Swing MVC W implementacji Swinga wprowadzono jednak pewne dodatkowe założenie ograniczające elastyczność podejścia oferowanego przez MVC, mianowicie połączono widok z kontrolerem za pomocą delegacji (delegacja jest prostym mechanizmem obiektowym polegającym na przeniesieniu części zobowiązań z obiektu do obiektu w nim agregowanego innymi słowy delegowanie oznacza stosowanie relacji agregacji). Obiekt ten to tzw. delegat UI. Zatem w Swing odseparowano model od delegatów UI. Wyróżnia się dwa typy modelu dla komponentów Swing: modele GUI - interfejsy definiujące wizualne stany komponentów, np. przycisk wciśnięty lub zaznaczenie elementu na liście, modele danych - interfejsy reprezentujące dane takie jak np. wartość komórki w tabeli lub elementu listy

GUI w Swing MVC Dostęp do modelu w ramach komponentu Swing dają metody: getmodel() setmodel()

GUI w Swing MVC JList Klasa ta implementuje oba interfejsy modelu: GUI i danych. Do tej pory działaliśmy na tym komponencie statycznie jak na liście (zamknięty zbiór danych). Jednak czasem potrzebne jest skorzystanie z modelu danych: jeśli chcemy w sposób niestandardowy (nie sprowadzający się do użycia tablic lub wektorów) określić zawartość listy - winniśmy stworzyć własny model danych jeśli chcemy mieć listę dynamiczną tzn. zmieniającą swoją zawartość - możemy stworzyć własny model lub posłużyć się modelem implementowanym w klasie DefaultListModel

GUI w Swing MVC Model danych dla listy jest określany przez interfejs ListModel, abstrakcyjna klasa AbstractListModel implementuje ten interfejs, pozostawiając do zdefiniowania w klasach pochodnych dwie ważne metody: Object getelementat(int i) - zwraca i-ty element modelu (element listy) int getsize() - zwraca liczbę elementów listy

GUI w Swing MVC Przykład powiązania modelu z kontrolerem: AbstractListModel listmodel = } new AbstractListModel() { public Object getelementat(int i) {} int getsize() {} Możliwości powiązania modelu z komponentem: JList list = new JList(); list.setmodel(listmodel); albo: JList list = new JList(listModel);

GUI w Swing MVC Komunikacja model-widok Zasady: Wszelkie zmiany (które ew. będą uwidocznione w widoku) muszą być dokonywane jako zmiany w modelu danych O każdej zmianie model musi powiadamiać zainteresowanych słuchaczy, kreując odpowiednie zdarzenia za pomocą metod fire...; zdarzenia te będą przekazywane do odpowiednich delegatów

GUI w Swing MVC Komunikacja model-widok dla JList Rodzaje modeli danych: model automatyczny, tworzony w konstruktorach, które nie mają modelu jako argumentu model domyślny (DefaultListModel) przygotowana klasa, która ułatwia tworzenie dynamicznych list modele własne Model automatyczny nie pozwala na automatyczne uwidacznianie zmian modelu w widoku. Oby uniknąć tego ograniczenia należy utworzyć własny model.

GUI w Swing MVC Zdarzenia zmian modelu należą do klasy ListDataEvent i mają następujące charakterystyki: typ (zapytanie gettype()): przedział indeksów dodany, przedział indeksów usunięty, zmiana zawartości dolny indeks przedziału (zapytanie getindex0()) górny indeks przedziału (zapytanie getindex1())

GUI w Swing MVC Do nasłuchu zmian w modelu służy interfejs ListDataListener, który udostępnia trzy metody: intervaladded(listdataevent e) intervalremoved(listdataevent e) contentschanged(listdataevent e) Klasa AbstractListModel definiuje trzy zabezpieczone metody, służące do powiadamiania słuchaczy o zmianach w modelu: protected void fireintervaladded(object source, int index0, int index1) protected void fireintervalremoved(object source, int index0, int index1) protected void firecontentschanged(object source, int index0, int index1) Metody te generują zdarzenia ListDataEvent z odpowiednimi charakterystykami i rozsyłają te zdarzenia do wszystkich zarejestrowanych słuchaczy.

GUI w Swing MVC Przykład tworzenia własnego modelu: Zbyt skomplikowany na slajdy, daje możliwość zrealizowania szerokiego spektrum funkcjonalności, ale rzadko jest potrzebny.

GUI w Swing MVC Realizowanie własnego modelu jest dość kłopotliwe. Dlatego twórcy Swinga wbudowali w tę bibliotekę klasę DefaultListModel. Sposób korzystania: DefaultListModel lm = new DefaultListModel(); JList list = new JList(lm); lm.addelement(...)

GUI w Swing MVC Nasłuch zmian modelu Istnieją dwa typy interfejsów nasłuchu: ChangeListener, który nasłuchuje zdarzeń typu ChangeEvent. Można z niego jedynie uzyskać informację o źródle zmiany (getsource), ale nie o jej charakterze trzeba odpytywać model. wyspecjalizowane interfejsy, które obsługują zdarzenia zawierające informacje o konkretnych zmianach modelu (wiele typów interfejsów nasłuchu oraz zdarzeń, specyficznych dla konkretnych modeli).

GUI w Swing MVC JComboBox Klasa JComboBox ma dwie przyjemne właściwości: pozwala na selekcję elementów listy poprzez wciskanie klawiszy oznaczających pierwsze litery napisów, oraz umożliwia dynamiczne zmiany zawartości listy bez bezpośredniego użycia modelu danych z nią związanych. Mimo to model może być nadal przydatny. Można go np. wykorzystać do odsiewania duplikatów z listy.

GUI w Swing MVC Wykreślacze (Renderers) Służą do rysowania komponentu, ale jedynie jako widok bez funkcjonalności.

GUI w Swing MVC JTable Komponent ten należy do najbardziej rozbudowanych. Prosty przykład: Object[][] dane = { {"Kowalski", "Jan", new Integer(30), new Boolean(true) }, { Jankowski", "Jan", new Integer(20), new Boolean(false) },... }; Object[] nazwykolumn = { }; "Nazwisko", "Imię", "Wiek", "Urlop wykorzystany?" JTable tab = new JTable(dane, nazwykolumn); JScrollPane sp = new JScrollPane(tab);

GUI w Swing MVC Każda tabela jest związana z trzema modelami: modelem danych - obiektem klasy implementującej interfejs TableModel, modelem kolumn - TableColumnModel, modelem selekcji - znany już interfejs ListSelectionModel. Zróżnicowanie modeli związane jest m.in. z potrzebą zapewnienia braku zgodności kolejności kolumn w modelu danych z ich kolejnością w widoku. Tabela może zawierać dowolne obiekty i wyświetlać w komórkach dowolne komponenty.

GUI w Swing MVC Klasa TableColumn zawiera metody określające właściwości kolumn tabeli. Z każdą kolumną - obiektem TableColumn - skojarzony jest: nagłówek, wykreślacz komórek (obiekt typu TableCellRenderer) edytor komórek (obiekt typu TableCellEditor) wykreślacz nagłówka. Pewne typy danych mają ustalone domyślne wykreślacze i edytory.

GUI w Swing MVC JTree Klasa JTree zapewnia hierarchiczne obrazowanie danych w postaci drzewa. W drzewach - podobnie jak w tabelach - mamy do czynienia: z modelem danych (klasy implementujące interfejs TreeMedel; domyślna implementacja DefaultTreeModel pozwala modyfikować drzewo przez modyfikacje modelu danych) z modelem selekcji węzłów (TreeSelectionModel) z nasłuchem zdarzeń selekcji (TreeSelectionListener) z wykreślaczami komórek (TreeCellRenderer) z edytorami komórek (TreeCellEditor).

GUI w Swing MVC Komponenty tekstowe Są to najbardziej rozbudowane komponenty Swinga. Uważa się, że pozwalają one na tworzenie dowolnie złożonych rozwiązań. Na kolejnym slajdzie pokazano hierarchię tych komponentów.

GUI w Swing MVC W tej złożonej architekturze można wyróżnić: model danych - reprezentowany przez obiekty klasy implementujących interfejs Document; model danych opisuje zawartość dokumentu widok - który zarządza uwidaczanianiem dokumentu i jego fragmentów (widoki są produkowane przez podklasy klasy View; pośredniczą pomiędzy modelem danych a widokami "niskiego poziomu" związanymi z delegatami UI) kontroler - edytor, który dostarcza możliwości edycyjnych oraz odczytu/zapisu dokumentów z/do strumieni. Edytory są obiektami klas dziedziczących klasę EditorKit powiązania pomiędzy klawiszami i akcjami edycyjnymi; interfejs KeyMap wiąże klawisze (obiekty typu KeyStroke) z obiektami typu Action; jest to alternatywny wobec ogólnego modelu akcji klawiaturowych (ActionMap i InputMap, o których mowa była w wykładzie 11) sposób tworzenia. modyfikacji i użycia klawiszy edycyjnych; model ogólny jest obecnie preferowany menedżer cofania (undo) i przywracania (redo) edycji (UndoManager), pozwalający łatwo realizować właściwości undo-redo kursor tekstowy - realizowany przez interfejs Caret; może być dowolnie dostosowywany jeśli chodzi o wygląd poprzez odpowiednią implementację tego interfejsu podświetlacze - realizowane przez interfejs Highliter; klasy implementujące ten interfejs określają sposoby zaznaczania różnych fragmentów dokumentu

GUI w Swing MVC Z komponentami tekstowymi wiążą się również nowe zdarzenia i nowe interfejsy nasłuchu: DocumentListener umożliwia śledzenie i reagowanie na zmiany w dokumencie (zdarzenie typu DocumentEvent) CaretListener pozwala śledzić zmiany pozycji kursora tekstowego (CaretEvent) UndoableEditionListener umożliwia kompletowanie dokonanych edycji (poprawek) i przygotowanie UndoManagera do ich cofania (a po cofnięciu - przywracania)

GUI w Swing Zakład Inżynierii Oprogramowania Istnieje możliwość tworzenia GUI z plików zasobów (property files lub XML), ale jest ona wspierana przez zewnętrzne narzędzia. Zaletą jest mniej kodu po stronie GUI i możliwość skupienia się w nim na obsłudze zdarzeń. Przykład narzędzia działającego w ten sposób: http://www.swixml.org/ Czy w NetBeans też tak się da?

GUI w Swing MVC Architektura Swing jest zgodna z wzorcem architektonicznym (należy odróżniać tę kategorię wzorców od wzorców projektowych) MVC (Model-View_Controler). W ramach tego wzorca warstwa prezentacji może być zależna od warstwy kontrolerów jak i od warstwy danych. Jednocześnie warstwa kontrolerów zależy od warstwy danych. Innych zależności w tym wzorcu nie ma. Są jednak znane wzorce architektoniczne lepsze pod względem możliwości wprowadzania, np. MVP (Model-View-Presenter) wolny od zależności warstwy prezentacji od warstwy danych.

GUI w Swing MVC Testowanie Wykorzystanie wzorca MVC nadaje nie tylko ramy implementacji ale wprowadza też możliwości uporządkowania podejścia do testowania oprogramowania. Można w ramach tego wzorca wykonywać następujące testy: Testy jednostkowe Testy elementów warstwy danych (klas encyjnych w UML stereotyp <<entity>>) Testy elementów warstwy kontrolerów (klas kontrolerów w UML stereotyp <<control>>)

GUI w Swing Zakład Inżynierii Oprogramowania Testy funkcjonalne Są to tylko i wyłącznie testy API warstwy kontrolerów Testy integracyjne - weryfikują one poprawność komunikacji pomiędzy warstwami: Danych i kontrolerów Prezentacji i kontrolerów Prezentacji i danych Testy GUI są to testy wykonywane na obiektach biblioteki Swing Warto pamiętać, że testy te są zwykle wykonywane kolejnymi kategoriami w takiej kolejności jak zostało to przedstawione powyżej ze względu na zależności pomiędzy ich rodzajami i czas ich wykonania.

GUI w Swing Zakład Inżynierii Oprogramowania Narzędzia testujące GUI w Swing z poziomu Eclipse: FEST -Swing Jubula functional testing tools (wraz z GUI Dancer) UISpec4J Google Window Tester Pro GUI Tester Maveryx Aktualny przegląd i charakterystyka niektórych narzędzi: https://wiki.eclipse.org/eclipse/testing

Koniec