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
ą
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
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
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
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).
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.
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
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.
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
.
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.
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:
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
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
);
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
}
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
w
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
ą
c
w
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.
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);
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) {}
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;
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 + "°
</Font><Font Color=black> Fahrenheit</font></html>");
9. Swing - wprowadzenie
W. Kasprzak: Programowanie zdarzeniowe
9 - 37
} else if (tempFahr <= 80) {
fahrenheitLabel.setText("<html><Font Color=green>" + tempFahr + "°
</Font><Font Color=black> Fahrenheit </Font></html>");
} else {
fahrenheitLabel.setText("<html><Font Color=red>" + tempFahr + "°
</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:
°.
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
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.
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)));
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
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
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.
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
.
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
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.*;
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";
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 {
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.");
}
}
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);
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);
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.
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
ą
d
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]);
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,
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);
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>"
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
.