Proz S12 id 402989 Nieznany

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 1

12. Swing - kontenery

12.1

JApplet

12.2

JFrame

12.3

JRootPane

12.4 Panel warstwowy -

JLayeredPane, JDesktopPane

12.5

JInternalFrame

12.6 Kontenery ogólne pośredniego poziomu -

JPanel

i inne:

JScrollPane, JSplitPane, JTabbedPane, JToolBar

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 2

12.1 Klasa

JApplet

Ka

ż

dy aplet zawieraj

ą

cy komponenty

Swing

-a musi by

ć

utworzony jako

klasa pochodna od klasy

JApplet

, która dziedziczy z klasy

java.applet.Applet

.

1) Cechy

JApplet

Jako kontener główny klasa

JApplet

posiada "

root pane

", "

content pane

" i

opcjonalnie

pasek menu

.

ż

nice pomi

ę

dzy apletem w Swing-u a apletem

Applet

:



komponenty dodawane s

ą

do "content pane" apletu;



menad

ż

er układu ustawiany jest dla "content pane" a nie dla apletu

bezpo

ś

rednio;



domy

ś

lnym menad

ż

erem układu dla "content pane" apletu jest

BorderLayout

(dla

Applet

jest nim

FlowLayout

);



kod malowania nie powinien znajdowa

ć

si

ę

bezpo

ś

rednio w obiekcie

klasy

JApplet

.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 3

2) W

ą

tki w apletach

Typowa

konstrukcja

apletów

korzysta

z

w

ą

tków,

tymczasem

komponenty Swing-a nie s

ą

zabezpieczone przed w

ą

tkami.


Komponenty tworzymy i ustawiamy w metodzie

init

- takie rozwi

ą

zanie

uznaje si

ę

za bezpieczne.

Metody

start, stop, destroy

mog

ą

sprawia

ć

kłopoty i nale

ż

y je

zabezpieczy

ć

przed w

ą

tkami. Np. nie powinny by

ć

one wołane z w

ą

tku

rozdziału zdarze

ń

i nie powinny odwoływa

ć

si

ę

do komponentów

bezpo

ś

rednio. Zamiast tego powinny posłu

ż

y

ć

si

ę

one metod

ą

SwingUtilities.invokeLater

przy dost

ę

pie do komponentu.

3) Korzystanie z obrazów w aplecie Swing-a

Klasa

Applet

posiada metod

ę

getImage

dla ładowania obrazów do

apletu. Tworzy ona obiekt klasy

Image

reprezentuj

ą

cy załadowany

obraz. W Swing-u zamiast

Image

stosuje si

ę

klas

ę

Icon

- aplety Swing-a

z zasady nie korzyst

ą

z

getImage

. Zamiast tego aplety Swing-a tworz

ą

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 4

obiekty klasy

ImageIcon

- ikona załadowana z pliku z obrazem. Zalet

ą

stosowania

ImageIcon

jest to,

ż

e klasa automatycznie

ś

ledzi ładowanie

obrazu.

Przykład 12.1.

W

ą

tek apletu implementowany w postaci obiektu pewnej

klasy

SwingWorker

odpowiada za załadowanie 17 ró

ż

nych obrazów

stosuj

ą

c jeden obiekt ImageIcon dla jednego obrazu. Aplet ładuje obrazy

w metodzie

init

.

public void init() {
...
imgs = new ImageIcon[nimgs];
...
final SwingWorker worker = new SwingWorker() {
public Object construct() {

// Indeksy obrazów: od 1 do nimgs, indeksy tablicy - od 0 do nimgs-1.

for (int i = 0; i < nimgs; i++) {
imgs[i] = createFrame(i+1);
}
finishedLoading = true;

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 5

return imgs;
}
...
};
worker.start();
}
protected ImageIcon createFrame(int imageNum) {
String path = dir + "/T" + imageNum + ".gif";
URL imgURL = this.getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
}
else {
System.err.println("Couldn't find file: " + path);
return null;
}
}

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 6

12.2 Klasa

JFrame

(klasa głównego okna)



Typowy obiekt klasy

JFrame

(ramka) posiada okno udekorowane

brzegiem, tytułem, przyciskami dla zamykania, zmniejszania i
powi

ę

kszania okna.



Aplikacje posiadaj

ą

ce GUI korzystaj

ą

z przynajmniej jednej ramki.



Równie

ż

aplety

mog

ą

korzysta

ć

z ramek.



Okna zale

ż

ne od innego okna (okno zanika, gdy inne jest zmniejszane

lud zamykane) mo

ż

na uzyska

ć

stosuj

ą

c

JDialog

zamiast

JFrame

.



Umieszczenie jednego okna w drugim oknie umo

ż

liwia klasa

JInternalFrame

.

1) Reakcje na zdarzenie zamkni

ę

cia okna

Je

ś

li u

ż

ytkownik zamyka okno, zostaje ono ukryte, ale obiekt mo

ż

e

istnie

ć

dalej w programie i okno mo

ż

e zosta

ć

ź

niej przywrócone.


Jest to domy

ś

lna reakcja, która mo

ż

e zosta

ć

zmieniona:

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 7



przez zarejestrowanie procedury obsługi zdarzenia zamkni

ę

cia okna;



przez

specyfikacj

ę

reakcji

na

zamkni

ę

cie

okna

metod

ą

setDefaultCloseOperation

;



lub podanie obu rozwi

ą

za

ń

jednocze

ś

nie – pierwsza wykona sie

obsługa zdarzenia a nast

ę

pnie domy

ś

lna reakcja na zamkni

ę

cie.


Argumentem metody

setDefaultCloseOperation

musi by

ć

jedna z

podanych ni

ż

ej warto

ś

ci (3 pierwsze zdefiniowano w interfejsie

WindowConstants

implementowanym przez

JFrame, JInternalPane,

JDialog

):



DO_NOTHING_ON_CLOSE ,



HIDE_ON_CLOSE

(domy

ś

lne dla

JDialog

i

JFrame

) ,



DISPOSE_ON_CLOSE

(domy

ś

lne dla

JInternalFrame

),



EXIT_ON_CLOSE

(zdefiniowana w

JFrame

) – zako

ń

czy aplikacj

ę

wywołaniem

System.exit(0)

.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 8

2) Reakcja na inne zmiany stanu

Procedury obsługi zdarze

ń

mog

ą

te

ż

reagowa

ć

na zdarzenia zmiany

stanu okna takie, jak zmniejszenie i aktywowanie okna.


Utworzenie i pokazanie ramki

Przykład 12.2

//1. Opcjonalnie: dekoracje ramki zgodne z domy

ś

lnym

ś

rodowiskiem

// "look and feel". Domy

ś

lnie dekoracje dostarczane s

ą

przez system

// zarz

ą

dzaj

ą

cy oknami.

JFrame.setDefaultLookAndFeelDecorated(true);

//2. Utwórz ramk

ę

podaj

ą

c jako argument tytuł ramki.

JFrame frame = new JFrame("FrameDemo");

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 9

//3. Opcjonalnie: co dzieje si

ę

z programem w chwili zamykania ramki –

// ma on si

ę

zako

ń

czy

ć

.

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//4. Utwórz komponenty i dodaj je do ramki.

//...utwórz pustą etykietę ... dodaj ją do panelu zawartości dla ramki

frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);

// Opcjonalnie: umieść na środku ekranu

frame.setLocationRelativeTo(null);

//5. Realizacja ramki - wyznacz rozmiar i układ ramki.

frame.pack();

//6. Poka

ż

ramk

ę

- narysuj j

ą

.

frame.setVisible(true);

Ustawienie dekoracji ramki

Domy

ś

lnie za dekoracje okna odpowiada system nadzoruj

ą

cy okna.

Mo

ż

na zastosowa

ć

te

ż

dekoracje zgodne z domy

ś

lnym „look and feel”.

Mo

ż

liwe s

ą

te

ż

rozwi

ą

zania:

-

bez dekoracji,

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 10

-

z własnymi dekoracjami u

ż

ytkownika,

-

tryb pełnego ekranu.

Mo

ż

liwy jest zawsze powrót do domy

ś

lnych dekoracji systemu okien:

JFrame.setDefaultLookAndFeelDecorated(false).

Przykład 12.3

. Poni

ż

sze 3 ramki posiadaj

ą

ż

