background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 1 

 

9. Swing – wprowadzenie 

 

9.1 Komponenty 

9.2 Przykłady tworzenia GUI 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 2 

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

ą

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 3 

 

Kontenery główne

 

    JApplet      

 

  JDialog 

 

   JFrame

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 4 

Kontenery ogólne po

ś

redniego poziomu 

 

  JPanel                

    JScrollPane 

 

 JSplitPane   

 JTabbedPane 

 

   JToolBar 

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 5 

Kontenery specjalne po

ś

redniego poziomu

 

 

 Internal frame    

 Layered pane 

 
 

 Root pane 

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 6 

Podstawowe kontrolki

 

 

 JButton            

   JComboBox 

 

  JList       

  JMenu 

 

  JSlider                       

  JSpinner 

 

 

JTextField lub JFormattedTextField

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 7 

Nieedytowalne komponenty informacyjne 

 

   JLabel  

 

 JProgressBar 

 

   JToolTip 

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 8 

Interaktywne komponenty z edytowaln

ą

 sformatowan

ą

 informacj

ą

 

 

 JColorChooser   

 JFileChooser 

 

  JTable                  

   JText 

 

 JTree 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 9 

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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 10 

 

 

 

 

 

 

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). 
 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 11 

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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 12 

// 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. 

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 13 

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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 14 

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 

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. 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 15 

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  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 16 

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

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 17 

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.*; 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 18 

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.  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 19 

        /* 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) {} 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 20 

       // 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:  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 21 



 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.  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 22 

(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 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 23 

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 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 24 

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 

                                ); 
 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 25 

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); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 26 

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  

}  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 27 

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 

interfejsie 

ActionListener

)  o  jednym  argumencie,  obiekcie  klasy 

ActionEvent

podaj

ą

cym informacj

ę

 o zdarzeniu i jego 

ź

ródłowym obiekcie. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 28 

 

Przykłady zdarze

ń

 zgłaszanych przez komponenty 

Swing

 

Zjawisko powoduj

ą

ce zdarzenie 

Typ obsługi zdarzenia 

U

Ŝ

ytkownik  wybiera  i  "klika"  na  przycisk, 

wybiera 

"Return" 

pisz

ą

polu 

tekstowym, lub wybiera element menu.  

ActionListener 

U

Ŝ

ytkownik zamyka główne okno.  

WindowListener 

U

Ŝ

ytkownik  "klika"  mysz

ą

,  gdy  kursor 

znajduje si

ę

 nad komponentem.  

MouseListener 

U

Ŝ

ytkownik  przesuwa  kursor  mysz

ą

  nad 

komponentem.  

MouseMotionListener 

Komponent staje si

ę

 widoczny.  

ComponentListener 

Komponent uzyskuje kontekst klawiatury. 

FocusListener 

Zmiany opcji na wykazie lub li

ś

cie.  

ListSelectionListener 

 

Obsługa zdarze

ń

 aplikacji realizowana jest w jednym w

ą

tku.  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 29 

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.*; 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 30 

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); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 31 

 

// 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); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 32 

 

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) {} 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 33 

// 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"); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 34 

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; 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 35 

    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); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 36 

 

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>"); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 37 

 

} 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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 38 

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 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 39 

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.*; 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 40 

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. 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 41 

 

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); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 42 

 

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))); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 43 

     

// 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 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 44 

 

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 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 45 

 
Trzy  panele  programu 

LunarPhases

 

rozmieszczono nast

ę

puj

ą

co: 

 

Wszystkie  3  panele  tworzone  s

ą

  w  konstruktorze  klasy 

LunarPhases 

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. 
 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 46 

(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

.  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 47 

(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.  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 48 

(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 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 49 

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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 50 

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.*; 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 51 

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. 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 52 

        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"; 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 53 

        radioButtons[0] = new JRadioButton("<html>Candidate 1:  

<font color=red>Sparky the Dog</font></html>"); 

        radioButtons[0].setActionCommand(defaultMessageCommand); 
        radioButtons[1] = new JRadioButton("<html>Candidate 2:  

<font color=green>Shady Sadie</font></html>"); 

        radioButtons[1].setActionCommand(yesNoCommand); 
        radioButtons[2] = new JRadioButton("<html>Candidate 3:  

<font color=blue>R.I.P. McDaniels</font></html>"); 

        radioButtons[2].setActionCommand(yeahNahCommand); 
        radioButtons[3] = new JRadioButton("<html>Candidate 4:  

<font color=maroon>Duke the Java<font size=-2> <sup>TM</sup></font 
size> Platform Mascot</font></html>"); 

        radioButtons[3].setActionCommand(yncCommand); 
        for (int i = 0; i < numButtons; i++) { 

// Dodaj przyciski radiowe do grupy  

            group.add(radioButtons[i]); 
        } 

        // Wybierz domy

ś

lnie pierwszy przycisk. 

        radioButtons[0].setSelected(true); 
        voteButton = new JButton("Vote"); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 54 

     // Definiuje i rejestruje obsług

ę

 zdarzenia dla przycisku potwierdzenia 

       voteButton.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e) { 
                String command = group.getSelection().getActionCommand(); 

            // Dialog typu ok  

                if (command == defaultMessageCommand) { 
                    JOptionPane.showMessageDialog(frame, 
                                "This candidate is a dog. Invalid vote."); 

            // Dialog yes/no  

                } else if (command == yesNoCommand) { 
                    int n = JOptionPane.showConfirmDialog(frame,  
          "This candidate is a convicted felon. \nDo you still want to vote for her?", 
                            "A Follow-up Question", 
                            JOptionPane.YES_NO_OPTION); 
                    if (n == JOptionPane.YES_OPTION) { 
                        setLabel("OK. Keep an eye on your wallet."); 
                    } else if (n == JOptionPane.NO_OPTION) { 
                        setLabel("Whew! Good choice."); 
                    } else { 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 55 

                        setLabel("It is your civic duty to cast your vote."); 
                    } 

           // Dialog yes/no (ze słowami u

Ŝ

ytkownika) 

                } else if (command == yeahNahCommand) { 
                    Object[] options = {"Yes, please", "No, thanks"}; 
                    int n = JOptionPane.showOptionDialog(frame, 
                    "This candidate is deceased. \nDo you still want to vote for him?", 
                                    "A Follow-up Question", 
                                    JOptionPane.YES_NO_OPTION, 
                                    JOptionPane.QUESTION_MESSAGE, 
                                    null, options, options[0]); 
                    if (n == JOptionPane.YES_OPTION) { 
                        setLabel("I hope you don't expect much from your candidate."); 
                    } else if (n == JOptionPane.NO_OPTION) { 
                        setLabel("Whew! Good choice."); 
                    } else { 
                        setLabel("It is your civic duty to cast your vote."); 
                    } 

                // Dialog typu yes/no/cancel (ze słowami u

Ŝ

ytkownika) 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 56 

                } else if (command == yncCommand) { 
                    Object[] options = {"Yes!", "No, I'll pass", "Well, if I must"}; 
                    int n = JOptionPane.showOptionDialog(frame, 
                                    "Duke is a cartoon mascot. \nDo you  " 
                                    + "still want to cast your vote?", 
                                    "A Follow-up Question", 
                                    JOptionPane.YES_NO_CANCEL_OPTION, 
                                    JOptionPane.QUESTION_MESSAGE, 
                                    null, options, options[2]); 
                    if (n == JOptionPane.YES_OPTION) { 
                        setLabel("Excellent choice."); 
                    } else if (n == JOptionPane.NO_OPTION) { 
                        setLabel("Whatever you say. It's your vote."); 
                    } else if (n == JOptionPane.CANCEL_OPTION) { 
                        setLabel("Well, I'm certainly not going to make you vote."); 
                    } else { 
                        setLabel("It is your civic duty to cast your vote."); 
                    } 
                } 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 57 

                return; 
            } 
        });  

       

// Koniec definicji obsługi zdarzenia dla przycisku wyboru

 

      // Wywołanie metody prywatnej 

createPane() 

        System.out.println("calling createPane"); 
        return createPane(simpleDialogDesc + ":",  radioButtons,  voteButton);  
    }  

   // Koniec metody

 createSimpleDialogBox() 

   // Definicja metody prywatnej

 createPane() 

    private JPanel createPane(String description, JRadioButton[] radioButtons, 
                                              JButton showButton) { 
        int numChoices = radioButtons.length; 
        JPanel box = new JPanel(); 
        JLabel label = new JLabel(description); 
        box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS)); 
        box.add(label); 
        for (int i = 0; i < numChoices; i++) { 
            box.add(radioButtons[i]); 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 58 

        } 
        JPanel pane = new JPanel(); 
        pane.setLayout(new BorderLayout()); 
        pane.add(box, BorderLayout.NORTH); 
        pane.add(showButton, BorderLayout.SOUTH); 
        System.out.println("returning pane"); 
        return pane; 
    } 

   // Koniec definicji prywatnej metody 

   // Metoda 

main

 klasy głównej 

    public static void main(String[] args) { 
        JFrame frame = new JFrame("VoteDialog"); 
        Container contentPane = frame.getContentPane(); 
        contentPane.setLayout(new GridLayout(1,1)); 
        contentPane.add(new VoteDialog(frame)); 

     // Zako

ń

czy

ć

 program, gdy okno zostaje zamkni

ę

te  

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

     // Realizacja i wizualizacja głównego okna  

        frame.pack(); 
        frame.setVisible(true); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 59 

    } 

  

// Koniec metody

 main 

}  

// Koniec definicji klasy głównej

 

 

Komentarz do programu 

(1) Przyciski radiowe 
Grupa  4  przycisków  radiowych  zebrana  jest  w  obiekcie  klasy 

ButtonGroup

, który zapewnia wył

ą

czno

ść

 wyboru jednego przycisku. 

Poni

Ŝ

ej  powtórzono  fragment  programu,  w  którym  tworzony  jest  obiekt 

klasy 

ButtonGroup

 

i dodawane s

ą

 4 przyciski radiowe.  

Metoda 

setActionCommand

  zwi

ą

zuje  specyficzny  dialog  z  ka

Ŝ

dym 

przyciskiem.  
Metoda 

setSelected

 okre

ś

la pocz

ą

tkowo wybrany przycisk radiowy. 

// Utworzenie obiektów 

JRadioButton[] radioButtons = new JRadioButton[numButtons]; 
final ButtonGroup group = new ButtonGroup(); 

// Utworzenie przycisków radiowych i zwi

ą

zanie napisów dialogowych z 

// akcjami dla tych przycisków  

radioButtons[0] = new JRadioButton("<html>Candidate 1:  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 60 

      <font color=red>Sparky the Dog</font></html>"); 
radioButtons[0].setActionCommand(defaultMessageCommand); 
radioButtons[1] = new JRadioButton("<html>Candidate 2:  
      <font color=green>Shady Sadie</font></html>"); 
radioButtons[1].setActionCommand(yesNoCommand); 
radioButtons[2] = new JRadioButton("<html>Candidate 3:  
      <font color=blue>R.I.P. McDaniels</font></html>"); 
radioButtons[2].setActionCommand(yeahNahCommand); 
radioButtons[3] = new JRadioButton("<html>Candidate 4:  
      <font color=maroon>Duke the Java<font size=-2><sup>TM</sup> 
      </font size> Platform Mascot</font></html>"); 
radioButtons[3].setActionCommand(yncCommand); 

// Dodaj przyciski do obiektu "grupa przycisków" 

for (int i = 0; i < numButtons; i++) {  
    group.add(radioButtons[i]); 

// Wybierz pierwszy przycisk jako domy

ś

lny  

radioButtons[0].setSelected(true); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 61 

(2) Okna dialogowe klasy 

JOptionPane 

W  naszych  przykładach  główny  kontener  jest  typu 

JFrame.

  Istnieje  te

Ŝ

 

mo

Ŝ

liwo

ść

  wykorzystania  klasy 

JDialog

  -  umo

Ŝ

liwia  ona  operowanie  na 

oknach o bardziej ograniczonej funkcjonalno

ś

ci ni

Ŝ

 ramki typu 

JFrame

 
Ale  standardowe  okna  dialogowe  s

ą

  obiektami  klasy 

JOptionPane

  -  s

ą

 

one  oknami 

modalnymi,

  tzn.  je

ś

li  okno  dialogowe  jest  widoczne  to 

blokuje ono wprowadzanie danych do pozostałych okien programu.  

 

Np. powy

Ŝ

sze okno powstaje w wyniku wykonania poni

Ŝ

szego kodu: 

JOptionPane.showMessageDialog(frame, "There's no \"there\" there."); 

 
Ka

Ŝ

de 

okno  dialogowe  zale

Ŝ

y  od  istnienia  ramki  typu 

JFrame

  -  je

ś

li 

ramka  jest  usuwana,  równie

Ŝ

  zale

Ŝ

ne  od  niej  okna  dialogowe  s

ą

 

usuwane; je

ś

li ramka jest minimalizowana, to jej okna dialogowe znikaj

ą

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 62 

z  ekranu;  je

ś

li  ramka  jest  przywracana  to  równie

Ŝ

  jej  okna  dialogowe 

powracaj

ą

 na ekran.  

 
(3) Charakterystyka klasy 

JOptionPane

 

 
Metody  i  pola  klasy 

JOptionPane

  umo

Ŝ

liwiaj

ą

  tworzenie  okien 

dialogowych o indywidualnych cechach: 

 standardowe dialogi, 

 ikonki, 

 tytuł okna 

 tekst okna, 

 tekst przycisku 

 rodzaj komponentu dla dialogu, 

 miejsce wyst

ą

pienia dialogu na ekranie. 

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 63 

Ikony 

Mo

Ŝ

na  korzysta

ć

  z  własnych  ikonek, 

Ŝ

adnych  lub  ze  standardowo 

dost

ę

pnych  ikonek  (4  standarodwe  ikonki  w  klasie 

JOptionPane

  dla 

wyra

Ŝ

enia stanów (

zapytanie, informacja, ostrze

Ŝ

enie, bł

ą

d

). Ich wygl

ą

zale

Ŝ

y od 

ś

rodowiska. Np. dla Java "look and feel": 

         

         

         

 

 

Metoda 

showMessageDialog()

 

Metoda  wy

ś

wietla  modalne  okno  dialogowe  o  jednym  przycisku  z 

napisem 

'OK'

 (lub regionalnym równowa

Ŝ

niku). U

Ŝ

ytkownik mo

Ŝ

e poda

ć

 

wy

ś

wietlan

ą

 wiadomo

ść

, ikon

ę

 i tytuł okna. 

 

Np. w programie 

VoteDialog

 skorzystano z tej metody: 

 

// Domy

ś

lny tytuł i ikona 

JOptionPane.showMessageDialog(frame, 
   "This candidate is a dog. " +  
   "Invalid vote.");

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 64 

Metoda

 

showOptionDialog()

 

Metoda wy

ś

wietla modalne okno dialogowe, które mo

Ŝ

e zawiera

ć

 ró

Ŝ

ne 

przyciski o dowolnym tek

ś

cie, ikony, tytuł, komponenty, itd.. 

Przykład skorzystania z metody 

showOptionDialog():  

 

Ob.ject[] options = {"Yes!", "No, I'll pass", "Well, if I must"}; 
int n = JOptionPane.showOptionDialog(frame, 

    "Duke is a cartoon mascot. \n" 
    + "Do you still want to cast your vote?", 
    "A Follow-up Question", 
    JOptionPane.YES_NO_CANCEL_OPTION, 
    JOptionPane.QUESTION_MESSAGE, 

 

 null,      

 

 options,     

 

 options[2]);

 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 65 

Argumenty metod 

showXxxDialog()

 

i konstruktorów

 

JOptionPane



 

Component parentComponent ; 

1-szym  argumentem  metod 

showXxxDialog()

  jest  komponent-przodek, 

którym mo

Ŝ

e by

ć

-  obiekt  typu 

JFrame

  (okno  dialogowe  pojawi  si

ę

  na 

ś

rodku  ramki  i 

b

ę

dzie od niej zale

Ŝ

ne),  

-  komponent  wewn

ą

trz  obiektu 

JFrame

  (okno  dialogowe  pojawi  si

ę

  w 

ś

rodku tego komponentu i b

ę

dzie zale

Ŝ

ne od jego ramki),  

-  lub 

null

 (

ś

rodowisko wybierze pozycj

ę

 okna - zwykle w 

ś

rodku ekranu - 

a okno nie jest zale

Ŝ

ne od 

Ŝ

adnej ramki). 

Konstruktory  klasy 

JOptionPane

  nie  posiadaj

ą

  takiego  argumentu  - 

ramka-przodek podawana jest podczas tworzenia obiektu klasy 

JDialog

który 

zawiera

ć

 

b

ę

dzie 

obiekt 

klasy 

JOptionPane

 

metoda 

setLocationRelativeTo

  w  klasie 

JDialog

  umo

Ŝ

liwia  nadanie  poło

Ŝ

enia 

oknu dialogowemu.  
 



 

Object message ;  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 66 

Ten  argument  okre

ś

la  wiadomo

ść

  wy

ś

wietlan

ą

  przez  okno  w  swojej 

centralnej  cz

ęś

ci.  Zwykle  podaje  si

ę

  napis  co  spowoduje  wy

ś

wietlenie 

etykiety z tym tekstem. 
 



 

String title ;  

 

Argument podaje tytuł okna dialogowego. 
 



 

int optionType ; 

Argument podaje zbiór przycisków, które maj

ą

 si

ę

 pojawi

ć

 na dole okna. 

Mo

Ŝ

na wybra

ć

 jeden z czterech standardowych zbiorów podaj

ą

c: 

DEFAULT_OPTION,  YES_NO_OPTION,  YES_NO_CANCEL_OPTION, 
OK_CANCEL_OPTION.  

 



 

int messageType ; 

Argument  okre

ś

la  typ  standardowej  ikony  wy

ś

wietlanej  w  oknie.  Mo

Ŝ

na 

wybra

ć

 jedn

ą

 z warto

ś

ci: 

PLAIN_MESSAGE (bez ikony),  

ERROR_MESSAGE,  

INFORMATION_MESSAGE,     

WARNING_MESSAGE,  

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 67 

QUESTION_MESSAGE.  

 



 

Icon icon ;

 

 

Argument okre

ś

la ikon

ę

 u

Ŝ

ytkownika wy

ś

wietlan

ą

 w oknie. 

 



 

Object[] options ; 

Opcjonalny  argument  okre

ś

la  napisy,  które  maj

ą

  wyst

ą

pi

ć

  na 

przyciskach okna. Jest to zwykle tablica napisów. 

 



 

Object initialValue ; 

Argument  okre

ś

la  warto

ść

  domy

ś

ln

ą

.  Mo

Ŝ

na  u

Ŝ

y

ć

  domy

ś

lnej  ikony  lub 

jawnie poda

ć

 ikon

ę

 argumentem 

messageType

 lub 

icon

.  

Domy

ś

ln

ą

  warto

ś

ci

ą

  jest  ikona  informacyjna  dla  obiektu  tworzonego 

metod

ą

 

showMessageDialog()

 lub ikona zapytania dla obiektu tworzonego 

metod

ą

 

showConfirmDialog()

.

 

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 68 

(4) Pobieranie danych wej

ś

ciowych od u

Ŝ

ytkownika  

Metody 

showMessageDialog

 i 

showOptionDialog

 przekazuj

ą

 wynik - liczb

ę

 

całkowit

ą

 b

ę

d

ą

c

ą

 kodem wyboru u

Ŝ

ytkownika. Mo

Ŝ

liwe warto

ś

ci to: 

YES_OPTION, 

NO_OPTION, 

CANCEL_OPTION, 

OK_OPTION, 

CLOSED_OPTION.  

Poza 

CLOSED_OPTION

  ka

Ŝ

da  z  tych  warto

ś

ci  odpowiada  przyciskowi 

wybranemu  przez  u

Ŝ

ytkownika.  Jedynie  warto

ść

 

CLOSED_OPTION

 

wskazuje, 

Ŝ

e  u

Ŝ

ytkownik  zamkn

ą

ł  okno  dialogowe  jawnie  bez 

korzystania z przycisków panelu opcji. 

 

Np. poni

Ŝ

szy kod okre

ś

la jaki przycisk został wybrany i ustawia etykiet

ę

 

w ramce na odpowiedni tekst. 

 

} else if (command == yesNoCommand) { 
    int n = JOptionPane.showConfirmDialog ( frame,  
     "This candidate is a convicted felon. \n Do you still want to vote for her?", 
             "A Follow-up Question",    
             JOptionPane.YES_NO_OPTION); 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 69 

    if (n == JOptionPane.YES_OPTION) { 
        setLabel("OK. Keep an eye on your wallet."); 
    } else if (n == JOptionPane.NO_OPTION) { 
              setLabel("Whew! Good choice."); 
              } else {   
                 setLabel("It is your civic duty to cast your vote.");  
                } 
... 

Np. dialog typu 

YES_NO_OPTION

 zawsze zwraca mo

Ŝ

liwe warto

ś

ci:  

YES_OPTION, NO_OPTION, 

lub

 CLOSED_OPTION.  

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 70 

7) Korzystanie z HTML-a w komponentach Swing-a 

Metody  komponentu 

setFont

setForeground

  pozwalaj

ą

  na  ustawienie 

indywidualnej czcionki i koloru tekstów komponentu. 
 

Przykład.

 Utworzenie etykiety i ustawienie jej czcionki i koloru: 

label = new JLabel("A label"); 
label.setFont(new Font("Serif", Font.PLAIN, 14)); 
label.setForeground(new Color(0xffffdd)); 

 
Do  formatowania  tekstu  komponentu  –  u

Ŝ

ycie  ró

Ŝ

nych  kolorów, 

czcionek, wiele wierszy tekstu – mo

Ŝ

na wykorzysta

ć

 j

ę

zyk HTML.  

Przykład 

button = new JButton("<html><b><u>T</u>wo</b><br>lines</html>"); 

 
Przykład 9.7.

 Program 

ButtonHtmlDemo

  

… 
b1 = new JButton("<html><center><b><u>D</u>isable</b><br>" 

background image

9. Swing - wprowadzenie 

W. Kasprzak: Programowanie zdarzeniowe 

9 - 71 

                 + "<font color=#ffffdd>middle button</font>", 
                 leftButtonIcon); 
Font font = b1.getFont().deriveFont(Font.PLAIN); 
b1.setFont(font); 
... 
b2 = new JButton("middle button", middleButtonIcon); 
b2.setFont(font); 
b2.setForeground(new Color(0xffffdd)); 
... 
b3 = new JButton("<html><center><b><u>E</u>nable</b><br>" 
                 + "<font color=#ffffdd>middle button</font>", 
                 rightButtonIcon); 
b3.setFont(font); 

 
Klasy  korzystaj

ą

ce  z  Html: 

JButton,  JLabel,  JMenuItem,  JMenu, 

JRadioButtonMenuItem,  JCheckBoxMenuItem,  JTabbedPane,  JToolTip. 
JToggleButton, JCheckBox, JRadioButton

.