background image

 

Przygotował: Jacek Sroka

1

Programowanie obiektowe

Swing

background image

 

Przygotował: Jacek Sroka

2

GUI w Javie

Abstract Window Toolkit (AWT)

podstawowy zbiór komponentów opartych na zarządcy okien

wspólny mianownik funkcjonalności ze wszystkich platform

rozbudowany model obsługi zdarzeń

klasy pomocnicze m.in. kształty, kolory i fonty

zarządcy układu

obsługa schowka

background image

 

Przygotował: Jacek Sroka

3

GUI w Javie

Swing

to co w AWT plus

Javowa implementacja komponentów z AWT

rozbudowany zestaw komponentów zaimplementowanych w Javie

tylko komponenty najwyższego poziomu są oparte na zarządcy okien

ta sama funkcjonalność na wszystkich platformach

przełączalny wygląd i zachowanie (pluggable look and feel)

dość dobra ale nie idealna symulacja wyglądu zarządcy okien (nie korzysta z 
akceleracji)

background image

 

Przygotował: Jacek Sroka

4

GUI w Javie c.d.

Standard Widget Toolkit (SWT)

zapoczątkowany przez IBMa, rozwijany w ramach platformy Eclipse

opiera się na zarządcy okien tak ja AWT, ale nie ogranicza funkcjonalności

gorsza przenośność aplikacji (WORE vs WOTE)

background image

 

Przygotował: Jacek Sroka

5

import

 javax.swing.*;

public

 

class

 WitajSwiecie {

  

private

 

static

 

void

 utwórzGUI() {

    

//tworzenie nowego okna 

    JFrame frame = 

new

 JFrame(

"Okno WitajSwiecie"

);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    

    

//dodawanie etykiety z przywitaniem

    JLabel label = 

new

 JLabel(

"Witaj świecie!"

);

    frame.add(label);

    

    

//ustalanie wymiarów i wyświetlanie okna

    

//frame.pack(); //względem komponentów

    frame.setSize(300,150);

    frame.setVisible(

true

);

  }

  

  

public

 

static

 

void

 main(String[] args) {

    

//aby uniknąć zakleszczeń tworzenie GUI

    //zlecamy do wątku obsługi zdarzeń

    SwingUtilities.invokeLater(

new

 Runnable() {

      

public

 

void

 run() {

        utwórzGUI();

      }

    });

  }

}

Przykład

background image

 

Przygotował: Jacek Sroka

6

Podstawowe komponenty

JLabel

wyświetla tekst lub obrazek

get/setText()

get/setIcon()

get/setHorizontalAlignment()

get/setVerticalAlignment()

get/setDisplayedMnemonic() – mnemonic to podkreślona 

litera

get/setLabelFor() – komponent do którego zostanie 

przeniesiony focus po wybraniu Alt+mnemonic

background image

 

Przygotował: Jacek Sroka

7

Podstawowe komponenty

JButton

podobnie jak etykieta (i inne komponenty) posiada 

get/setText(), get/setIcon(), get/setHorizontalAlignment(), 

get/setVerticalAlignment(), get/setDisplayedMnenomic()

przycisk może zmieniać wygląd w zależności od swojego stanu

get/setDisabledIcon()

get/setDisabledSelectedIcon()

get/setIcon()

get/setPressedIcon()

get/setRolloverIcon()

get/setRolloverSelectedIcon()

get/setSelectedIcon()

akcję dowiązujemy przy pomocy zdarzeń

background image

 

Przygotował: Jacek Sroka

8

Podstawowe komponenty

JTextField

get/setText()

JFrame

kontener na inne komponenty

łącznik do systemu operacyjnego (systemu okien)

get/setTitle() – tytuł okienka

get/setState() – minimalizacja/maksymalizacja

is/setVisible() – widoczność na ekranie

get/setLocation() – umiejscowienie na ekranie

get/setSize() – rozmiar

add() – dodanie komponentu

background image

 