ne dekoracje okien.

Korzystaj

ą

one z "Java look and feel" co wida

ć

po postaci przycisku.

Ś

rodkowa ramka korzysta z dekoracji okien dostarczanych przez system

zarz

ą

dzania oknami - w tym przypadku jest nim MS Windows ale mógłby

to by

ć

ka

ż

dy inny system dysponuj

ą

cy platform

ą

Javy.

Dekoracje zgodne z

“look and feel”

Dekoracje zgodne z

systemem okien

Ikona u

ż

ytkownika.

Dekoracje zgodne z

“look and feel”

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 11

Trzecia ramka posiada ikonk

ę

dostarczon

ą

przez u

ż

ytkownika.

// Ustawienie dekoracji okna zgodnych z “look and feel”.

JFrame.setDefaultLookAndFeelDecorated(true);

// Utwórz ramk

ę

.

JFrame frame = new JFrame("A window");

// Ustaw ikonk

ę

w postaci obrazu ładowanego z pliku.

frame.setIconImage(new ImageIcon(imgURL).getImage());

Przykład 12.4

Program

FrameDemo2.java

ilustruje tworzenie ramek o

ż

nych dekoracjach i ikonkach. Opcjonalnie korzysta z pliku:

images/FD.jpg

.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class FrameDemo2 extends WindowAdapter
implements ActionListener {
private Point lastLocation = null;

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 12

private int maxX = 500;
private int maxY = 500;
… //

// Konstruktor:

public FrameDemo2() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
maxX = screenSize.width - 50;
maxY = screenSize.height - 50;
}

// Utwórz i poka

ż

obiekt obiekt klasy MyFrame

public void showNewWindow() {
JFrame frame = new MyFrame();

// Gdy nie są potrzebne dekoracje okna można też użyć Window lub JWindow

if (noDecorations) {
frame.setUndecorated(true);

// Brak dekoracji okna

}

// Ustaw położenie okna:

if (lastLocation != null) {

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 13

// Przesuń okno o 40 pikseli:

lastLocation.translate(40, 40);
if ((lastLocation.x > maxX) || (lastLocation.y > maxY)) {
lastLocation.setLocation(0, 0);
}
frame.setLocation(lastLocation);
}
else { lastLocation = frame.getLocation(); }

// Wywołanie

setIconImage

- ustawia ikonk

ę

wy

ś

wietlan

ą

wtedy, gdy

// okno jest w stanie zminimalizowanym a tak

ż

e ikonk

ę

w dekoracjach

// kontrolowanych przez „look and feel”:

if (specifyIcon) {
if (createIcon) {
frame.setIconImage(createFDImage());

// Nowa ikonka

}
else {
frame.setIconImage(getFDImage());

// Ikonka z pliku

}

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 14

}

// Realizuj i poka

ż

ramk

ę

frame.setSize(new Dimension(170, 100));
frame.setVisible(true);
}

// Utwórz kontrolki dla opcji dekoracji i ikonek głównego okna

protected JComponent createOptionControls() {
JLabel label1 = new JLabel("Opcje dekoracji ramek:");
ButtonGroup bg1 = new ButtonGroup();
JLabel label2 = new JLabel("Icon options:");
ButtonGroup bg2 = new ButtonGroup();

// Utwórz przyciski

JRadioButton rb1 = new JRadioButton();
rb1.setText("Look and feel decorated");
rb1.setActionCommand(LF_DECORATIONS);
rb1.addActionListener(this);
rb1.setSelected(true);
bg1.add(rb1);

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 15

//

JRadioButton rb2 = new JRadioButton();
rb2.setActionCommand(WS_DECORATIONS);

// ...

JRadioButton rb3 = new JRadioButton();
rb3.setActionCommand(NO_DECORATIONS);

// ...

JRadioButton rb4 = new JRadioButton();
rb4.setActionCommand(DEFAULT_ICON);

// ...

JRadioButton rb5 = new JRadioButton();
rb5.setActionCommand(FILE_ICON);

// ...

JRadioButton rb6 = new JRadioButton();
rb6.setActionCommand(PAINT_ICON);
// ...

// Dodaj komponenty do kontenera .

…//

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 16

// Dodaj puste obramowanie

box.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
return box;
}

// Utwórz przycisk widoczny w głównym oknie

protected JComponent createButtonPane() {
JButton button = new JButton("New window");
button.setActionCommand(CREATE_WINDOW);
button.addActionListener(this);
defaultButton = button;

// Domyślny przycisk ramki

// Środkowe położenie przycisku w panelu i obramowanie.

JPanel pane = new JPanel();

// Korzysta z domyślnego FlowLayout

pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
pane.add(button);
return pane;

}

// Obsługa zdarze

ń

typu akcji ze wszystkich przycisków.

public void actionPerformed(ActionEvent e) {

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 17

String command = e.getActionCommand();

// Obsługa przycisku “New window”.

if (CREATE_WINDOW.equals(command)) {
showNewWindow();

// Obsługa 1-szej grupy przycisków radiowych.

} else if (NO_DECORATIONS.equals(command)) {
noDecorations = true;
JFrame.setDefaultLookAndFeelDecorated(false);
} else if (WS_DECORATIONS.equals(command)) {
noDecorations = false;
JFrame.setDefaultLookAndFeelDecorated(false);
} else if (LF_DECORATIONS.equals(command)) {
noDecorations = false;
JFrame.setDefaultLookAndFeelDecorated(true);

// Obsługa 2-giej grupy przycisków radiowych

} else if (DEFAULT_ICON.equals(command)) {
specifyIcon = false;
} else if (FILE_ICON.equals(command)) {

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 18

specifyIcon = true; createIcon = false;
} else if (PAINT_ICON.equals(command)) {
specifyIcon = true; createIcon = true;

}
}

// Utworzenie nowego obrazu

protected static Image createFDImage() {

// Utwórz obraz 16x16 pikseli.

BufferedImage bi = new BufferedImage(16, 16,
BufferedImage.TYPE_INT_RGB);

// Narysuj grafikę w obrazie.

Graphics g = bi.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, 15, 15);
g.setColor(Color.RED);
g.fillOval(5, 3, 6, 6);

// Wyczyść obiekt graficzny.

g.dispose();

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 19

return bi;
}

// Zwraca

Image

lub

null

.

protected static Image getFDImage() {
java.net.URL imgURL =
FrameDemo2.class.getResource("images/FD.jpg");
if (imgURL != null) {
return new ImageIcon(imgURL).getImage();
} else {
return null;

}
}

// Uruchamia program demonstracyjny.

public static void main(String[] args) {

// Korzystaj z “Java look and feel”.

try {
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 20

} catch (Exception e) { }

// Obiekt klasy steruj

ą

cej .

FrameDemo2 demo = new FrameDemo2();

// Zapewnij dekoracje domy

ś

lne

JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);

// Utwórz główne okno (o sterowanych dekoracjach)

JFrame frame = new JFrame("FrameDemo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Dodaj komponenty

Container contentPane = frame.getContentPane();
contentPane.add(demo.createOptionControls(), BorderLayout.CENTER);
contentPane.add(demo.createButtonPane(), BorderLayout.PAGE_END);
frame.getRootPane().setDefaultButton(defaultButton);

// Wyświetl okno demonstracyjne.

frame.pack();
frame.setLocationRelativeTo(null);

// Ulokuj pośrodku

frame.setVisible(true);

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 21

}

// Klasa MyFrame

class MyFrame extends JFrame implements ActionListener {

// Utwórz ramkę z przyciskiem .

public MyFrame() {
super("A window");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);

// Przyciskiem tym mo

ż

emy zamkn

ąć

okno – nawet nieudekorowane

JButton button = new JButton("Close window");
button.addActionListener(this);
Container contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.PAGE_AXIS));
contentPane.add(Box.createVerticalGlue());

// Wypełnia wolne miejsce

contentPane.add(button);
button.setAlignmentX(Component.CENTER_ALIGNMENT);

// Wyśrodkowany w poziomie

contentPane.add(Box.createVerticalStrut(5));

// spacje

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 22

}

// Obsługa zdarzenia dla przycisku realizuje to samo co domyślna operacja
// dla zamknięcia okna – (DISPOSE_ON_CLOSE).

public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();

}
}

// Koniec MyFrame

}

// Koniec FrameDemo2

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 23

