AWT i Swing, Layout Managers

34
AWT i Swing - Jacek Rudzń ski 1 AWT i Swing, Layout Managers

description

AWT i Swing, Layout Managers. Krótka historia AWT i Swing. - PowerPoint PPT Presentation

Transcript of AWT i Swing, Layout Managers

Page 1: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 1

AWT i Swing,Layout

Managers

Page 2: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 2

AWT (Abstract Window Toolkit) powstało aby umożliwić programiście stworzenie interfejsu, który by wyglądał dobrze na wszystkich platformach. Niestety, AWT z Java 1.0 tworzył GUI (graficzny interfejs użytkownika), który wręcz przeciwnie wygląda źle we wszystkich systemach. Można było używać tylko 4 czcionek i nie było dostępu do bardziej wyszukanych elementów GUI, mimo iż istniały w danym systemie operacyjnym.

Poprawa sytuacji nastąpiła przy wprowadzeniu standardu JavaBeans (komponentowy model programowania, ukierunkowany na łatwe wykorzystanie w środowiskach programistycznych) w Java 1.1

Natomiast w Javie 2.0 pojawiła się jak na razie najlepsza, choć pewnie nie ostateczna biblioteka GUI dla Javy jaką jest Swing.

Krótka historia AWT i Swing

Page 3: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 3

Dlaczego stosować AWT?Aby rozpocząć pisanie z zastosowaniem AWT do tworzenia GUI musimy napisać: import java.awt.*;

Dlaczego AWT?

Łatwy

Prosty w implementacji

Na etapie nauki daje najszybciej efekty

Nawet tworząc GUI Swingiem często musimy importować AWT, gdyż w bibliotece java.awt.* są między innymi definicje Layout-ów (o czym parę slajdów dalej) a w java.awt.event.* obsługa zdarzeń.

Największą wadą AWT jest:

Różny wygląd na różnych platformach

Page 4: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 4

Dlaczego stosować Swinga?

W większości przypadków gdy korzystamy ze Swinga piszemy:

import javax.swing.*;

import java.awt.*; // opcjonalnie import java.awt.event.*;

Dlaczego Swing?

Lepszy wygląd komponentów niż w AWT

Na wszystkich platformach wygląda tak samo (niezależny od systemu)

Button-y i Label-e mogą oprócz tekstu wyświetlać także obrazki

Komponenty Swinga nie muszą być prostokątne

UWAGA: Nie należy w programach mieszać komponentów AWT i Swinga!

Page 5: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 5

Porównanie niektórych komponentów AWT i Swing

AWT Swing

Frame JFrame

Button JButton

Label JLabel

TextField JTextField

Panel JPanel

CheckBox JCheckBox

Applet JApplet

Jak widać sporo komponentów Swinga jest po prostu pochodną komponentów AWT – nazwy różnią się niewiele, gdyż w Swingu dodano literę J przed nazwą komponentu. Oczywiście Swing jako, że bardziej rozbudowany posiada komponenty, które nie mają swojego odpowiednika w AWT – np. JTable

Page 6: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 6

Dodawanie komponentów

W AWT, gdy chcemy dodać komponent stosujemy metodę add(). Natomiast w Swingu powinniśmy najpierw komponenty opakować w pojemnik, czyli Container. Komponenty JApplet, JFrame, JWidnow, JDialog przez metodę getContentPane(), zwracają obiekt klasy Container, który będzie zawierał nasze komponenty.

AWT

Swing

Page 7: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 7

W Javie mamy wiele możliwych sposobów rozmieszczenia komponentów w GUI, a służą do tego menadżery układu (z ang. layout managers). Oto niektóre z nich:

FlowLayout

BorderLayout

GridLayout

CardLayout

GridBagLayout

BoxLayout

Layout Managers

Page 8: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 8

FlowLayout

FlowLayout wypełnia panel komponentami od lewej do prawej, aż zostanie zapełniona przestrzeń, następnie przechodzi do następnego wiersza i kontynuuje zapełnianie. Zmiana kształtu i rozmiaru appletu powoduje zmianę w układzie panelu.

