9. Swing wprowadzenie



Podobne dokumenty
Java - interfejs graficzny

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

Programowanie zdarzeniowe

Podstawy Języka Java

Programowanie graficznych interfejsów użytkownika

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

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

Programowanie obiektowe

Graphic User Interfaces pakiet Swing

Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com

Kontenery i komponenty graficzne

Tworzenie elementów graficznych

Informatyka i Ekonometria Programowanie komputerów Ćwiczenia Tworzenie aplikacji wykorzystaniem graficznego interfejsu użytkownika - Swing.

SWING. dr Jarosław Skaruz

Programowanie zdarzeniowe

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

SWING ZAGADNIENIA: wprowadzenie, kontenery I komponenty, LayoutManager, komponenty tekstowe.

Podstawy Swing. Tomasz Borzyszkowski

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

LABORATORIUM 7 Cel: 1_1

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

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

Programowanie w języku JAVA. Wykład IV Swing - GUI

Java niezbędnik programisty spotkanie nr 12. Graficzny interfejs użytkownika

Java SE Laboratorium nr 5. Temat: Obsługa zdarzeń

Kurs programowania. Wykład 4. Wojciech Macyna. 23 marca 2016

Java biblioteka Swing

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

Interaktywne aplety obsługa zdarzeń, uruchamianie apletu przez przeglądarkę lub maszynę wirtualną Javy. Tworzenie łącz w apletach

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt

Pierwsza ramka. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 10

Programowanie Obiektowe GUI

Programowanie obiektowe

Tworzenie i obsługa graficznego interfejsu uŝytkownika

Programowanie obiektowe

setdefaultcloseoperation(jframe.exit_on_close);//obsługa zamykania aplikacji setvisible(true); } //wyświetlenie okna

Aplikacja wielowątkowa prosty komunikator

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

SWING ZAGADNIENIA: wprowadzenie, kontenery i komponenty, LayoutManager, komponenty tekstowe. inne przydatne komponenty.

SWING c.d. przydatne narzędzia: JFileChooser, JOptionPane. drag'n drop, menu kontekstowe.

Dodanie nowej formy do projektu polega na:

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

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Dokumentacja do API Javy.

Aplikacje w Javie wykład 12 Programowanie GUI

Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1).

Programowanie w języku Java WYKŁAD

Programowanie w języku Java

GUI - projektowanie interfejsów cz. II

Podstawy tworzenia aplikacji z wykorzystaniem języka Java ME ćwiczenia 1

Ćwiczenia 9 - Swing - część 1

Multimedia JAVA. Historia

KaŜdy z formularzy naleŝy podpiąć do usługi. Nazwa usługi moŝe pokrywać się z nazwą formularza, nie jest to jednak konieczne.

Aplikacje w środowisku Java

Kierunek: ETI Przedmiot: Programowanie w środowisku RAD - Delphi Rok III Semestr 5. Ćwiczenie 5 Aplikacja wielo-okienkowa

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

JAVA CZ.2 Programowanie obiektowe. poniedziałek, 20 kwietnia 2009

Aplikacja wielow tkowa prosty komunikator

Programowanie Multimediów. Programowanie Multimediów JAVA. programowanie GUI. (AWT i Swing) [1]

C-geo definicja/edycja obiektów, zapis danych w formacie shape

Wykład 7: Pakiety i Interfejsy

Wykład 4_1. Interaktywne aplety obsługa zdarzeń, uruchamianie apletu przez przeglądarkę lub maszynę wirtualną Javy.

PWSG Ćwiczenia 12. Wszystkie ukończone zadania należy wysłać na adres: lub

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

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

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

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

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

Architektura interfejsu użytkownika

Aplikacje w środowisku Java

Programowanie obiektowe

JAVA W SUPER EXPRESOWEJ PIGUŁCE

1. Co będzie wynikiem wykonania poniŝszych instrukcji? g2d.gettransform().scale(1, -1); g2d.gettransform().translate(4, -8); g2d.drawline(4, 0, 4, 4);

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

Projekt ZSWS. Instrukcja uŝytkowania narzędzia SAP Business Explorer Analyzer. 1 Uruchamianie programu i raportu. Tytuł: Strona: 1 z 31

Za pomocą atrybutu ROWS moŝemy dokonać podziału ekranu w poziomie. Odpowiedni kod powinien wyglądać następująco:

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

Bezpieczne uruchamianie apletów wg

Dodawanie grafiki i obiektów

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

Interfejsy i klasy wewnętrzne

GEO-SYSTEM Sp. z o.o. GEO-RCiWN Rejestr Cen i Wartości Nieruchomości Podręcznik dla administratora systemu Warszawa 2007

Klasy i obiekty cz II

Podstawowe informacje o apletach

Kadry Optivum, Płace Optivum

Java Foundation Clases. Tworzenie graficznych interfejsów użytkownika (GUI) w Javie

Laboratorium 7 Blog: dodawanie i edycja wpisów

Wykład 4: Klasy i Metody

1. Czynności przygotowujące aplikację działającą na platformie Java SE Biblioteka5 (należy ją pobrać z załącznika z p.1)

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

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Programowanie obiektowe zastosowanie języka Java SE

Projektowanie aplikacji internetowych laboratorium