Przygotował: Jacek Sroka

9

Drugi przykład

import

 javax.swing.*;

public

 

class

 AWitajŚwiecie 

extends

 JFrame {

    JLabel 

jLabel

;

    JTextField 

jTextField

;

    JButton 

jButton

;

    

public

 AWitajŚwiecie()

   {

      

super

();

      

this

.setSize(300, 200);

      

this

.getContentPane().setLayout(

null

);

      

this

.add(getJLabel(), 

null

);

      

this

.add(getJTextField(), 

null

);

      

this

.add(getJButton(), 

null

);

      

this

.setTitle(

"WitajSwiecie"

);

      

this

.setVisible(

true

);

   }

background image

 

Przygotował: Jacek Sroka

10

private

 javax.swing.JLabel getJLabel() {

   

if

(jLabel == 

null

) {

      jLabel = 

new

 javax.swing.JLabel();

      jLabel.setBounds(34, 49, 53, 18);

      jLabel.setText(

"Imię:"

);

   }

   

return

 jLabel;

}

private

 javax.swing.JTextField getJTextField() {

   

if

(jTextField == 

null

) {

      jTextField = 

new

 javax.swing.JTextField();

      jTextField.setBounds(96, 49, 160, 20);

   }

   

return

 jTextField;

}

private

 javax.swing.JButton getJButton() {

   

if

(jButton == 

null

) {

      jButton = 

new

 javax.swing.JButton();

      jButton.setBounds(103, 110, 71, 27);

      jButton.setText(

"OK"

);

   }

   

return

 jButton;

}

public

 

static

 

void

 main(String[] args) {

   

new

 AWitajŚwiecie();

}

background image

 

Przygotował: Jacek Sroka

11

Problemy

Bezwzględne rozmiary i współrzędne

jak to będzie wyglądać na innych platformach?

Jak zakończyć aplikację?

DO_NOTHING_ON_CLOSE

HIDE_ON_CLOSE (domyślne dla JDialog i JFrame) – ukrywa okno

DISPOSE_ON_CLOSE (domyślne dla JInternalFrame) – ukrywa i 

zwalnia zasoby; jeżeli to było ostatnie okno to VM może zakończyć 
działanie

EXIT_ON_CLOSE kończy aplikację przy pomocy System.exit(0)

Czy rozszerzać JFrame i pamiętać komponenty jako atrybuty?

background image

 

Przygotował: Jacek Sroka

12

Zarządcy układu

BorderLayout

używany domyślnie przez główne komponenty (JApplet, JDialog i 
JFrame)

zmiana metodą setLayout(LayoutManager)

rejony: prawo, lewo, góra, dół, środek (domyślnie)

dodanie nowego komponentu do rejonu już posiadającego zawartość 
spowoduje jej podmianę

FlowLayout

układa komponenty od lewej do prawej

dozwala komponentom na preferowany
rozmiar, nawet jak nie będą przez to
widoczne w całości

background image

 

Przygotował: Jacek Sroka

13

Zarządcy układu c.d.

GridLayout

komponenty umieszczane są w komórkach siatki

wszystkie komponenty mają taki sam rozmiar

I wiele innych...

BoxLayout – wiersz lub kolumna (można zagnieżdżać)

GridBagLayout – duże możliwości, skomplikowany

SpringLayout – rozmieszczenie wyznaczone przez więzy (sprężyny z 

minimalną, maksymalną i optymalną długością)

CardLayout – przełączalne karty

background image

 

Przygotował: Jacek Sroka

14

Zarządcy układu c.d.

background image

 

Przygotował: Jacek Sroka

15

Jeszcze trochę komponentów

JComboBox

pozwala wybrać max 1 element

addItem() – dodaje element do grupy

get/setSelectedIndex()–  manipuluje stanem

get/setSelectedItem() – zwraca/ustawia wybrany element

removeAllItems() – usuwa wszystkie elementy

removeItem() – usuwa konkretny element

JPasswordField

podobny do JTextField

get/setEchoChar() – wyświetlany znak

getText() – zwraca napis (przy heap dump teoretycznie można go odczytać)

getPassword() – zwraca char[]

background image

 

Przygotował: Jacek Sroka

16

Jeszcze trochę komponentów c.d.

JCheckBox i JRadioButton 

JRadioButton  daje wykluczający się wybór

add()  –  dodaje checkbox lub przycisk do grupy

getElements() – zwraca wszystkie komponenty

grupy do iteracji

JOptionPane

gotowiec do wyskakujących okienek

background image

 

Przygotował: Jacek Sroka

17

Jeszcze trochę komponentów c.d.

JMenu/JMenuItem/JMenuBar

przy pomocy setJMenuBar() ustawia się JMenuBar dla ramki

JMenu zawiera JMenuItem lub inne JMenu

JMenuItem się wybiera

dla JMenuItem można ustawić skrót

dla JMenu i JMenuItem można ustawiać mnemoniki

Wspólne metody JMenuItem oraz jego podklasy JMenu:

get/setAccelerator() – ustawia skrót postaci Ctrl+klawisz

get/setText() – tekst wyświetlany w menu

get/setIcon() – ikona wyświetlana w menu

Metody JMenu:

add() – dodaje element lub podmenu

background image

 

Przygotował: Jacek Sroka

18

Jeszcze trochę komponentów c.d.

JSlider

wygodne pobieranie wartości całkowitych

z zadanego zakresu

get/setMinimum()

get/setMaximum()

get/setOrientation() – pion lub poziom

get/setValue()

JSpinner

umożliwia wybór z ciągu wartości, np. liczb, dat, kolorów

(trochę podobny do JSlider i JComboBox)

get/setValue() – początkowa wartość jako liczba całkowita

getNextValue() – wartość po kliknięciu strzałki w górę

getPrevioudValue() – wartość po kliknięciu strzałki w dół

background image

 

Przygotował: Jacek Sroka

19

Jeszcze trochę komponentów c.d.

JToolBar

pasek narzędziowy, może pływać

działa jak paleta na inne komponenty

is/setFloatable()

JToolTip

podpisy do wszystkich innych komponentów

sami nie tworzymy tylko ustawiamy metodą setToolTip()

background image

 

Przygotował: Jacek Sroka

20

Jeszcze trochę komponentów c.d.

JTextArea

wieloliniowe pole tekstowe

is/setLineWrap() – czy załamywać linie

is/setWrapStyleWord() – 

czy załamywać słowa

JScrollPane

przykład Dekoratora

getHorizontalScrollBar() –  zwraca zawarty

obiekty JScrollBar

getVerticalScrollBar() –  analogicznie

get/setHorizontalScrollBarPolicy() –

 Always, Never lub Needed

get/setVerticalScrollBarPolicy() –

 analogicznie

background image

 

Przygotował: Jacek Sroka

21

Jeszcze trochę komponentów c.d.

JList

podobna do JComboBox,

ale umożliwia wybór wielu wartości

najlepiej opakowywać w JScrollPane

get/setSelectedIndex() – indeks wiersza

lub int[]

get/setSelectionMode() – tryb wyboru

setListData() – dane dla listy

aet/setSelectedValue() – zaznaczony obiekt

background image

 

Przygotował: Jacek Sroka

22

Jeszcze trochę komponentów c.d.

JTable

JTree

background image

 

Przygotował: Jacek Sroka

23

Obsługa zdarzeń

Wzorzec Obserwator (ang. Observer)

Wydawca-Prenumerator (ang. Publish-Subscribe)

Delegowanie obsługi zdarzeń (ang. Delegation Event Model)

Konwencja nazewnicza

addActionListener(ActionListener) i 

removeActionListener(ActionListener)

actionPerformed(ActionEvent)

Kod obsługi zdarzeń wykonywany jest przez wątek 

koordynujący zdarzenia

długotrwałe operacje zamulają interfejs

można używać SwingUtilities.invokeLater()

uwaga na zakleszczenia przy przebudowywaniu interfejsu z innego wątku

background image

 

Przygotował: Jacek Sroka

24

public

 

class

 ZliczanieKliknięć 

extends

 JFrame {

  Integer licznikKliknięć = 0; JLabel etykieta;

 

  

class

 ZwiększanieLicznika 

implements

 ActionListener {

    

public

 

void

 actionPerformed(ActionEvent e) {

      

//obiekt klasy wewnętrznej ma dostęp do skład. obiektu klasy otaczającej

      licznikKliknięć++;

      etykieta.setText(

"Dotychczas kliknąłeś "

 + licznikKliknięć +

                       (licznikKliknięć == 1 ? 

" raz"

 : 

" razy"

));

    }

  }

 

  ZliczanieKliknięć() {

    

super

(

"Okno ZliczanieKliknięć"

);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = 

new

 JPanel();

    panel.setLayout(

new

 GridLayout(3, 0));

    JButton przycisk = 

new

 JButton(

"Kliknij"

);

    przycisk.addActionListener(

new

 ZwiększanieLicznika());

    panel.add(przycisk);

   

    etykieta = 

new

 JLabel(

"Jeszcze nie kliknięto ani razu"

);

    panel.add(

new

 JPanel());

//pusty panel zapewnia odstęp

    panel.add(etykieta);

    

//puste obramowanie odsuwa komponenty od krawędzi

    panel.setBorder(BorderFactory.createEmptyBorder(30,60,10,60));

    add(panel);

    

//...

background image

 

Przygotował: Jacek Sroka

25

Najważniejsze rodzaje zdarzeń

ActionListener – kliknięcie przycisku, wybór pozycji z menu, 

zaakceptowanie wartości w polu tekstowym

actionPerformed(ActionEvent e)

KeyListener – obsługa klawiatury: wciśnięcie, puszczenie i kliknięcie 

klawisza

istnieje klasa adapter KeyAdapter 

keyPressed(KeyEvent e)

keyReleased(KeyEvent e)

keyTyped(KeyEvent e) 

background image

 

Przygotował: Jacek Sroka

26

Najważniejsze rodzaje zdarzeń

MouseListener – obsługa myszki: wciśnięcie przycisku, puszczenie 

przycisku, kliknięcie, najechanie i opuszczenie

istnieje klasa adapter MouseMotionListener

mouseClicked(MouseEvent e)

mouseEntered(MouseEvent e)

mouseExited(MouseEvent e)

mousePressed(MouseEvent e)

mouseReleased(MouseEvent e) 

MouseMotionListener – wykrywanie ruchu kursora

istnieje klasa adapter MouseMotionAdapter

mouseDragged(MouseEvent e)

mouseMoved(MouseEvent e) 

background image

 

Przygotował: Jacek Sroka

27

Najważniejsze rodzaje zdarzeń

TextListener –  dotyczy komponentów rozszerzających 
JTextComponent (np. JTextArea i JTextField); zachodzi gdy zmienił 

się tekst

textValueChanged(TextEvent e)

WindowListener –  aktywacja/dezaktywacja, 

minimalizacja/maksymalizacja, itp.

istnieje klasa adapter WindowAdapter

windowActivated(WindowEvent e)

windowClosed(WindowEvent e)

windowClosing(WindowEvent e)

windowDeactivated(WindowEvent e)

windowDeiconified(WindowEvent e)

windowIconified(WindowEvent e)

windowOpened(WindowEvent e) 

background image

 

Przygotował: Jacek Sroka

28

Modele

Zamiast żmudnie zarządzać danymi niektórych komponentów 

wygodniej podłączyć do nich model

JComboBox – jakie są możliwości wyboru i ile ich jest

JSpinner – co wyświetlić i jakie są poprzednie i wcześniejsze możliwości

JList – jaki tekst opisuje poszczególne możliwości wyboru

JTable – liczba kolumn i wierszy, ich etykiety, klasy kolumn, tekst każdej 

komórki

JTree – struktura drzewa

background image

 

Przygotował: Jacek Sroka

29

Modele – przykład

super

(

"Okno ComboBoxModel"

);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

String[] data = {

"Ala"

"Ola"

"Ela"

"Ula"

};

MyComboModel model = 

new

 MyComboModel(java.util.Arrays.asList(data));

JComboBox cb1 = 

new

 JComboBox();

JComboBox cb2 = 

new

 JComboBox();

cb1.setModel(model);

cb2.setModel(model);

setLayout(

new

 FlowLayout());

add(cb1);

add(cb2);

setSize(300, 150);

setVisible(

true

);

background image

 

Przygotował: Jacek Sroka

30

Modele – przykład c.d.

class

 MyComboModel 

implements

 ComboBoxModel {

  

private

 List data = 

new

 ArrayList();

  

private

 

int

 

selected

 = 0;

  

public

 MyComboModel(List list) { 

data = list; }

  

public

 

void

 setSelectedItem(Object o) { 

selected

 = data.indexOf(o); 

}

  

public

 Object getSelectedItem() { 

return

 data.get(

selected

); 

}

  

public

 

int

 getSize() { 

return

 data.size();

 }

  

public

 Object getElementAt(

int

 i) { 

return

 data.get(i); 

}

  

public

 

void

 addListDataListener(ListDataListener l) {

      

//rejestruje listenery zainteresowane zmianami modelu

  }

  

public

 

void

 removeListDataListener(ListDataListener l) {

      

//usuwa listenery zainteresowane zmianami modelu

  }

}

background image

 

Przygotował: Jacek Sroka

31

Wygląd i zachowanie

Standardowe podklasy LookAndFeel

javax.swing.plaf.metal.MetalLookAndFeel – domyślne 

międzyplatformowe wygląd i zachowanie Javy; można go używać na każdej 
platformie,

com.sun.java.swing.plaf.windows.WindowsLookAndFeel – 

wygląd i zachowanie symulujące te znane z systemu Windows; obecnie 
można ich używać tylko pod systemem Windows,

com.sun.java.swing.plaf.motif.MotifLookAndFeel – wygląd i 

zachowanie CDE/Motif; domyślne na systemach firmy SUN; można go 
używać na każdej platformie,

com.sun.java.swing.plaf.gtk.GTKLookAndFeel – wygląd i 

zachowanie GTK+ (nie jest dostępny w wszystkich wersjach JRE). 

wiele innych na http://www.javootoo.com/

background image

 

Przygotował: Jacek Sroka

32

Przełączanie wyglądu i zachowania

w trakcie startu aplikacji

java -Dswing.defaultlaf=

      com.sun.java.swing.plaf.gtk.GTKLookAndFeel

      MyApp

jak nie doszło jeszcze do statycznej inicjalizacji żadnej klasy 
Swinga

UIManager.setLookAndFeel(String)

w trakcie działania aplikacji

SwingUtilities.updateComponentTreeUI(Component)

dwie przydatne metody:

UIManager.getSystemLookAndFeelClassName()

UIManager.getCrossPlatformLookAndFeelClassName()

background image

 

Przygotował: Jacek Sroka

33

Listwa górna i ramka okna

Niektóre wyglądy potrafią same rysować listwę górną i ramkę 

okna, np. javax.swing.plaf.metal.MetalLookAndFeel

zazwyczaj jest dostarczana przez menadżera okien

JFrame.setDefaultLookAndFeelDecorated(true)

background image

 

Przygotował: Jacek Sroka

34

Co dalej

Ćwiczenia z ważniaka

Bardzo dobre przewodniki na

http://java.sun.com/docs/books/tutorial/

Projekt Matisse

http://www.netbeans.org/kb/trails/matisse.html


Document Outline