PROGRAMOWANIE APLIKACJI
MULTIMEDIALNYCH
JĘZYK JAVA
Prowadzący:
Tomasz Kowalski
wykład 2
KOMPONENTY SWING
Komponenty Swing
2
wykład 2: KOMPONENTY SWING
Swing dostarcza komponenty umożliwiające
tworzenie bogatych graficznych interfejsów
użytkownika.
Komponenty w Swingu definiowane są w klasach
pakietu
javax.swing
. Ich nazwy zaczynają się
literą
J
.
Część komponentów to odpowiedniki
komponentów z biblioteki AWT. Swing posiada
również nowe komponenty niedostępne w AWT.
Komponenty Swing
3
wykład 2: KOMPONENTY SWING
Podstawowe cechy komponentów pakietu Swing:
są komponentami lekkimi o niezależnym od
platformy systemowej wyglądzie (Look & Feel),
mogą być przezroczyste,
istnieje możliwość zewnętrznego ustalania ich
preferowanych, maksymalnych i minimalnych
rozmiarów dla zarządcy rozkładu,
mogą mieć ramki o dowolnie ustalanej formie,
Komponenty Swing
4
wykład 2: KOMPONENTY SWING
c.d.:
mogą mieć podpowiedzi („dymki" pomocy, fly-
over help, tooltips),
mogą być uaktywniane z klawiatury (operowanie
na GUI za pomocą klawiatury, nie tylko myszy),
mogą mieć przypisaną dodatkową informację,
można używać wygodniejszych metod do
uzyskania informacji o komponencie.
Podpowiedzi
5
wykład 2: KOMPONENTY SWING
Klasy używane przy tworzeniu interfejsu
dziedziczą po klasie
JComponent
. Zawiera ona
metodę o nazwie
setToolTipText(String)
,
pozwalającą na umieszczanie na komponencie
podpowiedzi.
Aby ją umieścić dla obiektu
comp
(dowolnej klasy
dziedziczącej po
Jcomponent
) należy napisać:
comp.setToolTipText("Moja podpowiedź");
Podpowiedzi mogą zawierać tekst formatowany
za pomocą znaczników HTML.
Ramki
6
wykład 2: KOMPONENTY SWING
Klasa
JComponent
zawiera metodę o nazwie
setBorder()
, pozwalającą na ustawienie
każdemu z komponentów własnej ramki
(obramowania, krawędzi).
Można również tworzyć własne ramki.
Ramki
7
wykład 2: KOMPONENTY SWING
Przyciski
8
wykład 2: KOMPONENTY SWING
W Swingu mamy cztery rodzaje przycisków:
zwykły:
JButton
– odpowiednik
Button
z AWT,
JToggleButton
– przycisk dwustanowy o
wyglądzie normalnego przycisku,
JCheckBox
– odpowiednik
CheckBox
z AWT,
JRadioButton
– odpowiednik
RadioButton
z
AWT.
Podstawową funkcjonalność wszystkim klasom
przycisków dostarcza klasa
AbstractButton
.
Przyciski przełącznikowe mają za podstawę
JToggleButton
.
Przyciski
9
wykład 2: KOMPONENTY SWING
Pole tekstowe
10
wykład 2: KOMPONENTY SWING
Klasa
JTextField
oznacza tekstowe pole
edycyjne (jeden wiersz).
Aby stworzyć obiekt klasy
JTextField
wystarczy
przekazać konstruktorowi szerokość pola (w
kolumnach), ale możliwe jest także użycie
konstruktora bezargumentowego.
Do zmiany zawartość tego pola, używa się
metody
setText(String)
.
JTextPane
11
wykład 2: KOMPONENTY SWING
Używając kontrolki
JTextPane
otrzymujemy bez
wielkiego wysiłku ogromne możliwości edycji
tekstu.
Komponent ten posiada takie funkcje jak
np. automatyczne zawijanie wierszy.
Posiada on wiele innych ciekawych funkcji, które
można wyszukać w dokumentacji JDK.
Listy rozwijalne
12
wykład 2: KOMPONENTY SWING
Listy rozwijane (drop-down list
), pozwalają na
wybór tylko jednego elementu z grupy różnych
możliwości.
Lista rozwijana w Javie nie działa tak samo,
jak listy rozwijane w Windows.
W kontrolce
JComboBox
można wybrać jeden
i tylko jeden z elementów listy.
Listy
13
wykład 2: KOMPONENTY SWING
Pola listy znacząco różnią się od list rozwijanych
JComboBox
i to nie tylko wyglądem.
Lista typu
JComboBox
rozwija się dopiero przy
aktywacji.
Natomiast lista typu
JList
zawsze zajmuje z góry
określony obszar ekranu. Lista
JList
pozwala
również na wielokrotny wybór.
Listy
14
wykład 2: KOMPONENTY SWING
Menu
15
wykład 12: KOMPONENTY SWING
Komponenty zdolne do wyświetlania menu
zawierają metodę
setJMenuBar()
, która
przyjmuje obiekt
JMenuBar
.
Na pasku menu
JMenuBar
można umieszczać
kolejne menu, dodając obiekty typu
JMenu
.
Do nich z kolei można dodać pozycje, wstawiając
obiekty typu
JMenultem
.
Każdy taki element może mieć podpiętego
własnego odbiorcę zdarzeń
ActionListener
,
który będzie uruchamiany, po wybraniu
odpowiedniego elementu menu.
Menu
16
wykład 2: KOMPONENTY SWING
import
java.awt.*;
import
java.awt.event.*;
import
javax.swing.*;
public class
MenuTest
extends
JFrame
{
private
JTextField
textField
=
new
JTextField(15);
private
JMenuBar
menuBar
=
new
JMenuBar();
private
ActionListener
actionListener
=
new
ActionListener()
{
public void
actionPerformed(ActionEvent e)
{
textField
.setText(((JMenuItem)e.getSource()).getText());
}
};
private
JMenu[]
menus
= {
new
JMenu(
"Ene"
),
new
JMenu(
"Due"
),
new
Jmenu(
"Rabe"
)};
private
JMenuItem[]
items
= {
new
JMenuItem(
"Złapał"
),
new
JMenuItem(
"Bocian"
),
new
JMenuItem(
"Żabę"
),
new
JMenuItem(
"A"
),
new
JMenuItem(
"Żaba"
),
new
JMenuItem(
"Chińczyka"
),
new
JMenuItem(
"Co"
),
new
JMenuItem(
"Z tego"
),
new
JMenuItem(
"Wynika"
)};
//c.d. na następnej stronie
Menu
17
wykład 2: KOMPONENTY SWING
//kontynuacja kodu
public
MenuTest()
{
for
(
int
i = 0; i <
items
.
length
; i++)
{
items
[i].addActionListener(
actionListener
);
menus
[i % 3].add(
items
[i]);
}
for
(
int
i = 0; i <
menus
.
length
; i++)
menuBar
.add(
menus
[i]);
setJMenuBar(
menuBar
);
Container cp = getContentPane();
cp.setLayout(
new
FlowLayout());
cp.add(
textField
);
setDefaultCloseOperation(WindowConstants.
EXIT_ON_CLOSE
);
setTitle(
"MenuTest"
);
setSize(
new
Dimension(400, 300));
}
public static void
main(String[] args)
{
new
MenuTest().setVisible(
true
);
}
}
Menu
18
wykład 2: KOMPONENTY SWING
Menu
19
wykład 2: KOMPONENTY SWING
package
pl.brost.test;
import
java.awt.*;
import
javax.swing.*;
public class
AnotherMenuTest
extends
JFrame
{
private
JMenuBar
menuBar
=
new
JMenuBar();
private
JMenu
menu1
=
new
JMenu(
"Menu podstawowe 1"
);
private
JMenu
menuZagniezdzone11
=
new
JMenu(
"Menu zagnieżdżone 1.1"
);
private
JMenu
menuZagniezdzone12
=
new
JMenu(
"Menu zagnieżdżone 1.2"
);
private
JMenuItem
menuItem111
=
new
JMenuItem(
"Opcja menu 1.1.1"
);
private
JMenuItem
menuItem112
=
new
JMenuItem(
"Opcja menu 1.1.2"
);
private
JMenuItem
menuItem121
=
new
JMenuItem(
"Opcja menu 1.2.1"
);
private
JMenuItem
menuItem122
=
new
JMenuItem(
"Opcja menu 1.2.2"
);
private
JCheckBoxMenuItem
menuItem123
=
new
JCheckBoxMenuItem(
"Opcja menu 1.2.3"
);
private
JCheckBoxMenuItem
menuItem124
=
new
JCheckBoxMenuItem(
"Opcja menu 1.2.4"
);
private
JRadioButtonMenuItem
menuItem125
=
new
JRadioButtonMenuItem(
"Opcja menu 1.2.5"
);
private
JRadioButtonMenuItem
menuItem126
=
new
JRadioButtonMenuItem(
"Opcja menu 1.2.6"
);
//c.d. na następnej stronie
Menu
20
wykład 2: KOMPONENTY SWING
//kontynuacja kodu
public
AnotherMenuTest()
{
menuBar
.add(
menu1
);
menu1
.add(
menuZagniezdzone11
);
menu1
.add(
menuZagniezdzone12
);
menuZagniezdzone11
.add(
menuItem111
);
menuZagniezdzone11
.add(
menuItem112
);
menuZagniezdzone12
.add(
menuItem121
);
menuZagniezdzone12
.add(
menuItem122
);
menuZagniezdzone12
.addSeparator();
menuZagniezdzone12
.add(
menuItem123
);
menuZagniezdzone12
.add(
menuItem124
);
menuZagniezdzone12
.addSeparator();
menuZagniezdzone12
.add(
menuItem125
);
menuZagniezdzone12
.add(
menuItem126
);
setDefaultCloseOperation(WindowConstants.
EXIT_ON_CLOSE
);
setJMenuBar(
menuBar
);
setTitle(
"AnotherMenuTest"
);
setSize(
new
Dimension(400, 300));
}
public static void
main(String[] args)
{
new
AnotherMenuTest().setVisible(
true
);
}
}
Menu
21
wykład 2: KOMPONENTY SWING
Menu
22
wykład 2: KOMPONENTY SWING
Elementy menu można traktować jak przyciski co
pozwala na umieszczanie w ich opisie tekstów
i/lub ikon, kontrolowanie pozycji tekstu w stosunku
do ikony, ustalanie „mnemoników”, itd.
Jeśli dla danego menu lub elementu menu
ustalimy, za pomocą metody
setMnemonic(int)
,
kod znaku, który ma być mnemoniką. to
naciśnięcie klawiszy Alt+znak spowoduje wybór
tego elementu menu, ale tylko wtedy, gdy dany
element jest widoczny.
Menu
23
wykład 2: KOMPONENTY SWING
Innym narzędziem wyboru są akceleratory -
sekwencje klawiszy, których naciśnięcie powoduje
wybór opcji menu, niezależnie od tego, czy jest
ona widoczna.
Akceleratory ustalamy za pomocą metody
setAccelerator(KeyStroke)
.
Menu kontekstowe
24
wykład 2: KOMPONENTY SWING
Najprostszą metodą zaimplementowania menu
kontekstowego
JPopupMenu
jest stworzenie klasy
wewnętrznej rozszerzającej
MouseAdapter
(implementującej interfejs
MouseListener
), a
następnie dodanie obiektu tej klasy do każdego
komponentu, który ma posiadać menu
kontekstowe.
Menu kontekstowe
25
wykład 2: KOMPONENTY SWING
import
java.awt.*;
import
java.awt.event.*;
import
javax.swing.*;
private class
LocalPopupMenu
extends
JPopupMenu
{
private
JMenuItem
menuItem1
=
new
JMenuItem(
"Ocja menu 1"
);
private
JMenuItem
menuItem2
=
new
JMenuItem(
"Opcja menu 2"
);
private
JMenu
menu1
=
new
JMenu(
"Menu 1"
);
private
JMenuItem
menuItem11
=
new
JMenuItem(
"Ocja menu 1.1"
);
private
JMenuItem
menuItem12
=
new
JMenuItem(
"Opcja menu 1.2"
);
LocalPopupMenu()
{
add(
menuItem1
);
add(
menuItem2
);
addSeparator();
add(
menu1
);
menu1
.add(
menuItem11
);
menu1
.add(
menuItem12
);
}
}
}
//c.d. na następnej stronie
Menu kontekstowe
26
wykład 2: KOMPONENTY SWING
public class
PopupMenuTest
extends
JFrame
{
private
JTextField
textField
=
new
JTextField(15);
private
LocalPopupMenu
popupMenu
=
new
LocalPopupMenu();
public
PopupMenuTest()
{
Container cp = getContentPane();
cp.setLayout(
new
FlowLayout());
cp.add(
textField
);
popupMenu
.setInvoker(
textField
);
textField
.addMouseListener(
new
MouseAdapter()
{
public void
mousePressed(MouseEvent e)
{
showPopup(e);
}
public void
mouseReleased(MouseEvent e)
{
showPopup(e);
}
//c.d. na następnej stronie
Menu kontekstowe
27
wykład 2: KOMPONENTY SWING
//kontynuacja kodu
private void
showPopup(MouseEvent e)
{
if
(e.isPopupTrigger())
{
try
{
popupMenu
.show(
popupMenu
.getInvoker(), e.getX(), e.getY());
}
catch
(NullPointerException exc) {
exc.printStackTrace(); }
}
}
});
setDefaultCloseOperation(WindowConstants.
EXIT_ON_CLOSE
);
setTitle(
"PopupMenuTest"
);
setSize(
new
Dimension(400, 300));
}
public static void
main(String[] args)
{
new
PopupMenuTest().setVisible(
true
);
}
Menu kontekstowe
28
wykład 2: KOMPONENTY SWING
Dialogi
29
wykład 2: KOMPONENTY SWING
Dość specyficznymi dialogami są w Swingu:
dialog wyboru pliku (
JFileChooser
) i dialog
wyboru koloru (
JColorChooser
). Obie te klasy
tworzą komponenty lekkie.
Dialogi te mogą być dodane do dowolnego
kontenera i obsługiwane przez nasłuchiwanie
odpowiednich zdarzeń. Do wyboru plików i
kolorów używają standardowego
(synchronicznego i modalnego) dialogu.
Odpowiednie metody znajdują się w klasach
JFileChooser
i
JColorChooser
.
Dialogi
30
wykład 2: KOMPONENTY SWING
Dialogi
31
wykład 2: KOMPONENTY SWING
Środowiska okienkowe często zawierają zestaw
okienek komunikatów. W Swingu okienka te są
dostępne poprzez komponent
JOptionPane
.
Najczęściej używanymi będą okienko wiadomości
oraz okienko potwierdzenia, wywoływane przez
statyczne metody:
JOptionPane.showMessageDialog()
JOptionPane.showConfirmDialog()
Dialogi
32
wykład 2: KOMPONENTY SWING
HTML w komponentach
33
wykład 2: KOMPONENTY SWING
Prawie każdy komponent, który może pobierać
tekst, przyjmuje również tekst HTML, który
zostanie sformatowany zgodnie z zasadami
HTML.
Oznacza to, ze bardzo łatwo można nadać
komponentowi Swing sformatowany tekst.
HTML w komponentach
34
wykład 2: KOMPONENTY SWING
import
java.awt.*;
import
java.awt.event.*;
import
javax.swing.*;
public class
HTMLTest
extends
JFrame
{
private
JButton
button
=
new
JButton(
"<html><center>"
+
"<font size=+2 color=\"blue\">Witam!<br></font>"
+
"<i>Naciśnij mnie!</i>"
+
"</center></html>"
);
public
HTMLTest()
{
button
.addActionListener(
new
ActionListener()
{
public void
actionPerformed(ActionEvent e)
{
getContentPane().add(
new
Jlabel(
"<html><i><font size=+4 color=\"red\">"
+
"Łubudu!</font></i></html>"
));
//Wymuś ponowne rozmieszczenie aby uwzględnić nową etykietę:
validate();
}
});
//c.d. na następnej stronie
HTML w komponentach
35
wykład 2: KOMPONENTY SWING
//c.d. na następnej stronie
Container cp = getContentPane();
cp.setLayout(
new
FlowLayout());
cp.add(
button
);
setDefaultCloseOperation(WindowConstants.
EXIT_ON_CLOSE
);
setSize(
new
Dimension(400, 300));
setTitle(
"HTMLTest"
);
}
public static void
main(String[] args)
{
new
HTMLTest().setVisible(
true
);
}
}
HTML w komponentach
36
wykład 2: KOMPONENTY SWING
Kontenery Swing
37
wykład 2: KOMPONENTY SWING
Swing zapewnia szeroką gamę kontenerów
pozwalających na umieszczanie w nich
komponentów (także innych kontenerów) –
struktura drzewa.
Do tej pory posługiwaliśmy się kontenerem
ciężkim (
JFrame
) i lekkim (
JPanel
).
Zaprezentowane poniżej są także kontenerami
lekkimi.
Kontener JScrollPane
38
wykład 12: KOMPONENTY SWING
Kontener JSplitPane
39
wykład 12: KOMPONENTY SWING
Kontener JTabbedPane
40
wykład 12: KOMPONENTY SWING
Kontener JInternalFrame
41
wykład 12: KOMPONENTY SWING
Przezroczystość
42
wykład 2: KOMPONENTY SWING
Komponenty Swingu są komponentami lekkimi,
zatem mogą mieć właściwość przezroczystości.
Klasa
JComponent
dostarcza atrybut opaque
(nieprzezroczysty) oraz metody pobierające
(
isOpaque()
) i ustalające (
setOpaque()
) jego
wartość.
Niech
comp
będzie dowolnym J-komponentem.
Aby uczynić go przezroczystym, należy
zastosować następujące odwołanie:
comp.setOpaque(false);
Rysowanie w Java
43
wykład 2: KOMPONENTY SWING
Komponenty (nie tylko Swingu) udostępniają
obiekt klasy
java.awt.Graphics
. Klasa ta
udostępnia szereg metod związanych z obsługą
grafiki danego obiektu, np. czcionkami i
rysowaniem.
Aby uzyskać dostęp do obiektu
Graphics
należy
go pobrać przez metodę zdefiniowaną w klasie
Component
–
getGraphics()
, np. jeżeli w naszej
klasie dziedziczymy z jakiegoś komponentu:
Graphics g = this.getGraphics();
Rysowanie w Java
44
wykład 2: KOMPONENTY SWING
Wygodną praktyką jest przesłanianie metody
paint(Graphics)
odpowiedzialnej w
komponencie za renderowanie go na ekranie:
public void paint(Graphics g)
{
super.paint(g);
//nasza część implementacji metody
}
Dzięki temu grafika obiektu jest automatycznie
odświeżana przy zmianie jego wielkości,
powtórnym pokazaniu, itp. Inaczej musimy o to
zadbać ręcznie.
Rysowanie w Java
45
wykład 2: KOMPONENTY SWING
import
java.awt.Color;
import
java.awt.Dimension;
import
java.awt.Font;
import
java.awt.Graphics;
import
javax.swing.JFrame;
import
javax.swing.JPanel;
import
javax.swing.WindowConstants;
public class
GraphicsTest
extends
JFrame
{
public
GraphicsTest()
{
setContentPane(
new
DrawingPanel());
setSize(
new
Dimension(400, 300));
setDefaultCloseOperation(WindowConstants.
EXIT_ON_CLOSE
);
setTitle(
"GraphicsTest"
);
}
public static void
main(String[] args)
{
new
GraphicsTest().setVisible(
true
);
}
//c.d. na następnej stronie
Rysowanie w Java
46
wykład 2: KOMPONENTY SWING
//kontynuacja kodu
private class
DrawingPanel
extends
JPanel
{
DrawingPanel()
{
setBackground(Color.
white
);
}
@Override
public void
paint(Graphics g)
{
super
.paint(g);
g.setColor(Color.
red
);
g.drawLine(0, 0, 100, 100);
g.setColor(Color.
blue
);
g.drawLine(100, 100, 200, 50);
g.setColor(Color.
green
);
g.fillOval(100, 100, 150, 100);
g.setColor(Color.
black
);
g.drawOval(100, 100, 150, 100);
g.setFont(
new
Font(
"Monospaced"
, Font.
PLAIN
, 32));
g.setColor(
new
Color(255, 150, 80));
g.drawString(
"Jakiś napis"
, 100, 250);
}
}
}
Rysowanie w Java
47
wykład 2: KOMPONENTY SWING
Rysowanie w Java
48
wykład 2: KOMPONENTY SWING
Bardziej zaawansowane metody
(np. transformacje
– obroty, ścięcia, skalowanie,
itp.) udostępniane są przez klasę
java.awt.Graphics2D
uzyskiwaną wprost przez
rzutowanie obiektu
Graphics
:
Graphics g = this.getGraphics();
Graphics2D g2 = (Graphics2D)g;
lub krócej:
Graphics2D g2 =
(Graphics2D)this.getGraphics();
Javadoc
49
wykład 2: KOMPONENTY SWING
Pełna dokumentacja JFC dostępna jest pod
adresem:
http://java.sun.com/j2se/1.5.0/docs/api/index.html