12.3

JRootPane

1) Obiekt klasy

JRootPane

tworzony jest wraz z obiektem klasy

JInternalFrame

lub kontenera głównego Swing-a

: JApplet, JDialog,

JFrame.

Obiekt klasy

JRootPane

zawiera cztery dalsze obiekty:



Glass pane” - jest domy

ś

lnie przezroczysty i ukryty.



Layered pane” – rozmieszcza “content pane” i opcjonalny pasek menu

oraz dalsze komponenty w porz

ą

dku odpowiadaj

ą

cym „głebi” – o

ś

Z.



Content pane” –

zawiera wszystkie widoczne komponenty kontenera.



Pasek menu – miejsce dla menu kontenera panelu “root pane”.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 24

Przykład 12.5.

Program

GlassPaneDemo.java

- je

ś

li “glass pane” staje si

ę

“widoczny” wtedy blokuje on wszelkie zdarzenia dla “zasłanianych”
komponentów zawartych w “content pane”, w przeciwnym razie maluje
czerwon

ą

kropk

ę

w miejscu wyst

ą

pienia ostatniej wykrytej akcji.

W programie tworzony jest własny obiekt typu “glass pane” i ustawiany
metod

ą

klasy

JFrame -

setGlassPane

. W ten sposób zdefiniujemy własny

kod malowania tego komonentu – w domy

ś

lnym „glass pane” wyst

ę

puje

pusty kod malowania.

...// Inicjalizacja własnego “glass pane” w miejscu inicjalizacji GUI:

myGlassPane = new MyGlassPane(...);
frame.setGlassPane(myGlassPane);
...

// W naszej klasie

MyGlassPane

definiujemy metod

ę

paint

:

class MyGlassPane extends JComponent {
Point point = null;

// Będzie ustawiany aktualną pozycją kursora

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 25

public void paint(Graphics g) {

if (point != null) {

g.setColor(Color.red);

g.fillOval(point.x - 10, point.y - 10, 20, 20);

}

}
...
}

// Wizualizacja “glass pane” po wci

ś

ni

ę

ciu przycisku.

JCheckBox changeButton = new JCheckBox("Glass pane \"visible\"");
changeButton.setSelected(false);
changeButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
myGlassPane.setVisible(e.getStateChange()

==

ItemEvent.SELECTED);

}
});

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 26

Alernatywne rozwi

ą

zanie dla poprzednego przykładu to doł

ą

czenie

własnych metod obsługi zdarze

ń

do domy

ś

lnego “glass pane

pobranego uprzednio metod

ą

getGlassPane

.


Przykład 12.5A.

Własna obsługa

zdarze

ń

zwi

ą

zanych z mysz

ą

dla

domy

ś

lego panelu “glass pane”. Niech nasza obsługa polega na

ponownym „rozesłaniu” zdarzenia do wła

ś

ciwych komponentów

kontenera „root pane” – listy wysuwnej lub menu.

...// Obsługa zdarzenia w “glass pane” :

public void mouseMoved(MouseEvent e) {
redispatchMouseEvent(e, false);
}

.../* Metody :

mouseDragged,

mouseClicked,
mouseEntered,
mouseExited,

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 27

mousePressed

implementowane s

ą

w identyczny sposób

jak powy

ż

sza metoda

mouseMoved

*/.

// Implementacja metody

mouseReleased

:

public void mouseReleased(MouseEvent e) {
redispatchMouseEvent(e, true);
inDrag = false;
}

// Definicja metody obsługi – rozesłania obsług do komponentów:

private void redispatchMouseEvent(MouseEvent e, boolean repaint) {
boolean inButton = false;
boolean inMenuBar = false;
Point glassPanePoint = e.getPoint();
Component component = null;
Container container = contentPane;
Point containerPoint = SwingUtilities.convertPoint(
glassPane, glassPanePoint, contentPane);
int eventID = e.getID();
if (containerPoint.y < 0) {

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 28

inMenuBar = true;

//... tu ustawić należy odpowiednio container i containerPoint ...

testForDrag(eventID);
}
component = SwingUtilities.getDeepestComponentAt(
container, containerPoint.x, containerPoint.y);
if (component.equals(liveButton)) {
inButton = true;
testForDrag(eventID);
}
if (inMenuBar || inButton || inDrag) {

...// wyślij zdarzenie do komponentu ...

}
if (repaint) {
toolkit.beep();
glassPane.setPoint(glassPanePoint);
glassPane.repaint();
}

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 29

}
private void testForDrag(int eventID) {
if (eventID == MouseEvent.MOUSE_PRESSED) {
inDrag = true;
}
}

2) Warstwy funkcjonalne w GUI

Panel typu “

root pane

” przekazuje swoje komponenty – pasek menu i

komponenty zawarte w panelu typu “content pane” – do obiektu obiektu
klasy

panelu warstwowego

JLayeredPane

pełni

ą

cego rol

ę

zarz

ą

dcy

„gł

ę

bi poło

ż

enia” komponentu w GUI za pomoc

ą

wyró

ż

nienia

warstw

malowania

.



Im wy

ż

szy

indeks warstwy

"tym pó

ź

niej" i "tym bli

ż

ej wierzchu" jest ona

malowana.



W ramach tej samej warstwy o kolejno

ś

ci malowania komponentów

decyduje indeks ich

poło

ż

e

ń

w ramach warstwy

.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 30

Dodaj

ą

c komponent do panelu zawarto

ś

ci kontenera głównego mo

ż

emy

okre

ś

la

ć

jego przynale

ż

no

ść

do warstwy malowania.

panelWarstwowy.add(label, new Integer(i));

// Dodaj komponent do

//

warstwy

i

panelu warstwowego.

Do zmiany warstwy komponentu słu

ż

y metoda

setLayer

:

panelWarstwowy.setLayer(komponent, indeksWarstwy);

panelWarstwowy.setLayer(komponent, indeksWarstwy, pozycjaWWarstwie);


Pewne warto

ś

ci warstw

zarezerwowane s

ą

dla

specyficznych obiektów.

Nazwa zarezerwowanej warstwy i odpowiadaj

ą

ca jej stała, zdefiniowana

w klasie

JLayeredPane

:

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 31

FRAME_CONTENT_LAYER

new Integer(-30000)

To warstwa przeznaczona dla “content pane” i paska menu ramki.

DEFAULT_LAYER

new Integer(0)

Tutaj umieszczane s

ą

komponenty u

ż

ytkownika, którym nie nadał on

indeksu warstwy.

PALETTE_LAYER

new Integer(100)

Ta warstwa jest dogodna dla tymczasowo widocznych pasków narz

ę

dzi

i zestawów danych.

MODAL_LAYER

new Integer(200)

W tej warstwie umieszczane s

ą

okna dialogowe otwierane w trybie

wył

ą

czno

ś

ci (modalne) dla obiektu klasy

JInternalFrame

.

POPUP_LAYER

new Integer(300)

W tej warstwie wyst

ę

puj

ą

wysuwane menu typu „pop-up”, powinny one

wyst

ą

pi

ć

nad wszystkimi pozostałymi komponentami.

DRAG_LAYER

new Integer(400)

W tej warstwie umieszczany jest “uchwycony” mysz

ą

komponent

(„drag”). Po „porzuceniu” („drop”) komponentowi powinna by

ć

przywrócona jego normalna warstwa.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 32

12.4 Panel warstwowy ("layered pane")

1) Klasy paneli warstwowych

W Swingu zdefiniowano dwie klasy paneli warstwowych:



JLayeredPane

- klasa dla panelu "

root pane

" kontenera głównego;



JDesktopPane

- klasa pochodna od

JLayeredPane

, specjalizowana dla

zawierania "wewn

ę

trznych ramek".

Utworzenie własnego panelu warstwowego lub korzystanie z
domy

ś

lnego dla kontenera typu

JFrame

:

// Własny

// Domy

ś

lny

panelWarstw = new JLayeredPane();

panelWarstw = getLayeredPane();

... // Ustawienia panelu warstw

... // Ustawienia panelu warstw

// Własny panel warstwowy kontenera

frame.setLayeredPane(panelWarstw);

frame.pack();

frame.pack();

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 33

Przykład 12.6.

Program

LayeredPaneDemo

tworzy panel warstwowy i

rozmieszcza ró

ż