Interfejsy w Java. Przetwarzanie równoległe. Wątki.

Oficyna Wydawnicza UNIMEX ebook z zabezpieczeniami DRM

Aplikacje WWW - laboratorium

System imed24 Instrukcja Moduł Analizy i raporty

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Tworzymy projekt File->New Project->Java Application, przy czym tym razem odznaczamy create main class

Zaawansowane programowanie obiektowe. Wykład 3 część 2

Transkrypt:

9.1 Komponenty 9. Swing wprowadzenie 9.2 Przykłady tworzenia GUI W. Kasprzak: Programowanie zdarzeniowe 9-1 9.1 Komponenty 1) Przegląd komponentów Swing-a 1. Kontenery główne 2. Kontenery ogólne pośredniego poziomu 3. Kontenery specjalne pośredniego poziomu 4. Podstawowe kontrolki (wejście od uŝytkownika) 5. Nieedytowalne komponenty informacyjne 6. Interaktywne komponenty z edytowalną sformatowaną informacją W. Kasprzak: Programowanie zdarzeniowe 9-2

Kontenery główne JApplet JDialog JFrame W. Kasprzak: Programowanie zdarzeniowe 9-3 Kontenery ogólne pośredniego poziomu JPanel JScrollPane JSplitPane JTabbedPane JToolBar W. Kasprzak: Programowanie zdarzeniowe 9-4

Kontenery specjalne pośredniego poziomu Internal frame Layered pane Root pane W. Kasprzak: Programowanie zdarzeniowe 9-5 Podstawowe kontrolki JButton JComboBox JList JMenu JSlider JSpinner JTextField lub JFormattedTextField W. Kasprzak: Programowanie zdarzeniowe 9-6

Nieedytowalne komponenty informacyjne JLabel JProgressBar JToolTip W. Kasprzak: Programowanie zdarzeniowe 9-7 Interaktywne komponenty z edytowalną sformatowaną informacją JColorChooser JFileChooser JTable JText JTree W. Kasprzak: Programowanie zdarzeniowe 9-8

2) Kontenery główne - JFrame, JDialog, JApplet Aby narysować komponent GUI na ekranie musi on naleŝeć do pewnej hierarchii komponentów, której korzeniem jest kontener główny. Komponent GUI moŝe być zawarty w danej hierarchii tylko raz dodanie go do innego kontenera spowoduje automatyczne usunięcie go z pierwszego. KaŜdy kontener główny zawiera content pane - zawiera (bezpośrednio lub pośrednio) wszystkie wizualne komponenty danego kontenera. Opcjonalnym elementem kontenera głównego jest pasek menu nie naleŝy on do content pane - zwykle umieszczany na górze obszaru kontenera. Przykład. Ramka zawiera pasek menu (kolor niebieski) i w content pane zawarta jest duŝa pusta etykieta w kolorze Ŝółtym. W. Kasprzak: Programowanie zdarzeniowe 9-9 Hierarchia komponentów Aplikacja o GUI opartym na Swing-u posiada przynajmniej jedną hierarchię komponentów o korzeniu będącym kontenerem klasy JFrame. Np. aplikacja ma trzy hierarchie komponentów jedną dla okna głównej ramka i dwa dla okien dialogowych (odpowiednio kontenery są obiektami klas JFrame i JDialog). W. Kasprzak: Programowanie zdarzeniowe 9-10

Aplet oparty na Swing-u posiada przynajmniej jedną hierarchię komponentów o korzeniu będącym obiektem klasy JApplet. Np. aplet posiadający okno dialogowe posiada dwie hierarchie komponentów jedna o korzeniu klasy JApplet a druga - JDialog. Dodanie komponentu do hierarchii metoda add dla content pane. Np. frame.getcontentpane().add(yellowlabel, BorderLayout.CENTER); Domyślna realizacja content pane to obiekt klasy pochodnej od JComponent posiadający menadŝera układu klasy BorderLayout. Panel zawartości moŝe być ustawiany przez uŝytkownika stosownie do jego wymagań. Uwaga: metoda getcontentpane zwraca obiekt klasy Container nie klasy JComponent wymaga konwersji do JComponent przed ustawieniem cech klasy JComponent panelu zawartości. Alternatywnym rozwiązaniem jest uczynienie własnego panelu panelem zawartości. Powinien on być nieprzezroczysty. Korzystamy z metody setcontentpane. Np. W. Kasprzak: Programowanie zdarzeniowe 9-11 // Utwórz panel i dodaj do niego komponenty JPanel contentpane = new JPanel(new BorderLayout()); contentpane.setborder(someborder); contentpane.add(somecomponent, BorderLayout.CENTER); contentpane.add(anothercomponent, BorderLayout.PAGE_END); // Uczyń panel panelem zawartości kontenera głównego contentpane.setopaque(true); głównykontener.setcontentpane(contentpane); Uwaga. Z zasady panelami zawartości nie powinny być obiekty klas przezroczystych kontenerów takich, jak JScrollPane, JSplitPane i JTabbedPane. Nawet po wymuszeniu ich nieprzezroczystości metodą setopaque(true) nie będą miały właściwego wyglądu. Jeszcze innym sposobem ustawienia panelu zawartości jest dodanie komponentu będącego kontenerem do panelu zawartości, który przykrywa w pełni obszar wizualizacji panelu. W. Kasprzak: Programowanie zdarzeniowe 9-12

