java
/gui
1
Graficzny interfejs u ytkownika (GUI):
AWT
•
Abstract Windowing Toolkit: pakiet klas java.awt.* definiuj cy
proste komponenty graficzne
•
mały i prosty w u yciu, ale ubogie mo liwo ci graficzne i
interakcyjne
•
od pocz tku w rdzeniu klas Javy
•
brak niektórych potrzebnych komponentów np. tabel
•
zale ny od platformy wygl d komponentów
•
dysponuje prostszym komponentem reprezentuj cym ramk ; w ramce
umieszcza si bezpo rednio inne komponenty
Swing
•
pakiet javax.swing.* projektu JFC (Java Foundation Classes) –
pocz tkowo dodatek do klas rdzennych, w Javie 2 ju w składzie
klas rdzennych
•
profesjonalny i w pełni funkcjonalny pakiet narz dziowy do
grafiki – wi ksze mo liwo ci ni AWT i wi cej komponentów
•
AWT stanowi wewn trzn podstaw Swinga
Reguły pracy z komponentami GUI:
•
komponent ma właciwo ci (reprezentowane zazwyczaj przez obiekty
klas Font, Color, itp.), które mo na ustala (metody setXXX(…))
pobiera (metody getXXX(…)), lub sprawdza (metody isXXX(…))
•
kontener
o komponent, który mo e zawiera inne komponenty
o mo e zawiera komponenty lub kontenery
o jedn z wła ciwo ci kontenera jest rozkład – z ka dym
kontenerem jest zwi zany zarz dca rozkładu (jest to obiekt
odpowiedniej klasy)
•
okno
o (jedno lub wiele) słu y do komunikacji u ytkownika z
programem
o jest kontenerem najwy szego poziomu w hierarchii zawierania
si komponentów
o okno AWT jest kontenerem
o okno Swingu zawiera kontener contentPane
import javax.swing.*;
import java.awt.*;
class Przyklad {
public static void main(String[] args) {
Icon[] icon = { new ImageIcon("ocean.jpg"),// ikony z plików JPEG
new ImageIcon("pool.jpg"),
java
/gui
2
new ImageIcon("town.jpg") };
String[] opis = {"Ocean","Pool","Town"}; // tekst na przyciskach
JFrame f = new JFrame(); // utworzenie okna ramowego
Container cp = f.getContentPane(); // i pobranie jego contentPane
cp.setLayout(new FlowLayout()); // ustalenie rozkładu FlowLayout
for (int i=0; i<icon.length; i++){//tworzenie kolejnych przycisków
JButton b = new JButton(opis[i], icon[i]);
b.setFont( new Font("Dialog", Font.BOLD | Font.ITALIC, 18));
// jednoczesne pogrubiene i kursywa
b.setForeground(Color.blue);
// Ustalenie pozycji tekstu na przycisku wzgl dem ikony
b.setVerticalTextPosition(SwingConstants.BOTTOM);
b.setHorizontalTextPosition(SwingConstants.CENTER);
cp.add(b); // dodanie przycisku do contentPane
}
f.pack();// spakowanie okna
// (wymiary okna takie by dokładnie zmie ci komponenty)
f.show(); // pokazanie okna
} }
komponenty ci
kie
•
s realizowane przez u ycie graficznych bibliotek systemu
operacyjnego, zatem zale
od platformy i maj okre lony kształt
•
gotowe komponenty AWT s ci
kie
komponenty lekkie
•
mog by prze roczyste, zatem mog przybiera dowolne kształty
•
maj wygl d niezale ny od platformy
•
s rysowane za pomoc kodu Javy w obszarze jakiego komponentu
ci
kiego znajduj cego si wy ej w hierarchii (zwykle w
kontenerze najwy szego poziomu)
•
wszystkie komponenty Swingu (oprócz kontenerów najwy szego
poziomu) s lekkie i mo na wybiera ich wygl d (pluggable look
and feel)
mieszanie komponentów
•
mo liwe jest umieszczenie w jednym kontenerze komponentów
lekkich (np. Swingu) i ci
kich (np. AWT) jednak s restrykcje
na porz dek nakładania si komponentów (Z-order) i nie jest to
zalecane
•
Swing: standardowo powinno si dodawa komponenty do kontenera
contentPane okna ramowego JFrame
java
/gui
3
Hierarchia klas komponentów GUI:
•
java.awt.
Component
o klasa abstrakcyjna
o wspólne wła ciwo ci wszystkich komponentów (AWT, Swingu,
komponentów terminalnych, kontenerów)
o metody do ustalania i pobierania wła ciwo ci dla ka dego z
mo liwych komponentów
•
java.awt.
Container
o wspólne wła ciwo ci i metody dla wszystkich kontenerów
•
javax.swing.
JComponent
o klasa abstrakcyjna
o wspólne wła ciwo ci wszystkich lekkich komponentów Swingu
•
klasy komponentów np.
Button, JMenu, itp.
o specyficzne wła ciwo ci i funkcjonalno
komponentów
okno
Swingu
(b d ce
kontenerem
najwy szego
poziomu) okno
AWT kontener AWT
Container Component
lekki kontener lub okno wewn trzne Swingu
JComponent Container Component
terminalny komponent AWT
Component
AWT
hierarchia klas AWT
Button
Canvas
Checkbox
Dialog
FileDialog
Choice
Window
Frame
Object
Component
Container
Panel
Label
ScrollPane
List
Scrollbar
TextArea
TextComponent
TextField
Button
przycisk
konstruktory:
Button()
Button(String napis)
przycisk z napisem
metody:
getLabel()
pobiera napis z przycisku
setLabel(String txt)
zmienia napis na przycisku
setActionCommand(String)
kojarzy z przyciskiem napis, który mo na pobra
w zdarzeniu klikni cia mysz
java
/gui
4
Label
etykieta z tekstem; tekst mo e by wyrównany
metody:
getText()
pobiera tekst z etykiety
setText(String txt)
ustawia tekst etykiety
pola:
Label.LEFT
Label.RIGHT
Label.CENTER
wyrównanie tekstu
List
lista elementów do wyboru; tryb selekcji
pojedynczej lub wieloselekcji
konstruktory:
List()
tworzy list
List(int n)
inicjalnie lista ma n wierszy
List(int n, boolean b)
je li b==true mo liwa wieloselekcja
metody:
void add(String s)
dodanie s na koniec listy
void add(String s, int i)
dodanie s na pozycji i
int getRaws()
zwraca liczb widocznych wierszy
int getItemCount()
zwraca liczb elementów listy
String[] getItems()
zwraca wszystkie elementy na li cie
String getItem(int i)
zwraca element na pozycji i
String[] getSelectedItems()
zwraca zaznaczone elementy
String getSelectedItem()
zwraca zaznaczony element
int getSelectedIndex()
zwraca pozycje zaznaczonego elementu
int[] getSelectedIndexes()
zwraca pozycje zaznaczonych na li cie
elementów
boolean isIndexSelected(int i)
czy
element
o
indeksie
i
jest
zaznaczony
boolean isMultipleMode()
czy
lista
jest
w
trybie
wielozaznaczania
void select(int i)
zaznacza element o indeksie i
void deselect(int i)
usuwa zaznaczenie elementu o indeksie i
void remove(int i)
usuwa element o indeksie i
void removeAll()
usuwa wszystkie elementy z listy
void setMultipleMode(boolean m)
wł cza lub wył cza wielozaznaczanie
// przykład utworzenia listy i dodawanie elementów
List l=new List();
for (int i=1; i<=10; i++) l.add(„element listy”+i);
Choice
składa si z pola tekstowego z przyciskiem po
java
/gui
5
prawej stronie – po klikni ciu przycisku rozwija
si lista; wybrany z listy element pojawia si w
polu tekstowym; metody s podobne do metod klasy
List, ale mo na zaznaczy tylko jeden element
Checkbox
przycisk-znacznik do zaznaczania opcji; ka de
klikni cie zmienia stan na przeciwny z listy
zaznaczony-niezaznaczony;
stany
przycisków
s
niezale ne
od
siebie;
je li
chcemy
opisywa
wył czaj ce si opcje znaczniki powinny by dodane
do obiektu klasy CheckboxGroup (zaznaczenie z
ptaszka zmieni si na kropeczk )
metody:
void setLabel(String txt)
ustala napis przycisku
void setState(boolean b)
ustala stan (zaznaczony-niezaznaczony)
String getLabel()
pobiera napis przycisku
boolean getState()
pobiera stan przycisku
TextField
jednowierszowe pole edycyjne
konstruktory:
TextField(String txt)
tworzy pole zawieraj ce podany tekst
TextField(int n)
tworzy pole o n koluknach
TextArea
wielowierszowe pole edycyjne
metody:
void append(String txt)
dodaje tekst na ko cu
metody klasy abstrakcyjnej TextComponent dla TextField i TextArea:
int getCarrentPosition()
zwraca pozycj kursora
String getSelectedText()
zwraca zaznaczony tekst
int getSelectionEnd()
zwraca koniec zaznaczenia
int getSelectionStart()
zwraca pocz tek zaznaczenia
String getText()
zwraca cały tekst
boolean isEditable()
czy jest edytowany
void setCurrentPosition(int pos)
ustawia kursor na pozycji pos
void setEditable(boolean b)
ustawia b d wył cza mo liwo
edycji
void setSelectionEnd(int pos)
ustawia pozycj ko ca zaznaczenia
void setSelectionStart(int pos)
ustawia pozycj pocz tku zaznaczenia
void setText(String s)
ustala tekst
int getColumns()
pobiera licz. widocznych kolumn tekstu
void setColumns(int n)
ustala na n liczb widocznych kolumn
java
/gui
6
Swing
•
dostarcza nowych komponentów oraz rozbudowuje mo liwo ci starych
hierarchia klas Swingu:
JMenu
JComboBox
JCheckBoxMenuItem
JMenuBar
JButton
JRadioButtonMenuItem
JAbstractButton
JMenuItem
JLabel
JToggleButton
JRadioButton
JList
JCheckBox
JScrollPane
JScrollbar
JTextField
JPasswordField
JTextComponent
TextArea
JPopupMenu
JEditorPane
JTextPane
rozbudowane
JPanel
nowe
JColorChooser
JFileChooser
JInternalFrame
JLayeredPane
JComponent
JOptionPane
JRootPane
JProgressBar
JSlider
JSeparator
JSplitPane
JTabbedPane
JViewPort
JToolBar
JToolTip
JTable
JTree
JInternalFrame
JDesktopIcon
java
/gui
7
Komponenty terminalne:
Etykieta
JLabel
mo liwo ci:
•
tekst i/lub ikona z dowolnym pozycjonowaniem
•
tekst mo e by w HTML
•
ustalenie mnemoniki i zwi zanie jej z innym komponentem –
wci ni cie ALT+mnemonik powoduje przej cie fokusu do danego
komponentu
Przyciski
JButton, JToggleButton, JCheckBox, JRadioButton
mo liwo ci:
•
tekst i/lub ikona na przycisku z dowolnym pozycjonowaniem
•
tekst mo e by w HTML
•
ró ne ikony dla ró nych stanów (wci ni ty, kursor nad
przyciskiem itp.)
•
symulacja klikni
– metody doClick(), doClick(…)
•
ustalanie mnemoniki (skróty klawiaturowe) – metoda setMnemonic()
Menu rozwijalne
JMenu, JMenuItem, JCheckBoxMenuItem
mo liwo ci:
•
klasy te pochodz od AbstractButton wi c maj mo liwo ci
przycisków
Menu kontekstowe
JPopupMenu
Suwak
JSlider
mo liwo ci:
•
jako etykiety mo e zawiera tekst lub ikony
•
słu y do ustalania warto ci z pewnego podanego zakresu
Dialogi wyboru
JColorChooser, JFileChooser
mo liwo ci:
•
łatwy do u ycia w wersji standardowej
•
w pełni konfigurowalny
Pole edycyjne jednowierszowe
JTextField
JPasswordField
•
weryfikacja tekstu za pomoc dziedziczenia z klasy abstrakcyjnej
InputVerifier i zdefiniowania metody verify()
JFormattedTextField
•
od JDK 1.4
•
wbudowana weryfikacja tekstu
java
/gui
8
Pole edycyjne wielowierszowe
JTextArea
JEditorPane, JTextPane
•
procesory dokumentów, do tworzenia edytorów
Lista
JList
•
elementy: tekst i/lub ikony i inne komponenty GUI
•
ró ne elementy listy mog mie ró ny wygl d (kolor, pismo,
obrazek)
Lista rozwijalna
JComboBox
•
te same, co lista
•
dodatkowo przechodzenie do elementu tekstowego po wci ni ciu
pierwszej litery napisu, który on reprezentuje
Tabela
JTable
•
du e mo liwo ci konfiguracyjne
•
przestawianie kolumn programistycznie lub interaktywnie mysz
•
ró ny wygl d kolumny (tekst, ikona, komponenty iteracyjne)
•
sortowanie wierszy
•
wielozaznaczanie po wierszach lub kolumnach
Drzewo
JTree
•
graficzne przedstawienie hierarchii
•
w zły drzewa maj te same własno ci, co elementy tabeli tzn.
mog by reprezentowane w postaci napisów, ikon itp.
Panel
JPanel
•
do grupowania komponentów
JSplitPane
•
panel dzielony: podział kontenera na dwie cz
ci z przesuwaniem
belki podziału (poziomo lub pionowo)
JTabbedPane
mo liwo ci:
•
panel zakładkowy: zakładki do wybierania komponentów, które maj
by widoczne na panelu
JScrollPane
•
panel przewijany: do pokazywania za pomoc suwaków komponentów,
które nie mieszcz si w polu widoku
Pasek narz dzi
JToolBar
java
/gui
9
ZMIANA KOMPONENTÓW
//przykład zmiany wygl du przycisku
import javax.swing.*;
import java.awt.*;
class MyButton extends JButton {
public MyButton(String txt) { super(txt); }
public void paintComponent(Graphics g) {
super.paintComponent(g); //aby zagwarantowa podstawowy wygl d
int w = getWidth(); //i funkcjonalno
int h = getHeight();
g.setColor(Color.red);
g.fillRect(0, 0, 10, 10);
g.fillRect(w-10, 0, 10, 10);
g.fillRect(0, h-10, 10, 10);
g.fillRect(w-10, h-10, 10, 10); }
}
class MyButtonTest extends JFrame {
Container cp = getContentPane();
public MyButtonTest() {
MyButton mb = new MyButton("To jest przycisk");
cp.add(mb);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
show(); }
public static void main(String args[]) {new MyButtonTest();}
}
•
aby zagwarantowa odpowiedni wygl d i funkcjonalno
gotowych
komponentów, w paintComponent() musimy na pocz tku wywoła
paintComponent() z nadklasy
•
„minimalne” klasy dla projektu własnego komponentu:
o komponenty terminalne
ci
kie AWT – class MojKomponent extends
Canvas {…}
lekkie AWT –
Component (np. Button,…)
lekkie Swingu –
Jcomponent (np. JButton,…)
o komponenty-kontenery
ci
kie AWT –
Panel
lekkie AWT –
Container
lekkie Swingu –
Jpanel
•
przy budowie od podstaw wa ne jest nie tylko przedefiniowanie
paint() [paintComponent()], ale równie metod okre laj cych
minimalne, maksymalne i preferowane rozmiary komponentów –
inaczej nasze komponenty mog by niewidoczne; klasy „minimalne”
Canvas, JComponent daj komponenty o zerowych rozmiarach
java
/gui
10
//komponent budowany od podstaw
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class ObszarRysunku extends JComponent {
Dimension d;
public ObszarRysunku(int w, int h) {d = new Dimension(w, h);}
public Dimension getMinimumSize() { return d; }
public Dimension getPreferredSize() { return d; }
public Dimension getMaximumSize() { return new Dimension(1000,
1000); }
public void paintComponent(Graphics g) {
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
g.setColor(Color.blue);
g.drawRect(0,0,w-1,h-1);
int hor = 10, vert = 10;
while (hor < h) {
g.drawLine(1, hor, w-1, hor);
hor += 10;
}
while (vert < w) {
g.drawLine(vert, 1 , vert, h-1);
vert += 10;
}
}
}
class Rysunek extends JFrame {
Container cp = getContentPane();
public Rysunek() {
ObszarRysunku or = new ObszarRysunku(100, 100);
cp.add(or);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
show();
}
public static void main(String args[]) {
new Rysunek();
}
}
java
/gui
11
dobry kod: w ramce s umieszczone panele i dopiero w nich s
komponenty
class javax.swing.Jframe
•
s w niej dost pne dwa panele: głównym pojemnikiem jest
ContentPane (u ywa si go jako głównego pojemnika ramki – jego
nale y wywoła najpierw),
GlassPane ma prze roczyste tło i jest
umieszczony „ponad” – słu y do chwilowego wy wietlania
informacji „ponad” ContentPane
// wy wietlane okno jest b. małe (MS-Windows)
// lub b. du e(X-Windows), a zmiany wielko ci prowadz do zaj cia
// całego obszaru przez przycisk – nie ma tu mened era układu
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JFrameDemo extends JFrame {
boolean unsavedChanges = false;
JButton quitButton;
public JFrameDemo() {
super("JFrameDemo");
getContentPane().add(quitButton = new JButton("Koniec"));
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
System.exit(0); } }
);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
dispose();
System.exit(0); } });
pack(); // skaluje okno do komponentów
}
public static void main(String[] args) { new
JFrameDemo().setVisible(true); }
}
java
/gui
12
UKŁAD OKNA
•
mened er układu to obiekt, który na
danie pojemnika okre la
rozmieszczenie umieszczonych w nim komponentów
•
LayoutManager jest (z powodów historycznych) interfejsem, a nie
klas
•
w AWT jest pi
mened erów układu, w Swingu s dodatkowe
wyspecjalizowane
Nazwa
Uwagi
U ywane domy lnie w
FlowLayout
rozmieszcza komponenty wzdłu linii
(J)Panel, (J)Applet
BorderLayout
dzieli obszar pojemnika na pi
„geografi-
cznych” regionów; brak okre lenia regionu
dla komponentu oznacza, e zostanie
umieszczony w Center – je li b dzie ich
tam kilka to wida ostatni
(J)Frame, (J)Window
GridLayout
regularna siatka, wszystkie elementy maj
t sam wielko
-
CardLayout
wy wietla w danej chwili tylko jeden z
komponentów, przydatny przy tworzeniu
„kreatorów”
-
GridBagLayout b. elastyczny, ale b. zło ony
-
•
ka dy komponent powinien udost pnia własn wersj metody
getPreferredSize() – jest on u ywany przez mened ery układu do
okre lania jak i gdzie rozmie ci poszczególne komponenty
•
pack() – robi wielko
ramki jako minimaln potrzebn do
zmieszczenia wszystkich komponentów panelu
•
setSize() – t metod nale y wywoła , je li nie skorzystano z
pack() – okre li wymiary okna na podstawie podanych wymiarów,
b d obiektu Dimension
// u ycie układu FlowLayout
import java.awt.*;
import javax.swing.*;
public class JFrameFlowLayout extends JFrame {
public JFrameFlowLayout() {
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(new JLabel("Wspaniale?"));
cp.add(new JButton("O tak!"));
pack();
}
public static void main(String[] args) {
new JFrameFlowLayout().setVisible(true); }
}
java
/gui
13
ZAKŁADKI
•
class
javax.swing.JTabbedPane jest poł czeniem pojemnika i
mened era układu
•
przy obiekcie powy szej klasy nie trzeba stosowa
setLayout()
import javax.swing.*;
public class TabPaneDemo {
protected JTabbedPane tabPane;
public TabPaneDemo() {
tabPane = new JTabbedPane();
tabPane.add(new JLabel("Jeden", JLabel.CENTER),
"Pierwszy");
tabPane.add(new JLabel("Dwa", JLabel.CENTER), "Drugi"); }
public static void main(String[] a) {
JFrame f = new JFrame("Demonstracja zakładek");
f.getContentPane().add(new TabPaneDemo().tabPane);
f.setSize(150, 100);
f.setVisible(true); }
}
OBSŁUGA ZDARZE
•
ActionListener to odbiorca zdarze z przycisków, pól tekstowych,
itp.
// 1. samodzielnie za pomoc interfejsu ActionListener
// – dobre rozwi zanie dla małych programów
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonDemo2a extends Applet implements
ActionListener {
Button b1, b2;
public void init() {
add(b1 = new Button("Przycisk"));
b1.addActionListener(this);
add(b2 = new Button("Drugi przycisk"));
b2.addActionListener(this); }
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) showStatus("klikni cie pierwszego
przycisku!");
else showStatus("klikni cie drugiego przycisku!"); }
}
java
/gui
14
// 2. wykorzystuj c członkowsk klas wewn trzn
// – w ten sposób robi c nie poprawiamy jednak czytelno ci kodu,
// ani nie zmniejszamy nakładu pracy
public class ButtonDemo2b extends Applet {
Button b1, b2;
ActionListener handler = new ButtonHandler();
public void init() {
add(b1 = new Button("Przycisk"));
b1.addActionListener(handler);
add(b2 = new Button("Drugi przycisk"));
b2.addActionListener(handler); }
class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) showStatus("klikni cie pierwszego
przycisku!");
else showStatus("klikni cie drugiego przycisku!"); }
}
}
// 3. wykorzystuj c anonimow klas wewn trzn (w tym samym
// miejscu podawana jest definicja klasy i tworzony jest obiekt
// – przy podaniu nazwy klasy tworzona jest jej klasa potomna,
// w razie podania nazwy interfejsu tworzona
// jest anonimowa klasa potomna klasy java.lang.Object
// implementuj ca ten interfejs; nazwy klas anonimowych s
// nadawane przez kompilator)
// zaleta: kod obsługuj cy czynno
w tym samym miejscu, co
// utworzony komponent graficzny – nie trzeba przegl da całego
// kodu
public class ButtonDemo2c extends Applet {
Button b;
public void init() {
add(b = new Button("Oto przycisk"));
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus("klikni cie pierwszego przycisku!"); }
}
);
add(b = new Button("Kolejny przycisk"));
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus("klikni cie drugiego przycisku!"); }
}
);
}
}
java
/gui
15
ZAMYKANIE OKNA
•
okna główne (klasy potomne java.awt.Window, samo Window jest
potomkiem Component): (J)Frame oraz (J)Dialog nie s pocz tkowo
widoczne poniewa trzeba rozmie ci zawarto
w oknie i okre li
rozmiary, a u ytkownik nie powinien widzie jak poszczególne
komponenty s wy wietlane
•
interfejs
WindowListener obsługuje zdarzenia zwi zane z oknami –
wszystkie metody musz by zaimplemenetowane nawet je li
niektóre miałyby mie puste ciało
•
klasa
WindowAdapter pozwala na impelemntacji tylko potrzebnych
nam metod obsługi, a nie wszystkich
import java.awt.*;
import java.awt.event.*;
public class WindowDemo extends Frame {
public static void main(String[] argv) {
Frame f = new WindowDemo();
f.setVisible(true); }
public WindowDemo() {
setSize(200, 100);
addWindowListener(new WindowDemoAdapter()); }
// nazwana klasa wewn trzna zamykaj ca okno
class WindowDemoAdapter extends WindowAdapter {
public void windowClosing(WindowEvent e) {
// losowe zamykanie, z prawdopodobie stwem, mniej
wi cej, 1 do 3.
if (Math.random() > 0.666) {
System.out.println(" egnam!");
WindowDemo.this.setVisible(false);
// zamkni cie okna
WindowDemo.this.dispose();
// zwolnienie zasobów
// przy czym samo okno nie jest niszczone i pó niejsze
// wywołanie pack() lub setVisible() przywraca zasoby;
// nie stosowa je li okno ma by powtórnie otwarte
System.exit(0); }
System.out.println("okno nie wyraziło zgody na zamkni cie");
}
}
}
java
/gui
16
•
klasa
javax.swing.JFrame udost pnia metod
setDefaultCloseOperation(), która okre la domy lne zachowanie
okna – w jej wywołaniu mo na przekaza jedn z poni szych
warto ci zdefiniowanych w klasie WindowConstants:
WindowConstants.DO_NOTHING_ON_CLOSE
dania zamkni cia okna zostan
zignorowane
WindowConstants.HIDE_ON_CLOSE
okno zostanie ukryte (działanie domy lne)
WindowConstants.DISPOSE_ON_CLOSE
okno zostanie ukryte a jego zasoby
zwolnione
WindowConstants.EXIT_ON_CLOSE
(od JDK 1.3) zamkni cie okna i całej
aplikacji – nie trzeba stosowa interfejs
WindowListener
•
setDefaultCloseOperation() jest wykonywana po zako czeniu
ostatniej metody actionPerformed()
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class WindowDemo2 extends JFrame {
public static void main(String[] argv) {
JFrame f = new WindowDemo2();
f.setVisible(true); }
public WindowDemo2() {
setSize(200, 100);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
}
OKNA DIALOGOWE
class javax.swing.JoptionPane
•
udostepnia grup metod
show…Dialog() do wy wietlania
predefiniowanych okien dialogowych
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JOptionDemo extends JFrame {
JOptionDemo(String s) {
java
/gui
17
super(s);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
JButton b = new JButton("Podaj wiadomo
");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(
JOptionDemo.this,
// odwołanie do nadrz dnego obiektu (J)Frame, dla którego ma
// by wy wietlone okno dialogowe (je li nie znane mo na poda
// null, ale nie ma gwarancji, e po zamkni ciu okna
// dialogowego miejsce b dzie poprawnie przekazane)
"Oto wiadomo
: etaoin shrdlu", // tre
komunikatu
"Wiadomo
zakodowana", // ła cuch wy wietlany na pasku
JOptionPane.INFORMATION_MESSAGE);
// info któr z predefiniowanych bitmap trzeba wy wietli
}
});
cp.add(b);
b = new JButton("Do zobaczenia!");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { System.exit(0); }
});
cp.add(b);
// główne okno programu
setSize(200, 150);
pack();
}
public static void main(String[] arg) {
JOptionDemo x = new JOptionDemo("Testujemy 1 2 3...");
x.setVisible(true);
}
}
•
inny sposób wykorzystania klasy JOptionPane: wywoła
showDialog() przekazuj c do niej list ła cuchów – ka dy z nich
zostanie umieszczony na osobnym przycisku w oknie dialogowym;
program przerywa działanie do momentu klikni cia jednego z
przycisków – wtedy showDialog() zwraca indeks w tablicy
ła cuchów okre laj cy który przycisk został klikni ty
•
showInputDialog() okno dialogowe do wpisywania danych
•
klasa JDialog pozwala na tworzenie dowolnie zło onych okien
dialogowych: mo na otwiera (jak w przypadku JFrame) okna
modalne (blokuj dost p do pozostałych elementów aplikacji) lub
niemodalne (nie blokuj )
java
/gui
18
WYBIERANIE PLIKÓW
class javax.swing.JfileChooser
•
klasy potomne klasy FileFilter kontrola nad plikami
wy wietlanymi w oknie (class
javax.swing.filechooser.FileFilter,
lub jako interfejs w java.io.* jednak jest to jego starsza
wersja)
•
boolean accept(File), String getDescription() z FileFilter
wystarczaj do stworzenia filtru pliku
•
ka dy obiekt klasy FileFilter przekazany jako argument wywołania
metody addChoosableFileFilter() klasy JFileChooser staje si
opcj rozwijanej listy „Pliki typu” – domy lnie na tej li cie
jest opcja „Wszystkie pliki (*.*)”
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class JFileChooserDemo extends JPanel {
public JFileChooserDemo(JFrame f) {
final JFrame frame = f;
final JFileChooser chooser = new JFileChooser();
// aby u ytkownik mógł wybiera wył cznie katalogi, nale y usun
komentarz
// z poni szego wiersza. Domy lnie okno dialogowe pozwala
wył cznie na
// wybieranie plików
// przy DIRECTORIES_ONLY, w oknie dialogowym nie b d wy wietlane
adne pliki,
// nawet je li b dzie ono pracowa w widoku plików
//
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
JFileFilter filter = new JFileFilter();
filter.addType("java");
filter.addType("class");
filter.addType("jar");
filter.setDescription("Pliki Javy");
chooser.addChoosableFileFilter(filter);
JButton b = new JButton("Wybierz plik...");
add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int returnVal = chooser.showOpenDialog(frame);
if (returnVal == JFileChooser.APPROVE_OPTION) {
java
/gui
19
File file = chooser.getSelectedFile();
System.out.println("Wybrałe " + (file.isFile() ? "plik" :
"katalog") +
" o nazwie: " + file.getPath()); }
else { System.out.println("Nie został wybrany aden
obiekt."); }
}
});
}
public static void main(String[] args) {
JFrame f = new JFrame("Demo klasy JFileChooser");
f.getContentPane().add(new JFileChooserDemo(f));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
// filtr na rozszerzenia plików
class JFileFilter extends javax.swing.filechooser.FileFilter {
protected String description;
protected ArrayList exts = new ArrayList();
public void addType(String s) { exts.add(s); }
public boolean accept(File f) {
// Mała sztuczka: je li nie zostanie zastosowana, to
// w oknie dialogowym pojawi si wył cznie nazwy
// katalogów zako czone jednym z podanych rozszerze .
if (f.isDirectory()) {
return true; }
else if (f.isFile()) {
Iterator it = exts.iterator();
while (it.hasNext()) {
if (f.getName().endsWith((String)it.next()))
return true;
}
}
// Plik który nie pasuje, lub jakie dziwactwo (np. plik
// sterownika w systemie UNIX)
return false;
}
// okre la opis danego filtra
public void setDescription(String s) { description = s; }
// zwraca opis filtra
public String getDescription() { return description; }
}
java
/gui
20
WYBIERANIE KOLORU
•
w AWT jest oryginalnie 13 predefiniowanych kolorów
•
class javax.swing.JColorChooser pozwala na wybór jednego z
milionów kolorów
•
sposoby u ycia JColorChooser:
o utworzy obiekt tej klasy i umie ci go w panelu
o wywoła metod ConstructDialog() i uzyska obiekt JDialog
o wywoła metod showDialog() i uzyska kolor wybrany przez
u ytkownika
(najpro ciej)
•
trzeci sposób ma nast puj ce tryby wyboru koloru:
o Swatches: wybór jednego spo ród kilkuset predefiniowanych
kolorów
o HSB: Hue – odcie , Saturation – nasycenie, Brightnes –
jasno
, wybór jednego a reszta suwakiem
o RGB: wybór suwakiem
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JColorDemo extends JFrame {
JLabel demo;
Color lastChosen;
public JColorDemo() {
super("Wybieranie kolorów (Swing)");
Container cp = getContentPane();
JButton jButton;
cp.add(BorderLayout.NORTH, jButton = new JButton("Zmie
kolor..."));
jButton.setToolTipText("Kliknij aby wy wietli okno Color
Chooser");
jButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent)
{ Color ch = JColorChooser.showDialog(
JColorDemo.this, // element nadrz dny
"Wybieranie kolorów", // tytuł
getBackground()); // domy lnie
System.out.println(ch);
if (ch != null) {
demo.setBackground(ch);
demo.repaint(); }
}
});
cp.add(BorderLayout.CENTER, demo =
new JLabel("Twój jedyny prawdziwy kolor",
JLabel.CENTER));
demo.setToolTipText("Oto ostatni wybrany kolor");
java
/gui
21
// „chmurki z pomoc ”
pack();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
public static void main(String[] argv)
{ new JColorDemo().setVisible(true); }
}
WY WIETLANIE OKNA GŁÓWNEGO W RODKU EKRANU
import java.awt.*;
import javax.swing.*;
public class Centrum2 {
protected JFrame JF; // ramka
protected Container cp; // panel zawarto ci ramki
public Centrum2() {
JF = new JFrame("centrowanie na ekranie");
JF.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
cp = JF.getContentPane();
cp.setLayout(new FlowLayout());
//Button b= new Button("1");
//b.setSize(20,30);
//cp.add(b);
JButton b2= new JButton("2");
//b2.setSize(50,60);
cp.add(b2);
//b2.setSelected(true);
JButton b3= new JButton("3");
//b3.setSize(20,60);
cp.add(b3);
//b3.setSelected(true);
//JF.setSize(300,600);
JF.pack();
//JF.setLocation(200,300);
UtilGUI.centre(JF);
JF.setVisible(true);
}
java
/gui
22
public static void main (String [] args) {new Centrum2();}
}
class UtilGUI {
// centrujemy obietky Window, Frame, JFrame, Dialog, itp.
public static void centre(Window w) {
// Po "spakowaniu" komponentów umieszczonych w pojemnikach
// Frame lub Dialog wy wietlamy je na rodku ekranu
Dimension us = w.getSize(),
them = Toolkit.getDefaultToolkit().getScreenSize();
// klasa Toolkit jest zwi zana z zarz dzaniem oknami
// w danym systemie operacyjnym – ka da klasa potomna Toolkit
// jest przeznaczona do innego OS’a
int newX = (them.width - us.width) / 2;
int newY = (them.height- us.height)/ 2;
w.setLocation(newX, newY); }
// centrujemy, ale przy u yciu metody zgodnej ze słownictwem
// ameryka skim :-)
public static void center(Window w) {
UtilGUI.centre(w); }
// maksymalizacja okna, w brutalny sposób
public static void maximize(Window w) {
Dimension us = w.getSize(),
them = Toolkit.getDefaultToolkit().getScreenSize();
w.setBounds(0,0, them.width, them.height); }
}
ZMIANA INTERFEJSU U YTKOWNIKA
•
UIManager.setLookAndFeel() okre la sposób prezentacji programu,
pobiera pełn nazw klasy implementuj cej sposób prezentacji
interfejsu np.
UIManager.setLookAndFeel(„javax.swing.plaf.metal.MetalLookAndFee
l”); - metoda ta musi by wywołana przed stworzeniem graficznego
interfejsu u ytkownika
•
SwingUtilities.updateComponentTree() – zmienia sposób
prezentacji obiektu JFrame i wszystkich innych komponentów
java
/gui
23
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.metal.*;
public class LNFSwitcher {
protected JFrame theFrame; //ramka
protected Container cp; // panel zawarto ci ramki
final static String PREFERREDLOOKANDFEELNAME =
"javax.swing.plaf.metal.MetalLookAndFeel";
protected String curLF = PREFERREDLOOKANDFEELNAME;
protected JRadioButton previousButton;
public LNFSwitcher() { // tworzymy program
super();
theFrame = new JFrame("LNF Switcher");
// theFrame.addWindowListener(new WindowCloser(theFrame, true));
theFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE
);
cp = theFrame.getContentPane();
cp.setLayout(new FlowLayout());
ButtonGroup bg = new ButtonGroup();
JRadioButton bJava = new JRadioButton("Java");
bJava.addActionListener(new LNFSetter(
"javax.swing.plaf.metal.MetalLookAndFeel", bJava));
bg.add(bJava);
cp.add(bJava);
JRadioButton bMSW = new JRadioButton("MS-Windows");
bMSW.addActionListener(new LNFSetter(
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel", bMSW));
bg.add(bMSW);
cp.add(bMSW);
JRadioButton bMotif = new JRadioButton("Motif");
bMotif.addActionListener(new LNFSetter(
"com.sun.java.swing.plaf.motif.MotifLookAndFeel", bMotif));
bg.add(bMotif);
cp.add(bMotif);
JRadioButton bMac = new JRadioButton("MacOS");
bMac.addActionListener(new LNFSetter(
"com.sun.java.swing.plaf.mac.MacLookAndFeel", bMac));
bg.add(bMac);
cp.add(bMac);
java
/gui
24
JRadioButton bOL = new JRadioButton("OPEN LOOK");
// inny hipotetyczny
bOL.addActionListener(new LNFSetter( // sposób prezentacji
"com.darwinsys.openlook.OpenLookAndFeel", bOL));
bOL.setEnabled(false);
bg.add(bOL);
cp.add(bOL);
// domy lnie jest stosowany sposób prezentacji Javy
previousButton = bJava;
bJava.setSelected(true);
theFrame.pack();
theFrame.setVisible(true);
}
// klasa okre laj ca sposób prezentacji ramki
class LNFSetter implements ActionListener {
String theLNFName;
JRadioButton thisButton;
// wywoływana w celu okre lenia sposobu obsługi przycisków
LNFSetter(String lnfName, JRadioButton me) {
theLNFName = lnfName;
thisButton = me; }
// wywoływana gdy przycisk zostanie klikni ty
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(theLNFName);
SwingUtilities.updateComponentTreeUI(theFrame); }
catch (Exception evt) {
JOptionPane.showMessageDialog(null,
"Bł d metody setLookAndFeel: " + evt, "Bł d graficznego interfejsu
u ytkownika", JOptionPane.INFORMATION_MESSAGE);
previousButton.setSelected(true); }
// przywracamy wcze niejszy stan GUI
previousButton = thisButton;
}
}
public static void main(String[] argv) {
new LNFSwitcher(); }
}
java
/gui
25
GRAFIKA I D WI K
class java.awt.Graphics
•
pozwala na rysowanie konturów i wypełnionych figur, wy wietlanie
tekstów, ustawianie kolorów i fontów: drawString(), setColor(),
getColor(), setFont(), getFont(), drawLine(), drawOval(),
fillRect(), …
•
w pierwszej kolejno ci nale y rysowa elementy, które maj by
pod spodem, a potem te na wierzchu
•
nie mo na nic narysowa w oknie zanim okno to nie zostanie
utworzone (i skojarzone z ekranem) zatem nie powinno si
wywoływa
getGraphics() oraz metod rysuj cych obiekt Graphics
bezpo rednio w programie głównym b d w konstruktorze obiektu
klasy rozszerzaj cej klas Component – poprawnym sposobem jest
umieszczenie kodu rysuj cego wewn trz metody
paint() komponentu
(AWT)
•
paint() nie powinna wywoływa tej samej metody w klasie bazowej
•
nie nale y miesza rysowania z wykorzystaniem komponentów GUI
(np. zdefiniowanie paint() i dodanie add() przycisku mo e nie
działa w niektórych implementacjach, tzn. jeden z nich mo e by
tylko widoczny) trzeba wykorzysta kilka ró nych komponentów
lub wykorzysta metody getContentPane(), getGlassPane()
class javax.swing.*
•
w Swingu jest metoda paint() jednak ze wzgl du na obsług
kraw dzi i inne rzeczy zalecane jest przesłanianie jej przez
paintComponent()
•
paintComponent() powinna si zaczyna od super.paintComponent()
i przekazania w jej wywołaniu równie super.paintComponent() – w
ten sposób wszystkie komponenty b d wy wietlone w odpowiedniej
kolejno ci zaczynaj c od tych na samym spodzie a ko cz c na tych
z góry
// klasa narz dziowa pobiera nazw klasy „graficznej”
// (o konstruktorze bezargumentowym) z linii, tworzy obiekt tej
// klasy i umieszcza go w ramce JFrame wraz z przyciskiem koniec
// zapewnia, e okno jest odpowiednio du e
// wywołanie: java CompTest DrawStringDemo2
// tak e dla klas wbudowanych np. java CompTest javax.swing.JTree
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
java
/gui
26
public class CompTest {
public static void main(String[] av) {
if (av.length == 0) {
System.err.println("Usage: CompTest ComponentSubclass");
System.exit(1); }
String name = av[0];
Component c = null;
try { Class cf = Class.forName(name);
Object o = cf.newInstance();
if (!(o instanceof Component)) {
System.err.println("ERROR: Class " + name +” is not a subclass of
Component");
System.exit(1); }
c = (Component)o;
}
catch (Exception e) { System.err.println("Component under test
got exception in construction or initialization");
System.err.println(e.toString());
System.exit(1); }
// create a Frame, and "Component c" to it.
final JFrame f = new JFrame("CompTest: " + av[0]);
Container cp = f.getContentPane();
cp.add(BorderLayout.CENTER, c);
JButton quitButton;
cp.add(BorderLayout.SOUTH, quitButton = new JButton("Exit"));
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.setVisible(false);
f.dispose();
System.exit(0); }});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension d = c.getPreferredSize();
if (d.width == 0 || d.height == 0) {
f.setSize(300, 200); }
else { f.pack(); }
f.setLocation(200, 200);
f.setVisible(true);
}
}
//1. przykład komponentu z awt
import java.awt.*;
public class PaintDemo extends Component {
java
/gui
27
int X = 20, Y = 30;
int Width = 50, Height = 50;
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(X, Y, Width, Height); }
public Dimension getPreferredSize() { return new Dimension(100,
100); }
}
//2. przykład komponentu ze swinga
// wy wietla wy rodkowany tekst w komponencie
import java.awt.*;
import javax.swing.*;
public class DrawStringDemo2 extends JComponent {
String message = "Hello Java";
public void paint(Graphics g) {
// Pobieramy bie
c czcionk oraz jej metryki
(FontMetrics).
FontMetrics fm = getFontMetrics(getFont());
// Dysponuj c metrykami czcionki okre lamy szeroko
ła cucha
// znaków. Odejmujemy j od szeroko ci komponentu, dzielimy
// wynik przez 2 i w ten sposób wyznaczamy współrz dne punktu
// w którym nale y wy wietli tekst
int textX = (getSize().width - fm.stringWidth(message))/2;
if (textX<0) // je li ła cuch zbyt du y zaczynamy
textX = 0; // w punkcie 0
// to samo co wy ej lecz dla wysoko ci ła cucha znaków
int textY = (getSize().height - fm.getAscent())/2 -
fm.getDescent();
if (textY < 0)
textY = getSize().height - fm.getDescent() - 1;
// a teraz wy wietlamy tekst w wyznaczonym punkcie
g.drawString(message, textX, textY);
}
public Dimension getPreferredSize() { return new Dimension(100,
100); }
}