nokolorowe etykiety w ró

ż

nych warstwach.


W danej chwili obrazek “Duke”
rysowany jest

pod

zielon

ą

i czerwon

ą

etykiet

ą

ale

nad

pozostałymi trzema.


W kontrolce wysuwnych opcji mo

ż

na

zmieni

ć

warstw

ę

Duke-a

a

przyciskiem

radiowym

mo

ż

na

przenie

ść

go na pierwsze miejsce w

danej warstwie (pozycja 0).

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 34

// Utworzenie panelu warstwowego:

layeredPane = new JLayeredPane();

// Jedyny konstruktor w tej klasie

layeredPane.setPreferredSize(new Dimension(300, 310));

// Rozmiar

layeredPane.setBorder(BorderFactory.createTitledBorder(

// Brzeg

"Move the Mouse to Move Duke"));

// z tytułem

layeredPane.addMouseMotionListener(new MouseMotionAdapter() {

... // Obsługa zdarze

ń

myszy

});

// Dodaj komponent do okre

ś

lonej warstwy komponentów

for (int i = 0; i < ...number of labels...; i++) {
JLabel label = createColoredLabel(...);

// Metoda własna – tworzy

// obiekt klasy JLabel o pewnym kolorze, z brzegiem i tekstem.

layeredPane.add(label, new Integer(i));

// Dodaj komponent do

//

warstwy i panelu warstwowego

...
}

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 35

// Dynamiczna zmiana pozycji dla obiektu “dukeLabel” – w procedurze
//

actionPerformed

zarejestrowanej dla listy wysuwanych opcji:

public void actionPerformed(ActionEvent e) {
int position = onTop.isSelected() ? 0 : -1;

// Ustaw 0 lub -1

layeredPane.setLayer(dukeLabel,

// Komponent, który ustawiamy

layerList.getSelectedIndex(),

// Nowa warstwa

position);

// Nowa pozycja w warstwie – „góra” lub „dół

}


// Ustawienie pozycji w ramach warstwy

final ImageIcon icon = createImageIcon("images/dukeWaveRed.gif");
...
dukeLabel = new JLabel(icon);

// Utwórz etykiet

ę

zawieraj

ą

c

ą

ikon

ę

...
dukeLabel.setBounds(15, 225,

// Ustaw brzeg obiektu

icon.getIconWidth(),
icon.getIconHeight());

...

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 36

// Trzy-argumentowa wersja metody

add

:

layeredPane.add(dukeLabel,

// dodawany komponent

new Integer(2),

// obiekt Integer podaje indeks warstwy

0);

// warto

ść

int podaje pozycj

ę

w ramach warstwy

.

Pozycje w ramach warstwy numerowane
s

ą

od -1 do (n - 1), gdzie n jest liczb

ą

komponentów

warstwy.

Im

mniejsza

pozycja tym „wy

ż

ej” znajduje si

ę

dany

komponent. -1 jest równowa

ż

ne (n – 1) –

wskazuje „najni

ż

sz

ą

” pozycj

ę

.

// Metoda

actionPerformed

zarejestrowana dla listy wysuwanych opcji:

public void actionPerformed(ActionEvent e) {
if (onTop.isSelected())
layeredPane.moveToFront(dukeLabel);

// Ustaw pozycję 0

else
layeredPane.moveToBack(dukeLabel);

// Ustaw pozycje -1

}

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 37

2) Romieszczanie komponentów w warstwowym panelu

Domy

ś

lnie warstwowy panel

nie posiada menad

ż

era układu

. Nale

ż

y

samemu ustawi

ć

rozmiary i poło

ż

enia komponentów.


Np. z wykorzystaniem metody

setBounds

:

dukeLabel.setBounds(15, 225,
icon.getIconWidth(),
icon.getIconHeight());
...
label.setBounds(origin.x, origin.y, 140, 140);


Np. dynamiczna zmiana poło

ż

enia metod

ą

setLocation

:

dukeLabel.setLocation(e.getX()-XFUDGE, e.getY()-YFUDGE);


Mo

ż

na te

ż

nada

ć

menad

ż

era układu panelowi warstwowemu. B

ę

dzie

on traktował komponenty tak, jakby wszystkie nale

ż

ały do jednej

warstwy.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 38

Np.

Program

LayeredPaneDemo2

ustawia

menad

ż

era

układu

dla

panelu

warstwowego

na

obiekt

typu

GridLayout

i korzysta z niego dla

rzmieszczenia 6 kolorowych etykiet (z
poprzedniego przykładu).

Rozwi

ą

zanie z wykorzystaniem menad

ż

erów układu dla warstw:

Stosujemy kontenery po

ś

redniego poziomu (jak np. panele) - po jednym

dla ka

ż

dej warstwy komponentów –

- mo

ż

na skorzysta

ć

z menad

ż

erów układu ka

ż

dego panelu dla osobnego

ustawienia komponentów ka

ż

dej warstwy;

- poszczególne panele rozmieszczamy stosuj

ą

c bezwgl

ę

dne warto

ś

ci

poło

ż

e

ń

.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 39

12.5 Klasa

JInternalFrame

1) Klasa

JInternalFrame

umo

ż

liwia malowanie ramki wewn

ą

trz innej

ramki. Zwykle "ramki wewn

ę

trzne" dodawane s

ą

do panelu

warstwowego typu

JDesktopPane

, który z kolei staje si

ę

panelem

zawarto

ś

ci dla ramki typu

JFrame

(klasa

JDesktopPane

jest klas

ą

pochodn

ą

od klasy

JLayeredPane

).

Przykład 12.7

Program

InternalFrameDemo.java

tworzy poni

ż

szy GUI - posiada 2

wewn

ę

trzne ramki (jedna

została zminimalizowana)
wewn

ą

trz regularnej ramki.

// Tworzenie GUI -
// kod zawarty w konstruktorze klasy

InternalFrameDemo

, b

ę

d

ą

cej

// klas

ą

pochodn

ą

od klasy

JFrame

:

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 40

desktop = new JDesktopPane();

// Utwórz nowy obiekt typu

JDesktopPane

...
createFrame();

// Utwórz okno wewn

ę

trzne i doł

ą

cz do panelu

desktop

...
setContentPane(desktop);

// Ustaw panel zawarto

ś

ci ramki na

desktop

...

// Zmie

ń

tryb "uchwycenia" komponentów. Tylko obrys ramki a nie jej

// cała zawarto

ść

b

ę

d

ą

rysowane podczas przeci

ą

gania. To

// przyspieszy od

ś

wie

ż

anie kosztem wygl

ą

du.

desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
...

.. // Metoda

createFrame()

protected void createFrame() {
MyInternalFrame frame = new MyInternalFrame();

// Klasa

// programisty - pochodna od

JInternalFrame

frame.setVisible(true);

// Ustaw widoczno

ść

wewn

ę

trznej ramki

desktop.add(frame);

// Doł

ą

cz wewn

ę

trzn

ą

ramk

ę

do ramki głównej

try {

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 41

frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {}
}

// W konstruktorze klasy

MyInternalFrame

pochodnej od

JInternalFrame

:

static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;
public MyInternalFrame() {
super("Document #" + (++openFrameCount),
true,

// b

ę

dzie mo

ż

liwa zmiana rozmiaru

true,

// b

ę

dzie mo

ż

liwe zamkni

ę

cie

true,

// b

ę

dzie mo

ż

liwa maksymalizacja rozmiaru

true);

// b

ę

dzie mo

ż

liwa minimalizacja rozmiaru

//... Tworzy GUI i dodaje do ramki ...
// ... - jak na poczatku przykładu
//... Ustawia rozmiar ramki lub woła

pack()

...

// Ustaw poło

ż

enie ramki

setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
}

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 42

2) Zasady korzystania z wewn

ę

trznych ramek

Korzystanie z wewn

ę

trznych ramek przypomina korzystanie z

regularnych ramek. Ramka wewn

ę

trzna posiada panel "root pane" i

dlatego tworzenie z niej GUI jest niemal identyczne jak dla

JFrame

.

Ale

JInternalFrame

nie jest

klas

ą

typu

Windows

ani kontenerem

głównym

- wewn

ę

trzna ramka nie jest korzeniem hierarchii

komponentów - musi by

ć

dodana do kontenera (np. typu

JDesktopPane

).

JInternalFrame