Page 9: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 9

Konstruktory FlowLayoutFlowLayout()

konstruktor domyślny – ustawia 5 pikseli odstępu pomiędzy komponentami

FlowLayout(int alignment)

wciąż 5 pikseli, lecz jest możliwość wyrównania do lewej, do prawej i wyśrodkowania: FlowLayout.LEFT, FlowLayout.RIGHT, FlowLayout.CENTER

FlowLayout(int alignment, int hGap, int vGap)

Oprócz możliwości wyrównania jest możliwość ustawienia poziomych i pionowych odstępów pomiędzy komponentami (w pikselach)

Page 10: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 10

BorderLayout

BorderLayout użyty bez żadnych dodatkowych instrukcji powoduje, że wszystko będzie umieszczone na środku obszaru i rozciągnięte w każdym kierunku aż do krawędzi. BorderLayout potrafi jednak więcej. Ten menadżer układu kieruje się pojęciem 4 rejonów brzegowych oraz domyślnego obszaru środkowego (North, South, East, West, Center). Gdy chcemy je zastosować korzystamy z przeciążonej wersji metody add() jak widać poniżej.

Page 11: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 11

GridLayoutGridLayout pozwala nam utworzyć tabelę komponentów. W trakcie dodawania komponenty są umieszczane od lewej do prawej i od góry na dół. W konstruktorze możemy podać potrzebną liczbę wierszy i kolumn. W naszym przypadku podajemy w konstruktorze, że będą 3 wiersze i 4 kolumny.

Page 12: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 12

Inne konstruktory BorderLayout i GridLayout

BorderLayout(int hGap, int vGap)

możliwość ustawienia poziomych i pionowych odstępów pomiędzy komponentami (w pikselach)

GridLayout()

tworzy pojedynczy rząd z jedną kolumną zaalokowaną dla pojedynczego komponentu

GridLayout(int rows, int columns, int hGap, int vGap)

oprócz podania liczby wierszy i kolumn mamy możliwość ustawienia poziomych i pionowych odstępów pomiędzy komponentami

Page 13: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 13

CardLayout – cz.1Jednym z ciekawszych layout managerów jest CardLayout. Dzięki niemu można stworzyć stos layoutów i poruszać się pomiędzy nimi. Aby utworzyć layout przy pomocy CardLayouta na początku należy stworzyć panel – rodzic, który będzie zawierał te layouty. Następnie tworzymy obiekt CardLayout i ustawiamy go jako menadżer układu panelu. Na końcu ustawiamy każdy element stosu tworząc komponenty i dodając je do panelu.

Ponieważ CardLayout pozwala programiście do wybierania pomiędzy elementami w stosie layoutów, potrzebny jest pewien sposób by wiadomo było jak to robić. Dlatego tego też CardLayout posiada pewną ilość publicznych metod, aby wiadomo było który layout ma być widoczny na ekranie. Najbardziej przydatne metody znajdują się w tabelce na następnym slajdzie.

Page 14: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 14

CardLayout – cz.2

Nazwa metody Co robi?

first(Container parent) Wyświetla pierwszy element

last(Container parent) Wyświetla ostatni element

next(Container parent) Wyświetla następny element

previous(Container parent) Wyświetla poprzedni element

show(Container parent, String name) Wyświetla konkretny element

Page 15: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 15

CardLayout – cz.3

Page 16: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 16

GridBagLayout – cz.1Największe możliwości spośród wszystkich menadżerów układu daje nam jednak GridBagLayout – przy jego pomocy możemy stworzyć bardziej skomplikowanie (wymagające więcej kodu) rozmieszczenia komponentów. Przy pomocy wielu narzędzi automatycznego generowania GUI jak n.p. JBuilder łatwiej go stosować, ale czy od razu zrozumieć? Przykładowo JBuilder potrafiłby zmodyfikować metodę add() na coś w tym stylu:

add(pAps,new GridBagConstraints2(1, GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, 3, 0.0, 0.0,GridBagConstraints.CENTER,

GridBagConstraints.NONE, new Insets(0, 0, 0, 0), -3, 45));