Dodanie paska menu NaleŜy utworzyć obiekt klasy JMenuBar, dodać do niego obiekty menu i wywołać metodę setjmenubar. Np. frame.setjmenubar(cyanmenubar); Root Pane KaŜdy kontener główny zawiera pośredni kontener zwany root pane. Zarządza on content pane, paskiem menu i dalszymi kontenerami tzw. layered pane i glass pane. layered pane zawiera panel zawartości i pasek menu, umoŝliwia uporządkowanie dalszych komponentów na osi Z; glass pane słuŝy do przechwytywania zdarzeń wprowadzania informacji dla kontenera głównego i do jednoczesnego rysowania w obszarze wielu komponentów. W. Kasprzak: Programowanie zdarzeniowe 9-13 9.2 Przykłady tworzenia GUI Pakiet Swing ( javax.swing ) jest częścią "Java Foundation Classes (JFC)". Swing dostarcza wizualnych komponentów aplikacji - od przycisków do dzielonych paneli i wykazów - wspomagając uŝytkownika podczas projektowania jego GUI. Nazwy komponentów Swing-a rozpoczynają się na literę J. Pakiet Swing pojawił się jako dodatek do JDK 1.1. Przedtem komponenty GUI pochodziły z Abstract Window Toolkit (AWT) - w JDK 1.0 i 1.1. Wprawdzie Java 2 nadal zawiera komponenty AWT jednak powinniśmy zasadniczo korzystać z komponentów Swing-a. Gdy komponenty Swing-a "przecinają się" na ekranie z komponentami AWT, te ostatnie są zawsze kreślone na wierzchu. W. Kasprzak: Programowanie zdarzeniowe 9-14

1) Pierwszy program w Swing-u Przykład 9.1. Program HelloWorldSwing. Wizualny efekt programu: Kod programu HelloWorldSwing: import javax.swing.*; // Zaimportuj główny pakiet Swing-a. public class HelloWorldSwing { public static void main(string[] args) { JFrame frame = new JFrame("HelloWorldSwing"); // Kontener główny. final JLabel label = new JLabel("Hello World"); // Komponent frame.getcontentpane().add(label); // Dodaj etykietę do kontenera frame.setdefaultcloseoperation(jframe.exit_on_close); // Ustaw // domyślną reakcję obiektu klasy JFrame na aktywację przycisku "close". frame.pack(); // Przygotuj okno do prezentacji frame.setvisible(true); // Wyświetl okno Komentarz 1) Obok głównego pakietu W. Kasprzak: Programowanie zdarzeniowe 9-15 import javax.swing.*; większość programów w Swing-u będzie potrzebować 2 pakietów AWT: import java.awt.*; import java.awt.event.*; w celu obsługi zdarzeń. 2) KaŜdy program GUI w Swing-u wymaga przynajmniej jednego głównego kontenera, wspomagającego komponenty w rysowaniu i obsłudze zdarzeń. Istnieją 3 kontenery główne: JFrame, JDialog, JApplet (dla apletów). Obiekt klasy JFrame implementuje pojedyncze główne okno; Obiekt klasy JDialog implementuje wtórne okno (zaleŝne od innego okna); Obiekt klasy JApplet implementuje obszar ekranu wewnątrz okna przeglądarki. Obiekt klasy JFrame implementowany jest wizualnie jako okno posiadające "dekoracje" w postaci: ramki, tytułu, przycisków dla zmniejszania ("ikonizacji") i zamykania okna. W. Kasprzak: Programowanie zdarzeniowe 9-16