posiada metody takie, jak np.

moveToFront

, która

wymaga, aby kontenerem ramki był wła

ś

nie panel warstwowy taki, jak

JDesktopPane.

Wybieraj

ą

c wewn

ę

trzne ramki w GUI u

ż

ytkownik nie generuje zdarze

ń

dla okien systemu, lecz zdarzenia dla okna ramki głównej.

Wewn

ę

trzne ramki s

ą

zaimplementowane w

kodzie niezale

ż

nym od

platformy

i dlatego daj

ą

pewne mo

ż

liwo

ś

ci u

ż

ytkownikowi, których nie

posiadaj

ą

zwykłe ramki:

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 43

-

Mo

ż

na

programowo minimalizowa

ć

lub

maksymalizowa

ć

ramk

ę

.

-

Mo

ż

na poda

ć

ikonk

ę

dla paska

z tytułem.

-

Mo

ż

na okre

ś

li

ć

, czy ramka posiada

dekoracje okien

dla zmiany

rozmiaru, minimalizacji, zamykania i maksymalizacji.

Zasady korzystania z wewn

ę

trznych ramek

1. Ustawi

ć

rozmiar wewn

ę

trznej ramki -

w przeciwnym razie b

ę

dzie ona

mie

ć

rozmiar zerowy. Metody:

setSize, pack, setBounds

.

2. Ustawi

ć

poło

ż

enie

- w przeciwnym razie lokalizacja wyniesie (0, 0)

(lewy górny róg jej kontenera). Metody:

setLocation , setBounds

.

3. Doda

ć

komponenty do "panelu zawarto

ś

ci

" wewn

ę

trznej ramki - jak

dla ramki

JFrame

.

4. Okna dialogowe

b

ę

d

ą

ce

wewn

ę

trznym ramkami

powinny by

ć

implementowane jako

JOptionPane

lub

JInternalFrame

, a nie

JDialog

.

Dla prostych dialogów nale

ż

y u

ż

y

ć

metod klasy

JOptionPane

w rodzaju:

showInternalXxxDialog.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 44

5. Wewn

ę

trzna ramka

musi by

ć

dodana do kontenera

- w przeciwnym

razie nie b

ę

dzie widoczna.

6. Nale

ż

y

wywoła

ć

show

lub

setVisible

dla wewn

ę

trznej ramki -

wewn

ę

trzne ramki s

ą

domy

ś

lnie niewidoczne. Metody:

setVisible(true)

lub

show()

.

7. Wewn

ę

trzne ramki

zgłaszaj

ą

charakterystyczne dla nich zdarzenia

.

Chocia

ż

zdarzenia te nie s

ą

zwi

ą

zane z oknami systemu, to jednak

obsługa tych zdarze

ń

jest prawie identyczna z obsług

ą

zdarze

ń

dla okien

systemu.

8. Dla zwi

ę

kszenia szybko

ś

ci od

ś

wie

ż

ania przy wielu wewn

ę

trznych

ramkach mo

ż

na zmieni

ć

tryb od

ś

wie

ż

ania podczas przeci

ą

gania.

Metoda klasy

JDesktopPane

-

setDragMode

- umo

ż

liwia ustawienie trybu

od

ś

wie

ż

ania podczas przeci

ą

gania. Np.

desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 45

12.6 Klasa

JPanel

JPanel

jest klas

ą

ogólnego kontenera po

ś

redniego poziomu:

-

zasadniczo rysuje tylko swoje tło;

-

mo

ż

na doda

ć

brzeg;

-

mo

ż

na doda

ć

komponenty;

-

komponenty rozmieszczane s

ą

przez menad

ż

era układu zwi

ą

zanego

z panelem;

-

panel jest domy

ś

lnie nieprzezroczysty i mo

ż

e wtedy słu

ż

y

ć

jako

„content pane” dla ramki lub apletu.

Przykład 12.8

W programie Converter zastosowano kilka obiektów klasy

JPanel

.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 46

Czerwony

panel – pełni rol

ę

content pane” dla ramki. Korzysta z

menad

ż

era układu typu

BoxLayout

dla rozmieszczenia w pionie swoich

komponentów. Posiada pusty brzeg o szeroko

ś

ci 5 pikseli.

Dwa panele

typu ConversionPanel (definiowanego przez u

ż

ytkownika)

– zawieraj

ą

komponenty i koordynuj

ą

wymian

ę

informacji mi

ę

dzy

odpwiadaj

ą

cymi sobie komponentami w obu panelach. Oba panele

posiadaj

ą

brzegi opatrzone w tytuł i kraw

ę

dzie. Korzystaj

ą

z

menad

ż

erów układu typu

BoxLayout

(rozmieszcza od lewej do prawej).

Po jednym panelu

- wyst

ę

puje w ka

ż

dym panelu konwersji dla

rozmieszczenia listy wysuwanych opcji z wykorzystaniem menad

ż

erów

konwersji typu

BoxLayout

(rozmieszczanie w pionie) (dodatkowo

wyst

ę

puje niewidoczny komponent wypełniaj

ą

cy obszar panelu).

Po jednym panelu

dla ka

ż

dego panelu konwersji grupuje dwa dalsze

komponenty – pole edycyjne i suwak — rozmieszczane w pionie
menad

ż

erem układu typu

BoxLayout

.


Menad

ż

er układu dla panelu

Domyslny menad

ż

er jest typu FlowLayout – rozmieszczanie w wierszu.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 47

Ustawienie innego menad

ż

era układu – podczas konstrukcji panelu lub

metod

ą

setLayout. Np.

JPanel p = new JPanel(new BorderLayout()); // preferowane rozwiązanie

// ale BoxLayout wymaga istnienia panelu:

JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));


Dodanie komponentów

// Dla menad

ż

erów układu typu FlowLayout, BoxLayout, GridLayout,

// lub SpringLayout wystarczy 1-argumentowa metoda add():

aFlowPanel.add(aComponent);
aFlowPanel.add(anotherComponent);

// Dla BorderLayout potrzebny jest argument podaj

ą

cy pozycj

ę

:

aBorderPanel.add(aComponent, BorderLayout.CENTER);
aBorderPanel.add(anotherComponent, BorderLayout.PAGE_END);

// Dla GridBagLayout mo

ż

na u

ż

y

ć

obu wersji metody add()

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 48

12.7

JScrollPane

Panel przewijany zapewnia przewijany widok komponentu, co ma
znaczenie wtedy, gdy dost

ę

pny obszar ekranu nie wystarcza na

pokazanie całego komponentu na raz.

Przykład 12.9

Program dodaje obszar tekstowy do panelu przewijania,

gdy

ż

obszar tekstowy dynamicznie ro

ś

nie.

// W konterze z menad

ż

erem układu typu Border Layout

// Utworzenie panelu przewijania z klientem – obszarem tekstowym::

textArea = new JTextArea(5, 30); // 5 wierszy i 30 kolumn tekstu
...

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 49

JScrollPane scrollPane = new JScrollPane(textArea);
...
setPreferredSize(new Dimension(450, 120)); // Rozmiar kontenera
...
add(scrollPane, BorderLayout.CENTER);

Kod dotycz

ą

cy panelu przewijania jest minimalny, gdy

ż

wszystko jest

wykonywane automatycznie przez metody klasy

JScrollPane

.

Przykład 12.10

Program

ScrollDemo

zapewnia zmodyfikowany przez

u

ż

ytkownika panel przewijania dla prezentacji du

ż

ej fotografii.


Poza obszarem centralnym – widokiem
dla komponentu – klienta (w tym
przypadku jest nim obraz) panel
przewijania zawiera te

ż

2 paski

przesuwne, nagłówek wierszy,
nagłówek kolumn i cztery rogi.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 50

// Deklaracja pola klasy:

private ScrollablePicture picture;
...

// Tworzenie GUI :

picture = new ScrollablePicture( ... ); // Utworzenie klienta
JScrollPane pictureScrollPane = new JScrollPane(picture);

ź

niejsza zmiana klienta panelu jest mo

ż

liwa metod

ą

setViewportView

.

JScrollPane

nie posiada metody getViewportView – w celu pobrania

obiektu

klienta

nale

ż

y

posłu

ż

y

ć

si

ę

wywołaniem

getViewport().getViewportView()

.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 51

Widocznym obszarem klienta zarz

ą