Jednak gdy ręcznie tworzymy kod, nie musi on tak strasznie wyglądać.

Page 17: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 17

GridBagLayout – cz.2

Zaletą GridBagLayout jest to, iż dzieli okienka na gridy, dzięki czemu możemy tworzyć różnej wielkości komponenty.

Każdy kompnent jest związany z instancją GridBagConstraints.

GridBagConstraints specyfikuje:

jak komponent jest ustawiony

w której komórce się zaczyna i kończy dany komponent

jak komponent się zmieni, gdy będzie dodatkowe miejsce

w którą stronę będzie wyrównany komponent

Na następnym slajdzie znajduje się tabelka określająca co oznaczają poszczególne pola klasy GridBagConstraints.

Page 18: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 18

GridBagLayout – cz.3 Pole Opis

anchor Określa gdzie wewnątrz obszaru danego komponentu powinien on być umieszczony np. GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST, GridBagConstraints.EAST, GridBagConstraints.SOUTHEAST,GridBagConstraints.SOUTH, GridBagConstraints.SOUTHWEST,GridBagConstraints.WEST, GridBagConstraints.NORTHWEST, GridBagConstraints.CENTER.

fill Określa jaki rozmiar nadać komponentowi, gdy obszar wyświetlania jest większy niż komponent np. : GridBagConstraints.NONE (HORIZONTAL, VERTICAL czy BOTH)

gridheight Ilość komórek w każdej kolumnie obszaru wyświetlania danego komponentu.

gridwidth Ilość komórek w każdym wierszu obszaru wyświetlania danego komponentu.

gridx Współrzędna x komórki w górnym lewym rogu obszaru wyświetlania danego komponentu.

gridy Współrzędna y komórki w górnym lewym rogu obszaru wyświetlania danego komponentu.

insets Minimalna ilość miejsca pomiędzy komponentem a brzegami obszaru wyświetlania.

ipadx Ilość miejsca w poziomie wokół komponentu.

ipady Ilość miejsca w pionie wokół komponentu.

weightx Określa czy komponenty się powiększają poziomo aby zapełnić obszar wyświetlania.

weighty Określa czy komponenty się powiększają pionowo aby zapełnić obszar wyświetlania.

Page 19: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 19

GridBagLayout – cz.4Przykład

Page 20: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 20

GridBagLayout – cz.5Przykład – ciąg dalszy

Page 21: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 21

BoxLayout

Jako, że GridBagLayout jest całkiem skomplikowany, w Swingu istnieje BoxLayout, posiadający wiele zalet poprzedniego, ale mniej skomplikowany. BoxLayout pozwala na kontrolę rozmieszczenia komponentów w pionie i poziomie oraz na kontrolę odstępów pomiędzy komponentami.

Page 22: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 22

Brak Layout Managera – ręczna robota

Jeśli layout jest ustawiony na null, to należy ręcznie ustawić i nadać rozmiar komponentom. Korzystamy z przydatnej metody setBounds:

component.setBounds(left, top, width, height)

Page 23: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 23

Rysowanie w AWTDo rysowania w Javie korzystamy z metody:

public void paint(Graphics g)

Wywołuje się ona za każdym razem, gdy kiedy applet bądź aplikacja się uruchamia oraz gdy musi być ponownie wyświetlany.

Gdy po wykonaniu jakiejś czynności znowu rysować korzystamy z metody:

public void repaint() lub jedną z jej przeciążonych wersji:

public void repaint(long tm)