2) Przyciski i etykiety. Inny sposób zamykania okna to skorzystanie z mechanizmu obsługi zdarzeń - WindowListener: Np. frame.addwindowlistener(new WindowAdapter() { public void windowclosing(windowevent e) { System.exit(0); ); Przykład 9.2. Program SwingApplication. Po kaŝdym kliknięciu przycisku (obiekt klasy JButton) modyfikowana jest wartość etykiety (obiekt klasy JLabel). import javax.swing.*; import java.awt.*; W. Kasprzak: Programowanie zdarzeniowe 9-17 import java.awt.event.*; public class SwingApplication { private static String labelprefix = "Number of button clicks: "; private int numclicks = 0; public Component createcomponents() { // Utwórz komponenty final JLabel label = new JLabel(labelPrefix + "0 "); JButton button = new JButton("I'm a Swing button!"); button.setmnemonic(keyevent.vk_i); // Skrót klawiszowy dla akcji przycisku button.addactionlistener(new ActionListener() { // Rejestracja obsługi // zdarzenia i blok inicjalizacji instancji klasy anonimowej public void actionperformed(actionevent e) { // Metoda obsługi zdarzenia numclicks++; label.settext(labelprefix + numclicks); ); label.setlabelfor(button); // Ustawia komponent, dla którego przeznaczona jest // ta etykieta. W. Kasprzak: Programowanie zdarzeniowe 9-18

/* Zawartość kontenera będzie dodana do obiektu klasy JPanel:*/ JPanel pane = new JPanel(); pane.setborder(borderfactory.createemptyborder( // Definicja brzegu. 30, // góra 30, // lewa strona 10, // dół 30) // prawa strona ); pane.setlayout(new GridLayout(1, 2)); // Nowy menadŝer układu. pane.add(button); pane.add(label); return pane; public static void main(string[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); catch (Exception e) { W. Kasprzak: Programowanie zdarzeniowe 9-19 // Utwórz obiekt głównego kontenera i dodaj komponenty: JFrame frame = new JFrame("SwingApplication"); SwingApplication app = new SwingApplication(); Component contents = app.createcomponents(); frame.getcontentpane().add(contents, BorderLayout.CENTER); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.pack(); frame.setvisible(true); Uwagi do powyŝszego programu: (1) Program SwingApplication korzysta z 4 komponentów Swing-a: kontenera głównego ramki (JFrame) - czyli głównego okna GUI; kontenera pośredniego panelu (JPanel) ; kontrolki - przycisku (JButton) ; komponentu - etykiety (JLabel). JPanel jako pośredni kontener upraszcza pozycjonowanie komponentów takich jak przycisk i etykieta. Inne waŝne pośrednie kontenery to: W. Kasprzak: Programowanie zdarzeniowe 9-20

panel z moŝliwością przewijania (JScrollPane) i panel z zakładkami (JTabbedPane). Program moŝe generować okno o postaci zaleŝnej od systemu - programista moŝe wybrać postać okna: wygląd charakterystyczny dla Java, CDE/Motif, Windows, lub inny. Java CDE/Motif Windows public static void main(string[] args) { try { UIManager.setLookAndFeel( // Ustawia wygląd okna UIManager.getCrossPlatformLookAndFeelClassName()); // Podaje klasę implementującą dekoracje typowe dla środowiska Java. catch (Exception e) {... // Utwórz i wizualizuj GUI. W. Kasprzak: Programowanie zdarzeniowe 9-21 (2) Utworzenie przycisku i etykiety. Np. inicjalizacja przycisku: JButton button = new JButton("I'm a Swing button!"); // Utwórz obiekt button.setmnemonic('i'); // Ustaw klawisz "i" jako skrót akcji. button.addactionlistener(... obiekt nasłuchujący...); // Rejestruj obsługę Np. inicjalizacja etykiety:...// W miejscu deklaracji zmiennych: private static String labelprefix = "Number of button clicks: "; private int numclicks = 0;...// W kodzie inicjalizacji dla GUI: final JLabel label = new JLabel(labelPrefix + "0 ");... label.setlabelfor(button); // Etykieta jest przeznaczona dla przycisku...// W procedurze obsługi zdarzenia "kliknięcia" przycisku: label.settext(labelprefix + numclicks); // Zmiana tekstu etykiety W. Kasprzak: Programowanie zdarzeniowe 9-22

3) Listy opcji Istnieje abstrakcyjna klasa public abstract class AbstractButton extends JComponent implements ItemSelectable, SwingConstants Ta klasa opisuje wspólne cechy dla klas JButton i JMenuItem. Po tych klasach dziedziczą: klasy pól wyboru JCheckBox i przycisków radiowych JRadioButton; klasy opcji "menu" (JCheckBoxMenuItem, JMenu, JRadioButtonMenuItem). Pola wyboru (check box) są zbliŝone funkcjonalnie do przycisków radiowych (radio button), ale inny jest ich tryb wyboru z grupy takich W. Kasprzak: Programowanie zdarzeniowe 9-23 samych elementów - z grupy pól wyboru moŝna wybrać dowolną ich liczbę naraz, ale z grupy przycisków radiowych - tylko jeden przycisk. Inna kontrolka wyboru opcji to lista wysuwnych opcji (JComboBox). (4) Brzegi panelu Wokół komponentów panelu istnieje pusty obszar - "brzeg" utworzony metodą setborder: pane.setborder(borderfactory.createemptyborder( 30, // rozmiar brzegu u góry wyraŝony w pikselach 30, // na lewo 10, // u dołu 30) // na prawo ); W. Kasprzak: Programowanie zdarzeniowe 9-24

5) Panel zawartości ( content pane ) KaŜdy kontener główny posiada jeden ukryty kontener pomocniczy "content pane". Za wyjątkiem paska menu panel zawartości zawiera wszystkie wizualne komponenty głównego okna. Do dołączania komponentów do kontenera słuŝą róŝne wersje metody add(). Np. frame = new JFrame(...); button = new JButton(...); label = new JLabel(...); pane = new JPanel(); pane.add(button); pane.add(label); frame.getcontentpane().add(pane, BorderLayout.CENTER); W. Kasprzak: Programowanie zdarzeniowe 9-25 3) Obsługa zdarzeń Typowe zdarzenia w systemie to przyciśnięcie klawisza klawiatury lub przycisku myszy. KaŜdy obiekt moŝe zostać powiadomiony o zdarzeniu - wystarczy, jeśli implementuje właściwy interfejs i jest zarejestrowany jako "listener" dla odpowiedniego źródła zdarzeń. Obsługa zdarzeń wymaga trzech fragmentów kodu. a. Definicja klasy obsługującej zdarzenia jest to klasa implementująca właściwy interfejs XXXListener lub dziedzicząca po klasie, która implementuje taki interfejs; np. public class MojaKlasa implements ActionListener { b. Rejestracja obiektu tej klasy dla obsługi zdarzenia jednego lub więcej komponentów; np. komponent.addactionlistener(obiektklasy); c. Definicja metod interfejsu w treści klasy obsługującej zdarzenie. Np. public void actionperformed(actionevent e) {...// właściwy kod obsługi zdarzenia W. Kasprzak: Programowanie zdarzeniowe 9-26

Uwaga: często klasa obsługi zdarzenia definiowana jest jako anonimowa klasa wewnętrzna. W klasie SwingApplication są dwa rodzaje obsługi zdarzeń: dla zamykania okna ("WindowListener"), dla przycisku ("ActionListener"). button.addactionlistener(...); - rejestracja obsługi zdarzenia dla button. Np. button.addactionlistener(new ActionListener() { public void actionperformed(actionevent e) { numclicks++; label.settext(labelprefix + numclicks); ); Zdarzenie typu "Action" dla przycisku spowoduje wywołanie metody actionperformed (jedynej metody deklarowanej w interfejsie ActionListener) o jednym argumencie, obiekcie klasy ActionEvent, podającym informację o zdarzeniu i jego źródłowym obiekcie. W. Kasprzak: Programowanie zdarzeniowe 9-27 Przykłady zdarzeń zgłaszanych przez komponenty Swing: Zjawisko powodujące zdarzenie UŜytkownik wybiera i "klika" na przycisk, wybiera "Return" pisząc w polu tekstowym, lub wybiera element menu. UŜytkownik zamyka główne okno. UŜytkownik "klika" myszą, gdy kursor znajduje się nad komponentem. UŜytkownik przesuwa kursor myszą nad komponentem. Komponent staje się widoczny. Komponent uzyskuje kontekst klawiatury. Zmiany opcji na wykazie lub liście. Typ obsługi zdarzenia ActionListener WindowListener MouseListener MouseMotionListener ComponentListener FocusListener ListSelectionListener Obsługa zdarzeń aplikacji realizowana jest w jednym wątku. W. Kasprzak: Programowanie zdarzeniowe 9-28

4) Pole tekstowe, tekst w HTML i ikonki Klasa JTextField pole tekstowe Utworzenie obiektu typu pole tekstowe, np.: JTextField tempcelsius = null; tempcelsius = new JTextField(5); Parametr konstruktora podaje liczbę kolumn pola tekstowego, co wraz z miarą dla aktualnej czcionki wyznacza szerokość pola. Przykład 9.3. Program CelsiusConverter: uŝytkownik wprowadza wartość temperatury wyraŝoną w stopniach Celsjusza, wybiera przycisk "Convert" a komponent - "etykieta" podaje równowaŝną wartość w stopniach Fahrenheita. import java.awt.*; import java.awt.event.*; W. Kasprzak: Programowanie zdarzeniowe 9-29 import javax.swing.*; // Klasa zawiera komponenty typu JButton, JTextField, JLabel. public class CelsiusConverter implements ActionListener { JFrame converterframe; // Identyfikator ramki JPanel converterpanel; // Identyfikator panelu JTextField tempcelsius; // Identyfikator pola teksowego JLabel celsiuslabel, fahrenheitlabel; // Dwa identyfkatory etykiet JButton converttemp; // Identyfikator przycisku // Konstruktor : public CelsiusConverter() { // Utwórz okno główne i panel converterframe = new JFrame("Convert Celsius to Fahrenheit"); converterpanel = new JPanel(); converterpanel.setlayout(new GridLayout(2, 2)); addwidgets(); // Dołącz komponenty - metoda programisty // Dołącz panel to okna. converterframe.getcontentpane().add ( converterpanel, BorderLayout.CENTER); W. Kasprzak: Programowanie zdarzeniowe 9-30

// Zakończ program, gdy okno zostanie zamknięte. converterframe.setdefaultcloseoperation(jframe.exit_on_close); // Realizacja i pierwsza wizualizacja ramki z komponentami: converterframe.pack(); converterframe.setvisible(true); // Koniec konstruktora // Metoda dla tworzenia i dołączania komponentów: private void addwidgets() { tempcelsius = new JTextField(2); celsiuslabel = new JLabel("Celsius", SwingConstants.LEFT); converttemp = new JButton("Convert..."); fahrenheitlabel = new JLabel("Fahrenheit", SwingConstants.LEFT); // Rejestruj obiekt dla obsługi zdarzeń dla przycisku Convert : converttemp.addactionlistener(this); // Dołącz komponenty do panelu: converterpanel.add(tempcelsius); converterpanel.add(celsiuslabel); converterpanel.add(converttemp); W. Kasprzak: Programowanie zdarzeniowe 9-31 converterpanel.add(fahrenheitlabel); celsiuslabel.setborder(borderfactory.createemptyborder(5,5,5,5)); fahrenheitlabel.setborder(borderfactory.createemptyborder(5,5,5,5)); // Koniec metody addwidgets() // Implementacja interfejsu ActionListener: public void actionperformed(actionevent event) { // Pobierz i zamień napis na wartość double oraz przelicz na Fahrenheita: int tempfahr = (int)((double.parsedouble(tempcelsius.gettext())) * 1.8 + 32); fahrenheitlabel.settext(tempfahr + " Fahrenheit"); // Metoda main public static void main(string[] args) { // Ustaw wygląd okna try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); catch(exception e) { W. Kasprzak: Programowanie zdarzeniowe 9-32

// Utwórz obiekt klasy programisty: CelsiusConverter converter = new CelsiusConverter(); Komentarz: Obsługa zdarzeń dla przycisku "convert" zawiera operację pobrania napisu i jego konwersję na liczbę: JButton converttemp;... converttemp.addactionlistener(this);... public void actionperformed(actionevent event) { int tempfahr = (int)((double.parsedouble(tempcelsius.gettext())) * 1.8 + 32); fahrenheitlabel.settext(tempfahr + " Fahrenheit"); W. Kasprzak: Programowanie zdarzeniowe 9-33 Dołączanie tekstu sformatowanego w HTML Tekst przycisków i etykiet moŝe być specyfikowany w języku HTML. Specyfikacja tekstu w HTML dla obiektu typu "etykieta" polega na rozpoczęciu napisu od znacznika <HTML> i podaniu poprawnego kodu w html. Jest to poŝyteczne rozwiązanie wtedy, gdy zmieniamy krój czcionki i kolor lub wprowadzamy łamanie wiersza w polu etykiety. Przykład 9.4. Poprzedni program 9.3 po zmianach uwzględniających tekst w HTML: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CelsiusConverter2 implements ActionListener { JFrame converterframe; W. Kasprzak: Programowanie zdarzeniowe 9-34

JPanel converterpanel; JTextField tempcelsius; JLabel celsiuslabel, fahrenheitlabel; JButton converttemp; public CelsiusConverter2() { converterframe = new JFrame("Convert Celsius to Fahrenheit"); converterpanel = new JPanel(); converterpanel.setlayout(new GridLayout(2, 2)); addwidgets(); converterframe.getcontentpane().add(converterpanel, BorderLayout.CENTER); converterframe.setdefaultcloseoperation(jframe.exit_on_close); converterframe.pack(); converterframe.setvisible(true); private void addwidgets() { ImageIcon icon = new ImageIcon("img/convert.gif", "Convert temperature"); tempcelsius = new JTextField(2); W. Kasprzak: Programowanie zdarzeniowe 9-35 celsiuslabel = new JLabel("Celsius", SwingConstants.LEFT); converttemp = new JButton(icon); fahrenheitlabel = new JLabel("Fahrenheit", SwingConstants.LEFT); celsiuslabel.setborder(borderfactory.createemptyborder(5,5,5,5)); fahrenheitlabel.setborder(borderfactory.createemptyborder(5,5,5,5)); converttemp.addactionlistener(this); converterpanel.add(tempcelsius); converterpanel.add(celsiuslabel); converterpanel.add(converttemp); converterpanel.add(fahrenheitlabel); public void actionperformed(actionevent event) { int tempfahr = (int)((double.parsedouble(tempcelsius.gettext())) * 1.8 + 32); // HTML: kolor czcionki zaleŝy teraz od wartości temperatury: if (tempfahr <= 32) { fahrenheitlabel.settext("<html><font Color=blue>" + tempfahr + "&#176 </Font><Font Color=black> Fahrenheit</font></html>"); W. Kasprzak: Programowanie zdarzeniowe 9-36

else if (tempfahr <= 80) { fahrenheitlabel.settext("<html><font Color=green>" + tempfahr + "&#176 </Font><Font Color=black> Fahrenheit </Font></html>"); else { fahrenheitlabel.settext("<html><font Color=red>" + tempfahr + "&#176 </Font><Font Color=black> Fahrenheit</Font></html>"); public static void main(string[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); catch(exception e) { CelsiusConverter2 converter = new CelsiusConverter2(); Wyświetlanie symbolu temperatury umoŝliwia kod w html-u: &#176. Metoda setfont umoŝliwia ustawienie czcionki dla całego komponentu. W. Kasprzak: Programowanie zdarzeniowe 9-37 Dołączanie ikon "Ikona" to obraz o ustalonym rozmiarze. Obiekt typu "ikona" odwołuje się do interfejsu Icon. Implementacja tego interfejsu w Swingu to np.: ImageIcon - rysuje obraz zadany w formacie GIF lub JPEG. Np. ImageIcon icon = new ImageIcon("img/convert.gif", // Nazwa pliku obrazka "Convert temperature");... converttemp = new JButton(icon); // PrzekaŜ ikonę konstruktorowi etykiety W. Kasprzak: Programowanie zdarzeniowe 9-38

5) Wiele paneli, listy opcji, obrazy Przykład 9.5. Program LunarPhases : uŝytkownik wybiera fazę księŝyca z listy, a odpowiedni obraz pojawia się w obszarze dolnego panelu. import java.awt.*; import java.awt.event.*; import javax.swing.*; W. Kasprzak: Programowanie zdarzeniowe 9-39 import java.net.url; public class LunarPhases implements ActionListener { final static int NUM_IMAGES = 8; final static int START_INDEX = 3; ImageIcon[] images = new ImageIcon[NUM_IMAGES]; JPanel mainpanel, selectpanel, displaypanel; // Ident. trzech paneli JComboBox phasechoices = null; // Dla listy wysuwnych opcji JLabel phaseiconlabel = null; public LunarPhases() { // Konstruktor utworzy 3 panele. selectpanel = new JPanel(); // Najpierw utworzymy 2 pod-panele displaypanel = new JPanel(); addwidgets(); // Dołączenie komponentów do paneli // Główny panel będzie zawierać 2 pod-panele mainpanel = new JPanel(); mainpanel.setlayout(new GridLayout(2,1,5,5)); mainpanel.setborder(borderfactory.createemptyborder(5,5,5,5)); // Dołącz pod-panele. W. Kasprzak: Programowanie zdarzeniowe 9-40

mainpanel.add(selectpanel); mainpanel.add(displaypanel); // Koniec konstruktora // Metoda tworzenia komponentów dla listy opcji i prezentacji faz księŝyca. private void addwidgets() { for (int i = 0; i < NUM_IMAGES; i++) { String imagename = "images/image" + i + ".jpg"; System.out.println("getting image: " + imagename); // Pobierz obraz URL iconurl = ClassLoader.getSystemResource(imageName); ImageIcon icon = new ImageIcon(iconURL); images[i] = icon; // Utwórz obiekt typu "etykieta" dla wyświetlania obrazów phaseiconlabel = new JLabel(); phaseiconlabel.sethorizontalalignment(jlabel.center); phaseiconlabel.setverticalalignment(jlabel.center); phaseiconlabel.setverticaltextposition(jlabel.center); phaseiconlabel.sethorizontaltextposition(jlabel.center); W. Kasprzak: Programowanie zdarzeniowe 9-41 phaseiconlabel.setborder(borderfactory.createcompoundborder( BorderFactory.createLoweredBevelBorder(), BorderFactory.createEmptyBorder(5,5,5,5))); phaseiconlabel.setborder(borderfactory.createcompoundborder( BorderFactory.createEmptyBorder(0,0,10,0), phaseiconlabel.getborder())); // Utwórz wysuwaną listę opcji - faz księŝyca String[] phases = { "New", "Waxing Crescent", "First Quarter", "Waxing Gibbous", "Full", "Waning Gibbous", "Third Quarter", "Waning Crescent" ; phasechoices = new JComboBox(phases); phasechoices.setselectedindex(start_index); // Wyświetl pierwszy obraz. phaseiconlabel.seticon(images[start_index]); phaseiconlabel.settext(""); // Dodaj obramowanie panelu wyboru selectpanel.setborder(borderfactory.createcompoundborder( BorderFactory.createTitledBorder("Select Phase"), BorderFactory.createEmptyBorder(5,5,5,5))); W. Kasprzak: Programowanie zdarzeniowe 9-42

// Dodaj obramowanie panelu wyświetlania displaypanel.setborder(borderfactory.createcompoundborder( BorderFactory.createTitledBorder("Display Phase"), BorderFactory.createEmptyBorder(5,5,5,5))); // Dodaj listę opcji do panelu wyboru i etykietę z obrazem do 2-go panelu selectpanel.add(phasechoices); displaypanel.add(phaseiconlabel); // Zarejestruj swoją obsługę zdarzeń dla listy opcji: phasechoices.addactionlistener(this); // Implementacja obsługi zdarzeń public void actionperformed(actionevent event) { if ("comboboxchanged".equals(event.getactioncommand())) { // Zmodyfikuj ikonę - odpowiednio do aktualnego wyboru phaseiconlabel.seticon(images[phasechoices.getselectedindex()]); public static void main(string[] args) { // Metoda main W. Kasprzak: Programowanie zdarzeniowe 9-43 LunarPhases phases = new LunarPhases(); // Nowy obiekt głównej klasy JFrame lunarphasesframe = new JFrame("Lunar Phases"); // Utwórz okno try { // Ustaw wygląd okna: UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); catch(exception e) { // Ustaw kontener: lunarphasesframe.setcontentpane(phases.mainpanel); // Zakończ po zamknięciu okna lunarphasesframe.setdefaultcloseoperation(jframe.exit_on_close); // Realizacja i wizualizacja ramki lunarphasesframe.pack(); lunarphasesframe.setvisible(true); Uwagi do programu (1) Panele w głównym oknie W. Kasprzak: Programowanie zdarzeniowe 9-44

Trzy panele programu LunarPhases rozmieszczono następująco: Wszystkie 3 panele tworzone są w konstruktorze klasy LunarPhases a następnie dwa z nich (selectpanel, displaypanel) dołączane są do trzeciego (mainpanel). mainpanel = new JPanel(); mainpanel.setlayout(new GridLayout(2,1,5,5)); mainpanel.setborder(borderfactory.createemptyborder(5,5,5,5)); mainpanel.add(selectpanel); mainpanel.add(displaypanel); Za właściwy rozmiar i rozmieszczenie dołączanych komponentów w głównym panelu odpowiada menadŝer rozkładu. Domniemanym zarządcą dla JPanel jest FlowLayout - rozmieszczanie od lewej do prawej. W. Kasprzak: Programowanie zdarzeniowe 9-45 (2) ZłoŜony brzeg W omawianym przykładzie oba panele (selectpanel i displaypanel) posiadają złoŝone brzegi, które składają się z zewnętrznego brzegu z tytułem i wewnętrznego brzegu "pustego". Np. dodanie brzegu dla selectpanel : selectpanel.setborder(borderfactory.createcompoundborder( BorderFactory.createTitledBorder("Select Phase"), BorderFactory.createEmptyBorder(5,5,5,5))); Podobny kod wystąpi dla ustawienia brzegu panelu displaypanel. W. Kasprzak: Programowanie zdarzeniowe 9-46

(3) Lista wysuwanych opcji Wysuwalna lista opcji jest domyślnie nieedytowalną listą. Nieedytowalna lista wysuwana wygląda początkowo jak przycisk.. Po jej wybraniu wyświetlona zostaje lista wykluczających się opcji.. Np. utworzenie i ustawienie wysuwanej listy opcji - phasechoices: phasechoices = new JComboBox(phases); phasechoices.setselectedindex(start_index); // Początkowy napis W powyŝszym kodzie następuje inicjalizacja obiektu tablicą napisów. Inne sposoby inicjalizacji - przekazanie ikonek lub wektora danych. W. Kasprzak: Programowanie zdarzeniowe 9-47 (4) Obsługa zdarzeń dla wysuwanej listy opcji Wysuwalna lista opcji zgłasza zdarzenie typu akcji ("Action") po wybraniu przez uŝytkownika jednej z jej opcji. Przykład kodu obsługi takiego zdarzenia: phasechoices.addactionlistener(this);... public void actionperformed(actionevent event) { if ("comboboxchanged".equals(event.getactioncommand())) { // Zmień ikonę w celu wyświetlenia wybranej fazy księŝyca phaseiconlabel.seticon(images[phasechoices.getselectedindex()]); Kod obsługi - pobierz indeks wybranej opcji, zamień go na nazwę obrazu i zmodyfikuj etykietę dla wyświetlenia właściwej ikony. (5) Wiele obrazów W programie LunarPhases obiekt typu "etykieta" wykorzystuje 8 obrazów, ale tylko jeden z nich jest widoczny w danej chwili. Mamy wybór W. Kasprzak: Programowanie zdarzeniowe 9-48

pomiędzy wcześniejszym załadowaniem wszystkich obrazów a ładowaniem pojedynczego obrazu w razie jego wybrania. Np. wszystkie obrazy ładowane są na raz z chwilą tworzenia obiektu. final static int NUM_IMAGES = 8; final static int START_INDEX = 3; ImageIcon[] images = new ImageIcon[NUM_IMAGES];... private void addwidgets() { // W metodzie addwidgets: // pobierz obrazy i umieść je w tablicy ikonek typu ImageIcon. for (int i = 0; i < NUM_IMAGES; i++) { String imagename = "images/image" + i + ".jpg"; URL iconurl = ClassLoader.getSystemResource(imageName); ImageIcon icon = new ImageIcon(iconURL); images[i] = icon; Wykorzystano tu metodę getsystemresource w klasie ClassLoader która poszukuje plików na domyślnej ścieŝce klas. W. Kasprzak: Programowanie zdarzeniowe 9-49 6) Przyciski radiowe JRadioButton. Okna dialogowe JOptionPane. Przykład 9.6. Program VoteDialog ilustruje tworzenie dialogu z uŝytkownikiem i korzystanie z przycisków radiowych. UŜytkownik wybiera właściwy przycisk radiowy i potwierdza swój wybór przyciskiem "głosowania". Pojawia się potwierdzenie w postaci okna dialogowego, które moŝe teŝ być kontynuacją zapytań. import javax.swing.*; import java.awt.*; W. Kasprzak: Programowanie zdarzeniowe 9-50

import java.awt.event.*; public class VoteDialog extends JPanel { JLabel label; JFrame frame; String simpledialogdesc = "The candidates"; public VoteDialog(JFrame frame) { // Konstruktor klasy głównej this.frame = frame; JLabel title; // Utwórz komponenty JPanel choicepanel = createsimpledialogbox(); // Metoda własna title = new JLabel("Click the \"Vote\" button" + " once you have selected a candidate.", JLabel.CENTER); label = new JLabel("Vote now!", JLabel.CENTER); label.setborder(borderfactory.createemptyborder(10,10,10,10)); choicepanel.setborder(borderfactory.createemptyborder(20,20,5,20)); // Ustal rozkład komponentów. W. Kasprzak: Programowanie zdarzeniowe 9-51 setlayout(new BorderLayout()); add(title, BorderLayout.NORTH); add(label, BorderLayout.SOUTH); add(choicepanel, BorderLayout.CENTER); // Koniec konstruktora void setlabel(string newtext) { label.settext(newtext); // PoniŜsza metoda tworzy okno dialogowe private JPanel createsimpledialogbox() { final int numbuttons = 4; JRadioButton[] radiobuttons = new JRadioButton[numButtons]; final ButtonGroup group = new ButtonGroup(); // Grupa przycisków JButton votebutton = null; final String defaultmessagecommand = "default"; final String yesnocommand = "yesno"; final String yeahnahcommand = "yeahnah"; final String ynccommand = "ync"; W. Kasprzak: Programowanie zdarzeniowe 9-52