dza obiekt klasy

JViewport

przeliczaj

ą

c aktualne poło

ż

enia pasków przewijania na ograniczenia

widocznego obszaru klienta.
Panel przewijania korzysta z dwóch obiektów klasy

JScrollBar

dla

zapewnienia pasków przewijania. Trzy obszary paska to:

„gałka” (“knob”) lub „kciuk” (“thumb”),
„przyciski strzałek” - ruch o 1 jednostk

ę

,

„tor” („track”) - ruch o 1 blok.

Ustawianie opcji przewijania

Ka

ż

dy pasek przewijania posiada własne ustawienia opcji. Konstruktory

klasy

JScrollPane,

umo

ż

liwiaj

ą

ce ustawienie opcji przewijania, to:

JScrollPane(Component, int, int)
JScrollPane(int, int)

Pierwszy parametr typu

int

okre

ś

la opcj

ę

dla pionowego paska a drugi

parametr typu

int

dla poziomego paska.

Dynamiczne ustawienie opcji przewijania – metodami:

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 52

setHorizontalScrollBarPolicy
setVerticalScrollBarPolicy.

W interfejsie

ScrollPaneConstants

(implementowanym przez

JScrollPane

)

zdefiniowano nast

ę

puj

ą

ce stałe:

VERTICAL_SCROLLBAR_AS_NEEDED
HORIZONTAL_SCROLLBAR_AS_NEEDED

Domy

ś

lne ustawienie – pasek przewijania pojawia si

ę

w razie potrzeby

wtedy, gdy obszar widoku jest mniejszy ni

ż

obszar klienta a znika, gdy

widok jest wi

ę

kszy ni

ż

obszar klienta.

VERTICAL_SCROLLBAR_ALWAYS
HORIZONTAL_SCROLLBAR_ALWAYS

Zawsze wy

ś

wietla pasek przewijania – jedynie

ś

rodkowa cz

ęść

paska

(gałka) znika, gdy widok mo

ż

e pomie

ś

ci

ć

całego klienta.

VERTICAL_SCROLLBAR_NEVER
HORIZONTAL_SCROLLBAR_NEVER

Nigdy nie wy

ś

wietla paska przewijania.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 53

Dekoracje u

ż

ytkownika

Obszar panelu przewijania mo

ż

e składa

ć

si

ę

z

9 cz

ęś

ci:



obszaru centralnego,



czterech boków i



czterech naro

ż

ników.

Jedynie obszar centralny musi zawsze wyst

ą

pi

ć

– pozostałe s

ą

opcjonalne. W obszarach bocznych mog

ą

wyst

ą

pi

ć

paski przewijania i

nagłówki wierszy oraz kolumn. Naro

ż

niki s

ą

widoczne tylko wtedy, gdy

przecinaj

ą

si

ę

w nich po dwa widoczne komponenty.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 54

Przykład 12.11

W powy

ż

szym przykładzie 3 z 4 naro

ż

ników s

ą

wykorzystane przez u

ż

ytkownika – jeden zawiera dwustanowy przycisk,

a dwa dalsze s

ą

jedynie wypełniane kolorem linijek. Ostatni naro

ż

nik, na

przeci

ę

ciu pasków przewijania jest domy

ś

lnej postaci – mo

ż

e on zanika

ć

wtedy, gdy zaniknie przynajmniej jeden z pasków.

Nagłówki kolumn i wierszy zrealizowane s

ą

za pomoc

ą

komponentu

u

ż

ytkownika

Rule

(linijka). Mo

ż

na w tym celu u

ż

y

ć

dowolnego

komponentu. Panel przewijania umieszcza komponenty dla nagłówków
kolumn i wierszy w ich własnych widokach -

JViewport

. Te komponenty

przesuwaj

ą

si

ę

podczas przewijania synchronicznie z widokiem obszaru

klienta.

// Miejsce deklaracji pól klasy panelu:

private Rule columnView;
private Rule rowView;
...

// Miejsce inicjalizacji GUI :

ImageIcon david = createImageIcon("images/youngdad.jpeg");

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 55

...

// Utwórz nagłówki wierszy i kolumn:

columnView = new Rule(Rule.HORIZONTAL, true);
rowView = new Rule(Rule.VERTICAL, true);
if (david != null) {
columnView.setPreferredWidth(david.getIconWidth());
rowView.setPreferredHeight(david.getIconHeight());
}
...
pictureScrollPane.setColumnHeaderView(columnView);
pictureScrollPane.setRowHeaderView(rowView);


Jako klasa pochodna od

JComponent

klasa u

ż

ytkownika

Rule

definiuje

metod

ę

paintComponent

dla rysowania obiektu na ekranie. Metoda ta

sprawdza aktualny widok dla obiektu tak, aby nie rysowa

ć

cz

ęś

ci, które

wykraczaj

ą

poza ten widok.

W dwóch naro

ż

nikach umieszczane s

ą

obiekty klasy u

ż

ytkownika

Corner

a w trzecim – dwustanowy przycisk klasy

JToggleButton

:

// Utwórz obiekt dla naro

ż

nika z przyciskiem

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 56

JPanel buttonCorner = new JPanel();

// korzysta z FlowLayout

isMetric = new JToggleButton("cm", true);
isMetric.setFont(new Font("SansSerif", Font.PLAIN, 11));
isMetric.setMargin(new Insets(2,2,2,2));
isMetric.addItemListener(this);
buttonCorner.add(isMetric);
...

// Ustaw naro

ż

niki panelu przewijania

pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
buttonCorner);
pictureScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER,
new Corner());
pictureScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER,
new Corner());

Rozmiar naro

ż

nika wyznaczany jest przez rozmiary boków panelu

przewijania przecinaj

ą

cych si

ę

w danym naro

ż

niku.

Stałe definiowane w interfejsie

ScrollPaneConstants

wyznaczaj

ą

poło

ż

enie naro

ż

nika:

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 57

Klient implementuj

ą

cy interfejs

Scrollable

Dla zapewnienia lepszej współpracy klienta z panelem przewijania klasa
komponentu klienta powinna implementowa

ć

interfejs

Scrollable

.

Wtedy klient okre

ś

li rozmiar widoku potrzebnego dla ogl

ą

dania go i

jednostki dla przewijania za pomoc

ą

ż

nych cz

ęś

ci paska.

Innym sposobem na ustawienie jednostek paska przewijania jest
wywołanie metod w klasie

JScrollBar

:

setUnitIncrement
setBlockIncrement .

Np. ustawienie jednostki pionowego przewijania na 10 pikseli:

scrollPane.getVerticalScrollBar().setUnitIncrement(10);

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 58

W powy

ż

szym programie

ScrollDemo

klientem jest obiekt klasy

u

ż

ytkownika

ScrollablePicture

, klasy pochodnej od

JLabel

. Implementuje

ona wszystkie 5 metod interfejsu

Scrollable

:

-

getScrollableBlockIncrement

-

getScrollableUnitIncrement

-

getPreferredScrollableViewportSize

-

getScrollableTracksViewportHeight

-

getScrollableTracksViewportWidth


Metoda klienta

getScrollableUnitIncrement

jest wołana wtedy, gdy

u

ż

ytkownik klika jeden z przycisków na pasku przewijania. Sensown

ą

implementacj

ą

tej metody byłoby zwrócenie liczby pikseli pomi

ę

dzy

kolejnymi działkami na linijce. W klasie

ScrollablePicture

podano jednak

troch

ę

inn

ą

implementacj

ę

: zwracana jest liczba pikseli potrzebna do

umieszczenia obrazu na najbli

ż

szym znaczniku podziałki.

public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation,
int direction) {

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 59

// Pobierz aktualne poło

ż

enie.

int currentPosition = 0;
if (orientation == SwingConstants.HORIZONTAL) {
currentPosition = visibleRect.x;
} else {
currentPosition = visibleRect.y;
}

// Wynikiem jest liczba pikseli pomi

ę

dzy

currentPosition

// a najbli

ż

szym znacznikiem w podanym kierunku .

if (direction < 0) {
int newPosition = currentPosition -
(currentPosition / maxUnitIncrement)
* maxUnitIncrement;
return (newPosition == 0) ? maxUnitIncrement : newPosition;
} else {
return ((currentPosition / maxUnitIncrement) + 1)
* maxUnitIncrement - currentPosition;
}

}

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 60