public void repaint(int x, int y, int width, int height) public void repaint(long tm, int x, int y, int width, int height

Page 24: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 24

Rysowanie w Swing

Swing natomiast dzieli standardową metodę paint() na trzy osobne metody, które są wywoływane w następującej kolejności:

protected void paintComponent(Graphics g)

protected void paintBorder(Graphics g)

protected void paintChildren(Graphics g)

Programy Swingowe winny przesłaniać metodę paintComponent() zamiast paint(). Wprawdzie API zezwala na takie rozwiązanie, nie ma potrzeby przesłaniania paintBorder() czy paintChildren() (jeśli jednak to czynimy, należy to robić z ostrożnością).

Page 25: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 25

Podwójne buforowanie w AWTPodwójne buforowanie jest techniką gładkich animacji na płótnach (Canvas) czy panelach. Jest to technika pamięciochłonna ale niezbędna, gdy w naszym applecie chcemy otrzymać animacji przy wielokrotnym stosowaniu metody repaint().

W AWT przerysowywanie jest obsługiwane przy pomocy metody update(). Ta metoda po prostu czyści cały obszar obiektu i następnie wywołuje metodę paint().

Oto prosty przykład zastosowania podwójnego buforowania na płótnie. Polega on na tym, iż najpierw tworzony jest pozaekranowy bufor i po przerysowaniu jest dopiero przerzucany do okna.

Page 26: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 26

Podwójne buforowanie w SwingPodwójne buforowanie jest oczywiście także obecne w Swingu. Co więcej w Swingu mamy o wiele większe możliwości niż w AWT. Swing tworzy wsparcie dla podwójnego buforowania. Robi to przy pomocy następującej metody z javax.swing.JComponent:

public boolean isDoubleBuffered()

public void setDoubleBuffered(boolean o)

Domyślnie zwracana jest wartość true dla wszystkich komponentów Swinga.

Page 27: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 27

Model zdarzeń w Javie – cz.1

Kiedy użytkownik klika na przycisk, wpisuje tekst, używa myszy lub wykonuje jakąś inną czynność związaną z interfejsem w danym applecie, wtedy ma miejsce zdarzenie. W Javie 1.0 do obsługi kliknięć stosowano metodę action() (w tym momencie uznaną za przestarzałą), natomiast od czasu Javy 1.1 korzystamy z modelu zdarzeń delegowanych. Aby zastosować tę technikę musimy zaimplementować jeden z interfejsów typu Listener. Do wyboru mamy wiele interfejsów w zależności od tego co potrzebujemy w danym applecie bądź aplikacji. Klasa która implementuje interfejs typu XXXListener nie musi wcale być główną klasą, lecz można stworzyć do tego celu zupełnie nową klasę.

Dla każdego interfejsu typu XXXListener istnieją metody addXXXListener() oraz removeXXXListener() , dzięki którym można dodawać i usuwać odbiorców zdarzeń.

Page 28: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 28

Model zdarzeń w Javie – cz.2Zdarzenie Interfejs odbiorcy Komponenty generujące dany typ zdarzenia na

przykładzie komponentów Swinga

ActionEvent ActionListener JButton, JList, JTextField, JMenuItem oraz dziedziczące po nim m.in. JCheckBoxMenu

AdjustmentEvent AdjustmentListener JScrollbar oraz wszystko co implementuje interfejs Adjustable

ComponentEvent ComponentListener Component oraz dziedziczące po nim m.in.: JButton, JCanvas, JCheckBox, JComboBox, Container, JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, JFrame, JLabel, JList, JScrollbar, JTextArea i JTextField

ContainerEvent ContainerListener Container oraz dziedziczące po nim m.in.: JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog i JFrame

FocusEvent FocusListener Component oraz dziedziczące po nim

KeyEvent KeyListener Component oraz dziedziczące po nim

MouseEvent MouseListener Component oraz dziedziczące po nim

MouseEvent MouseMotionListener Component oraz dziedziczące po nim

WindowEvent WindowListener Window oraz dziedziczące po nim: JDialog, JFileDialog, JFrame

ItemEvent ItemListener JCheckBox, JCheckBoxMenu, JList, JComboBox

TextEvent TextListener JTextArea i JTextField

Page 29: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 29

Model zdarzeń w Javie - cz.3Interfejs odbiorcy Metody interfejsu

ActionListener actionPerformed(ActionEvent)

AdjustmentListener adjustmentValueChanged(AdjustmentEvent)

ComponentListener componentHidden(ComponentEvent), componentShown(ComponentEvent), componentMoved(ComponentEvent), componentResized(ComponentEvent)

ContainerListener componentAdded(ContainerEvent), componentRemoved(ContainerEvent)

FocusListener focusGained(FocusEvent), focusLost(FocusEvent)

KeyListener keyPressed(KeyEvent), keyReleased(KeyEvent), keyTyped(KeyEvent)

MouseListener mouseClicked(MouseEvent), mouseEntered(MouseEvent), mouseExited(MouseEvent), mousePressed(MouseEvent), mouseReleased(MouseEvent)

MouseMotionListener mouseDragged(MouseEvent), mouseMoved(MouseEvent)

ItemListener itemStateChanged(ItemEvent)

WindowListener windowOpened(WindowEvent), windowActiavted(WindowEvent), windowDeactivated(WindowEvent)

Page 30: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 30

Model zdarzeń w Javie - cz.4

Interfejs odbiorcy Adapter

ActionListener brak

AdjustmentListener brak

ComponentListener ComponentAdapter

ContainerListener ContainerAdapter

FocusListener FocusAdapter

KeyListener KeyAdapter

MouseListener MouseAdapter

MouseMotionListener MouseMotionAdapter

WindowListener WindowAdapter

Niektóre interfejsy odbiorców, posiadają (jak widać na tabelce w poprzednim slajdzie) wiele metod. Często zdarza się, że potrzebujemy jedną metodę np. mouseClick() z MouseListener-a. Niestety musimy wtedy zaimplementować także pozostałe metody z tego Listnera choć nic nie robią.

Aby rozwiązać ten problem, stworzono adaptery dla interfejsów mających więcej niż jedną metodę. Wystarczy wtedy odziedziczyć po adapterze i przesłonić jedynie te metody, które mają zostać zmienione.

Page 31: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 31

Zasada jednego wątku w Swingu – cz.1

„Gdy komponent Swinga zostanie zrealizowany, cały kod może mieć wpływ lub może zależeć od stanu jaki dany komponent powinien wykonać w wątku obsługującym zdarzenie (z ang. event-dispatching thread)”

Po pierwsze należy zdefiniować co oznaczają dwa terminy: zrealizowany oraz wątek obsługujący zdarzenie.

Zrealizowany oznacza, że metoda paint() mogła być lub może być wywołana dla danego komponentu. Komponent Swinga, który jest głównym oknem może natomiast zrealizowany także przez metody takie jak setVisible(true), czy show(). Gdy okno zostanie zrealizowane, wszystkie komponenty wewnątrz także zostaną zrealizowane. Innym sposobem na zrealizowanie komponentu jest dodanie go do pojemnika (Container), który już został zrealizowany.

Wątkiem obsługującym zdarzenie jest ten wątek, który wykonuje rysowanie oraz obsługę zdarzeń. Na przykład metody paint() czy actionPerformed() są automatycznie wykonywane w tym wątku.

Page 32: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 32

Zasada jednego wątku w Swingu – cz.2

Są jednak wyjątki od powyższej reguły n.p.:

Kilka metod jest „thread – safe”. W API do Swinga, takie metody są oznaczone takim oto tekstem: „This method is thread safe, although most Swing methods are not.  Please see"Using  a Swing Worker Thread"  for more information. „

Co jest „thread – safe”?

metoda repaint()

tworzenie GUI w metodzie init() jako, że przeglądarki nie rysują appletu zanim będzie wywołany init()

tworzenie GUI w main() przez co zostanie zrealizowany w wątku głównym

 

Page 33: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 33

Komponenty Swinga

Więcej o komponentach Swinga można przeczytać można m.in. na stronie: http://java.sun.com/docs/books/tutorial/uiswing/components/component.html

Page 34: AWT i Swing, Layout Managers

AWT i Swing - Jacek Rudzński 34

Eckel Bruce – „Thinking in Java. Edycja Polska. Wydanie 3”

Holzner Steven – „Java 1.2”

www.corewebprogramming.com

java.sun.com

inne źródła internetowe

program Eclipse

własna wyobraźnia

Bibliografia