Je

ś

li obraz znajduje si

ę

ju

ż

na znaczniku linijki ta metoda zwraca liczb

ą

pikseli pomi

ę

dzy dwoma znacznikami.

Panel przewijania wywołuje metod

ę

klienta

getScrollableBlockIncrement

je

ś

li potrzebna jest jednostka przewini

ę

cia o blok. Implementacja tej

metody w przykładowej klasie u

ż

ytkownika:

public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation,
int direction) {
if (orientation == SwingConstants.HORIZONTAL)
return visibleRect.width - maxUnitIncrement;
else
return visibleRect.height - maxUnitIncrement;
}

Powy

ż

sza metoda zwraca wysoko

ść

widoku zmniejszon

ą

o odległo

ść

pomi

ę

dzy znacznikami linijki. Jest to typowe podej

ś

cie. W ten sposób

pozostaje widoczny jeszcze w

ą

ski fragment poprzedniego widoku.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 61

Klasa u

ż

ytkownika

ScrollablePicture

implementuje te

ż

procedur

ę

obsługi

zdarzenia myszy, która pozwala na przewijanie obrazu metod

ą

“uchwycenia” i wyj

ś

cia kursorem poza obszar obrazu:

public class ScrollablePicture extends JLabel
implements Scrollable, MouseMotionListener {
...
public ScrollablePicture(...) {
...
setAutoscrolls(true);

// Dla zdarzenia sztucznego przesuni

ę

cia

addMouseMotionListener(this);

// Obsługa przesuni

ę

cia mysz

ą

}

...

public void mouseDragged(MouseEvent e) {

// U

ż

ytkownik “przeci

ą

ga” klienta, wi

ę

c przewijaj go:

Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
scrollRectToVisible(r);
}
...
}

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 62

Metoda

setAutoscrolls,

zdefiniowana w

JComponent,

ma na celu

asystowanie przy procesie “przewijania przez przeci

ą

ganie”. Po nadaniu

własno

ś

ci

autoscrolls

warto

ś

ci

true

komponent b

ę

dzie zgłaszał zdarzenia

typu “

mouse-dragged

” wtedy, gdy mysz jest zatrzymana poza

komponentem w stanie „uchwycenia” klienta komponentu.

Okre

ś

lenie rozmiaru panelu przewijania

Je

ś

li rozmiar panelu przewijania nie jest ustawiony jawnie to zostanie on

obliczony na podstawie preferowanych rozmiarów jego 9 cz

ęś

ci.

Najistotniejszy jest tu rozmiar widoku klienta.
Je

ś

li klient nie jest przygotowany do przewijania (nie implementuje

Scrollable) wtedy stosowanie panelu przewijanie staje si

ę

nadmiarowe –

rozmiar panelu jest wystarczaj

ą

co du

ż

y, aby prezentowa

ć

preferowany

rozmiar klienta, czyli cało

ść

.

Je

ś

li klient jest przygotowany do przewijania to panel przewijania

pobiera

jego

preferowany

rozmiar

widoku

metod

ą

klienta

getPreferredScrollableViewportSize .

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 63

Np. w klasie

JList

implementacja

getPreferredScrollableViewportSize

umo

ż

liwia widok 8 wierszy.

Dynamiczna zmiana rozmiaru klienta

Je

ś

li w czasie wykonywania programu rozmiar klienta musi ulec zmianie

to nale

ż

y o tym równie

ż

powiadomi

ć

panel przewijania:

-

najpierw nadawany jest nowy preferowany rozmiar klientowi,

-

nast

ę

pnie wywołana jest metoda

revalidate

dla klienta co zmusi panel

przewijania do od

ś

wie

ż

enia swojego wygl

ą

du, w tym pasków .

Np. klient nazywa si

ę

drawingArea

:

if (changed) {
drawingArea.setPreferredSize(/*nowy rozmiar*/);
drawingArea.revalidate();

// Powiadom o zmianie panel przewijania

}

Do zmiany rozmiaru klienta dopasowuj

ą

si

ę

suwaki panelu przewijania,

ale ani panel przewijania ani rozmiar widoku klienta nie ulegaj

ą

zmianie.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 64

12.8

JSplitPane

– panel dzielony

Obiekt klasy

JSplitPane

rysuje dwa poł

ą

czone ze sob

ą

komponenty,

jeden obok drugiego lub jeden nad drugim.
Przesuwaj

ą

c podziałk

ę

oddzielaj

ą

c

ą

komponenty mo

ż

na zmienia

ć

podział obszaru panelu na dwie jego cz

ęś

ci.

Panele dzielone mog

ą

by

ć

zagnie

ż

d

ż

ane co pozwala na dzielenie

obszaru ekranu na wi

ę

ksz

ą

liczb

ę

cz

ęś

ci.

Komponenty składowe dodawane s

ą

zwykle najpierw do paneli

przesuwnych a dopiero te staj

ą

si

ę

cz

ęś

ciami panelu dzielonego.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 65

Przykład 12.12

. Aplikacja korzysta z panelu dzielonego dla prezentacji

listy i obrazu obok siebie. Program pobiera dane – wektor nazw plików i
umo

ż

liwia prezentacj

ę

obrazów odpowiadaj

ą

cych nazwom.

// Utworzymy panel dzielony zawieraj

ą

cy dwa panele przewijane

splitPane = new JSplitPane (
JSplitPane.HORIZONTAL_SPLIT,

// Kierunek podziału

listScrollPane,

// 1-szy komponent składowy

pictureScrollPane);

// 2-gi komponent składowy

splitPane.setOneTouchExpandable(true);

// Przywró

ć

strzałki

splitPane.setDividerLocation(150);

// Ustal poło

ż

enie podziałki

// Okre

ś

lamy minimalne rozmiary dla składowych panelu

Dimension minimumSize = new Dimension(100, 50);
listScrollPane.setMinimumSize(minimumSize);
pictureScrollPane.setMinimumSize(minimumSize);


Kierunek podziału:

-

JSplitPane.HORIZONTAL_SPLIT

lub

JSplitPane.VERTICAL_SPLIT

,

-

ź

niejsza zmiana metod

ą

setOrientation( ).

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 66


Dwie małe strzałki na górze podziałce:

-

pojedynczym klikni

ę

ciem mo

ż

na zupełnie zwin

ąć

lub przywróci

ć

ka

ż

dy

ze składników .

-

w

ś

rodowisku “Java Look & Feel” s

ą

one domy

ś

lnie niewidoczne;

-

mo

ż

na przywróci

ć

strzałki metod

ą

setOneTouchExpandable( )

.


Dynamiczne ustawianie składników panelu dzielonego

-

Metody

słu

ż

ace

do

zmiany

komponentu

składowego:

setLeftComponent

,

setRightComponent

,

setTopComponent,

setBottomComponent

.

Interpretacja metod zale

ż

y od aktualnego kierunku podziału panelu

dzielonego. Lewy odpowiada górnemu a prawy dolnemu poło

ż

eniu i na

odwrót.

-

Mo

ż

na korzysta

ć

z metody

add()

dziedziczonej po JComponent ale po

uprzednim usuni

ę

ciu zast

ę

powanych komponentów metod

ą

remove()

.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 67

-

Przekazanie tylko jednego komponentu do panelu dzielonego sprawi,

ż

e zajmie on miejsce lewe lub górne a podziałka znajdzie si

ę

odpowiednio z prawej strony lub na dole obszaru panelu.


Ustawianie podziałki i ograniczanie jego zakresu

-

Metoda

setDividerLocation

słu

ż

y do ustawiania podziałki – w pikselach

lub w procentach.

-

Dla pobrania aktualnego poło

ż

enia podziałki wyra

ż

onego w pikselach

słu

ż

y metoda

getDividerLocation

.

Np.

// Ustaw podziałke na pikselu 150

splitPane.setDividerLocation(150);

// Ustaw podziałk

ę

na 25% cało

ś

ci dla lewego lub górnego składnika

splitPane.setDividerLocation(0.25);

-

Metoda

resetToPreferredSizes

ustawia podziałk

ę

, tak aby składowe

posiadały preferowane rozmiary. Taka jest te

ż

pocz

ą

tkowa, domy

ś

lna

podziałka.

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 68

-

Podziałk

ę

mo

ż

na przesuwa

ć

za pomoc

ą

myszy. Ograniczeniem sa

minimalne rozmiary składników panelu. Zwykle nalezy ustawi

ć

te

minimalne rozmiary (metoda

setMinimumSize

), gdy

ż

w przeciwnym

razie panel kieruje si

ę

preferowanymi rozmiarami i nie zezwala na

zmian

ę

podziałki.


Zagnie

ż

d

ż

anie paneli dzielonych

Przykład 12.13

. Kolejny program dzieli obszar UI aplikacji na trzy

cz

ęś

ci zagnie

ż

d

ż

aj

ą

c jeden panel

dzielony (utworzony w poprzednim
przykładzie w kierunku poziomym) w
drugim

(tworzonym

w

kierunku

pionowym). Pierwszym składnikiem
nowego panelu dzielonego jest
poprzedni panel dzielony a drugim
zwykła etykieta.

// Utwórz obiekt klasy SplitPaneDemo zawieraj

ą

cy panel dzielony

// z poprzedniego przykładu

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 69

SplitPaneDemo splitPaneDemo = new SplitPaneDemo();
JSplitPane top = splitPaneDemo.getSplitPane();

...

// Utwórz zwykł

ą

etykiet

ę

label = new JLabel("Click on an image name in the list.",
JLabel.CENTER);

// Utwórz panel dzielony i dodaj do niego panel oraz etykiet

ę

JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,

top, label);

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 70

12.9

JTabbedPane

Klasa

JTabbedPane

umo

ż

liwia zgrupowanie szeregu komponentów

(zwykle s

ą

nimi panele) dziel

ą

cych mi

ę

dzy sob

ą

ten sam obszar ekranu.

U

ż

ytkownik otwiera jedn

ą

z kart odpowiadaj

ą

c

ą

jednemu panelowi

wybieraj

ą

c zwi

ą

zan

ą

z ni

ą

metk

ę

(„tab”).

Przykład 12.14.

GUI aplikacji o jednym obiekcie

JTabbedPane

zawieraj

ą

cym cztery metki.

Metka mo

ż

e wy

ś

wietla

ć

ikonk

ę

i tekst a tak

ż

e zawiera

ć

wskazówk

ę

(„tool

tip”). Do zmiany poło

ż

enia metek słu

ż

y metoda

setTabPlacement

.

Nie jest wymagana własna obsługa zdarze

ń

, gdy

ż

klasa

JTabbedPane

obsługuje zdarzenia myszy.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 71


// Konstrukcja obiektu klasy JTabbedPane

ImageIcon icon = new ImageIcon("images/middle.gif");
JTabbedPane tabbedPane = new JTabbedPane();

// Dodaj karty z panelami

Component panel1 = makeTextPanel("Blah");
tabbedPane.addTab("One", icon, panel1, "Does nothing");
tabbedPane.setSelectedIndex(0);

Component panel2 = makeTextPanel("Blah blah");
tabbedPane.addTab("Two", icon, panel2, "Does twice as much nothing");

Component panel3 = makeTextPanel("Blah blah blah");
tabbedPane.addTab("Three", icon, panel3, "Still does nothing");

Component panel4 = makeTextPanel("Blah blah blah blah");
tabbedPane.addTab("Four", icon, panel4, "Does nothing at all");

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 72

12.10

Klasa JToolBar –

pasek narz

ę

dzi

Kontener klasy

JToolBar

grupuje i ustawia komponenty (zwykle s

ą

to

przyciski zaopatrzone w ikony) w wierszu lub w kolumnie. Jej zdaniem
jest ułatwienie wyboru i wywołania operacji przez u

ż

ytkownika – zbli

ż

one

zadanie do menu (klasy

JMenu

i

JMenuItem

).

Przykład 12.15

. GUI aplikacji

ToolBarDemo

posiadaj

ą

cej zestaw narz

ę

dzi

umieszczony nad obszarem tekstowym.

U

ż

ytkownik mo

ż

e przeci

ą

ga

ć

zestaw do ró

ż

nych kraw

ę

dzi kontenera, w

którym jest zawarty, a tak

ż

e przeci

ą

ga

ć

zestaw do własnego okna.

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 73

Ograniczenia:

-

Dla zapewnienia operacji “przeci

ą

gnij do własnego okna” (“drag-out”)

kontener zawieraj

ą

cy zestaw musi posiada

ć

menad

ż

era BorderLayout.

-

Zestaw narz

ę

dzi musi by

ć

obok komponentu dla centralnego obszaru,

jedynym pozostałym komponentem w kontenerze i nie mo

ż

e by

ć

w

centralnym obszarze.

// Ikonki powinny by

ć

pobrane z magazynu np. dla „Java Look and Feel”

String imgLocation = "toolbarButtonGraphics/navigation/Back24.gif";
URL imageURL = getClass().getResource(imgLocation);

if (imageURL != null) {
button = new JButton(new ImageIcon(imageURL));
}

// Utwórz i dodaj oba komponenty do kontenera

public ToolBarDemo() {
...
JToolBar toolBar = new JToolBar();
addButtons(toolBar); // Metoda własna użytkownika

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 74

...
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
...
contentPane.add(toolBar, BorderLayout.NORTH);
contentPane.add(scrollPane, BorderLayout.CENTER);
...
}

// Dodaj przyciski do zestawu narz

ę

dzi

protected void addButtons(JToolBar toolBar) {
JButton button = null;
// 1-szy przycisk
button = new JButton(new ImageIcon("images/left.gif"));
...
toolBar.add(button);
// 2-gi przycisk
button = new JButton(new ImageIcon("images/middle.gif"));
...

background image

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 75

toolBar.add(button);
// Trzeci przycisk
button = new JButton(new ImageIcon("images/right.gif"));
...
toolBar.add(button);
}

Przykład 12.16.

Program

ToolBarDemo2

. Kilka dodatkowych własno

ś

ci

zestawu

narz

ę

dzi:

unieruchomienie

zestawu

(metoda

setFloatable(false)), dodanie separatora , dodanie komponentu innego
ni

ż

przycisk.


W widoku zestawu narz

ę

dzi nie ma

ju

ż

„zderzaka”, gdy

ż

zestaw nie

mo

ż

e by

ć

przeci

ą

gany.

Wył

ą

czenie „przeci

ą

galno

ś

ci” zestawu narz

ę

dzi:

toolBar.setFloatable(false);

Dodanie separatora – spacji:

toolBar.addSeparator();

12. Swing – kontenery.

W. Kasprzak: Programowanie zdarzeniowe

12 - 76

Dodanie nowych komponentów:

// Czwarty przycisk

button = new JButton("Another button");
...
toolBar.add(button);

// Piąty komponent

JTextField textField = new JTextField("A text field");
...
toolBar.add(textField);

Komponenty ustawione s

ą

w sposób

wy

ś

rodkowany

wzgl

ę

dem siebie.

Mog

ą

by

ć

dopasowane swoimi dolnymi lub górnymi kraw

ę

dziami (przy

ustawieniu ich w poziomie) metod

ą

setAlignmentY

.

Np. wywoła

ć

nale

ż

y

setAlignmentY(TOP_ALIGNMENT)

dla ka

ż

dego

komponentu.
Podobnie metoda

setAlignmentX

słu

ż

y do zwi

ą

zania bokami wtedy, gdy

komponenty ustawione s

ą

w pionie.

Generalnie zestaw narz

ę

dzi korzysta z menad

ż

era układu

BoxLayout

.


Wyszukiwarka

Podobne podstrony:
Proz S2 id 402992 Nieznany
Proz S9 id 402999 Nieznany
Proz S8 id 402998 Nieznany
Proz S13 id 402990 Nieznany
Proz S4 id 402994 Nieznany
Proz S3 id 402993 Nieznany
Proz S14 id 402991 Nieznany
Proz S7 id 402997 Nieznany
Proz S10 id 402987 Nieznany
Proz S5 id 402995 Nieznany
Proz S2 id 402992 Nieznany
chemia proz maj 2011 cke id 112 Nieznany
Abolicja podatkowa id 50334 Nieznany (2)
4 LIDER MENEDZER id 37733 Nieznany (2)
katechezy MB id 233498 Nieznany
metro sciaga id 296943 Nieznany
perf id 354744 Nieznany
interbase id 92028 Nieznany

więcej podobnych podstron