26
GUI Graficzny Interfejs Użytkownika cz. 1 mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

GUI –Graficzny Interfejs Użytkownika cz. 1 · lub na sam dół stosu okien. void setUndecorated(boolean undecorated) –ramka nie zawiera żadnych dodatków (pasek tytuł, przycisk

Embed Size (px)

Citation preview

GUI – Graficzny Interfejs Użytkownika cz. 1

mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Java 1.0 – Abstract Window Toolkit (AWT)◦ Pakiet definiujący podstawowe komponenty. graficzne oraz

obsługę ich zachowań.◦ Ubogie możliwości graficzne i interaktywne komponentów.◦ Wykorzystanie natywnych narzędzi i mechanizmów tworzenia GUI

danej platformy systemowej.◦ Od początku zawarty w JDK.

Java 1.1, 1.2 – Swing◦ Elementy są „rysowane”. Rola systemu operacyjnego zostaje

zredukowana do wyświetlania okien i rysowania w nich.◦ Wygląd niezależny od platformy systemowej.◦ Nieco dłuższy czas renderowania. ◦ Mniej podatny na błędy występujące w systemie operacyjnym.

Java 5.0, 6.0 – poprawa i odświeżenie styli Metal, Windows, GTK (schematy kolorów, pulsujące przyciski przewijania itp.).

Której biblioteki zatem używać?

http://www.javootoo.com/index.html

http://www.youtube.com/watch?v=KHNHyK5J3Q8

Komponenty tworzone są za pomocą wyrażenia newwywołującego odpowiedni konstruktor klasy komponentu z ewentualnymi argumentami określającymi jego początkowy stan lub wygląd.

Komponenty mają właściwości, które można ustawiać lub pobierać za pomocą dostępnych akcesorów i modyfikatorów.

Wiele właściwości reprezentowanych jest przez obiekty danych klas (np. za krój pisma odpowiada klasa Font).

Komponenty mogące zawierać inne komponenty to tzw. kontenery. Można do nich dodawać również inne kontenery.

Każdy kontener ma określony rozkład (layout) komponentów. Aplikacja komunikuje się z użytkownikiem za pomocą jednego

lub wielu okien. Okna AWT są już kontenerami, natomiast w przypadku Swing’u tą role pełni tzw. contentPane.

Interakcja użytkownika z aplikacją odbywa się na zasadzie obsługi zdarzeń.

Wszystkie komponenty Swingu, oprócz kontenerów najwyższego poziomu są kontenerami lekkimi.

Wszystkie komponenty AWT są tzw. kontenerami ciężkimi.

Komponent ciężki – komponent realizowany przez użycie graficznych bibliotek GUI systemu operacyjnego.

Komponent lekki – komponent rysowany za pomocą odpowiedniego kodu Javy w obszarze innego komponentu ciężkiego znajdującego się wyżej w hierarchii dziedziczenia.

Możliwe jest umieszczanie w jednym kontenerze obu typów komponentów. Nie jest to zalecane.

Podstawowe właściwości wszystkich komponentów określa klasa Component.

Metody dla wszystkich kontenerów określa klasa Container.

Właściwości komponentów lekkich Swingu określa klasa JComponent.

Okno najwyższego poziomu (nie zawarte w żadnym innym oknie nazywane jest w Javie ramką. W AWT ramka implementowana jest przez obiekty klasy Frame, natomiast w przypadku swingu jest to JFrame.

Dwa sposoby tworzenia ramek

void setLocation(int x, int y) – przenosi komponent na nową pozycję. Górny-lewy róg komponentu określają parametry x, y. Wartość (0, 0) oznacza lewy górny róg ekranu.

void setBounds(int x, int y, int width, int height) – przesuwa i skaluje komponent. Górny-lewy róg komponentu określają parametry x, y, natomiast pozostałe dwa określają nową szerokość i wysokość ramki.

void setLocationByPlatform(boolean locationByPlatform) – pozostawia decyzję o położeniu okna systemowi operacyjnemu.

void setIconImage(Image image) – ustawia ikonę wyświetlaną w pasku tytułu, zasobniku systemowym itp.

void setTitle(String title) – ustawia tekst w pasku tytułu. void setResizable(boolean resizable) – ustawia możliwość zmiany

rozmiaru ramki void pack() – ustawia wielkość ramki tak, aby pomieściły się w niej

wszystkie dodane komponenty. void toFront(), toBack() – przenosi okno przed wszystkie pozostałe okna

lub na sam dół stosu okien. void setUndecorated(boolean undecorated) – ramka nie zawiera żadnych

dodatków (pasek tytuł, przycisk zamykający. void setExtendedState(int state) – ustawia stan rozszerzonego okna np.

na Frame.MAXIMIZED_BOTH.

Dodawanie komponentów:

Container contentPane = frame.getContentPane();

Component c = new …

contentPane.add(c);

Lub skrótowo [od Java 5.0]:

frame.add(c);

Najprościej zdefiniować klasę rozszerzającą JComponent i zredefiniować w niej metodę paintComponent(Graphics g).

Obiekt typu Graphics zawiera ustawienia dotyczące rysowania obrazków lub tekstu (np. krój czcionki), oraz udostępnia szereg przydanych przy rysowaniu metod.

Za każdym razem, gdy okno musi być ponownie narysowane, metoda obsługi zdarzeń informuje o tym komponent – wywoływana jest metoda paintComponentdla wszystkich komponentów. Nie należy jej wywoływać ręcznie.

Aby wymusić ponowne rysowanie ekranu należy użyć metody repaint();

void repaint(int x, int y, int width, int height) – powoduje jak najszybsze przerysowanie podanego obszaru komponentu.

Można również dziedziczyć po klasie JPanelzamiast JComponent.

Od Javy 1.0 klasa Graphics udostępnia metody rysujące różne kształty dwuwymiarowe (linie, protokąty, elipsy), natomiast jej możliwości są bardzo ograniczone.

Java 1.2 wprowadza bibliotekę Java2D. Aby narysować figurę za pomocą tej biblioteki należy utworzyć obiekt klasy Graphics2D.

Klasa Graphics2D jest podklasą klasy Graphics. Java2D, daje nam szereg gotowych kształtów rozszerzających

klasę Shape, znajdziemy tam:◦ Ellipse2D◦ Rectangle2D◦ Line2D

W przeciwieństwie do Graphics 1.0, w której to współrzędne były definiowane jako liczby całkowite, Java2D używa współrzędnych zmiennoprzecinkowych.

float x = 1.2; //Błąd. Literał to wartość typu doublefloat x = 1.2F; //OK. Jawna konwersja na typ float

Proszę pamiętać o dodaniu:import java.awt.*;import java.awt.geom.*;

Każda klasa reprezentująca figurę posiada 2 implementacje:◦ z pojedynczą precyzją np. Rectangle2D.Float◦ z dokładnością double np. Rectangle2D.Double

Tworząc obiekt klasy Rectange2D.Float wartości określające współrzędne należy podawać jako float. W przypadku klasy Rectangle2D.Double współrzędne muszą być typu double.

Rectangle2D .Float floatProst = new Rectangle2D.Float(10F, 12F, 25F, 20F);Rectangle2D.Double doubleProst = new Rectangle2D.Double (10, 12, 25,

20);

Lub krócej

Rectangle2D floatProst = new Rectangle2D.Float(10F, 12F, 25F, 20F);Rectangle2D doubleProst = new Rectangle2D.Double(10, 12, 25, 20); Podobnie jest w przypadku wszystkich innych figur.

include javax.awt.geom.*

Rysowanie elipsy odbywa się podając dane odnośnie opisanego na niej prostokąta:

Ellipse2D e = new Ellipse2D.Double(120, 220, 100, 40); Często jednak dane są punkty krańcowe (lewy górny, prawy dolny). Należy

zastosować wówczas metodę:Rectangle2D rect = new Rectangle2D.Double();rect.setFrameFromDiagonal(px, py, qx, qy) Lub co lepsze skorzystać z klasy Point2D:Point2D p = new Point2D.Double(10, 20);Point2D q = new Point2D.Double(30, 50);Rectangle2D rect = new Rectangle2D.Double();rect.setFrameFromDiagonal(p, q); W przypadku elipsy często znane są środek, szerokość i wysokość opisanego na

niej prostokąta, a nie jego rogi. Istnieje metoda setFramFromCenter, ale wymaga podania przynajmniej jednego rogu. Zatem elipsę tworzy się następująco:

Ellipse2D el = new Ellipse2D.Double(srodekX – szerokosc/2, srodekY – wysokosc/ 2, wysokosc, szerokosc);

Linię tworzy się analogicznie:Line2D l = new Line2D.Double(poczatek, koniec); //początek i koniec to Point2D LubLine2D l = new Line2D.Double(startX, startY, koniecX, koniecY);

Stare podejście

Nowe podejście

Dlaczego nowe jest lepsze?

double getX() double getY()Zwracają współrzędną x lub y lewego górnego rogu prostokąta. double getWidth() double getHeight()Zwracają szerokość lub wysokość prostokąta. double getMinX() double getMinY() double getMaxX() double getMaxY()Zwracają największą lub najmniejszą współrzędną prostokąta double getCenterX() double getCenterY()Zwracają współrzędną x-ową lub y-ową punktu środkowego

prostokąta.

Aby zmienić kolor aktualnie rysowanych figur należy użyć metody voidsetPaint(Paint paint).Przykładowo:

g2d.setPaint(Color.red);g2d.drawString(„Czerwony tekst”, 20, 20); Figury zamknięte można wypełnić dowolnym kolorem używając metody void

fill(Shape s):Ellipse2D circle = new Ellipse2D.Double(10, 10, 380, 380); //czerwone kołog2d.setPaint(Color.RED);g2d.fill(circle); Aby użyć kilka kolorów należy wybrać kolor, zastosować metodę draw lub fill,

wybrać inny kolor i ponownie zastosować metodę draw lub fill. Niestandardowy kolor można zdefiniować tworząc obiekt klasy Color oraz

podając wartości 3 składowych RGB z zakresu 0 – 255:g2d.setPaint(new Color(0, 255, 255));g2d.drawString(„Witaj świecie”, 45, 45); Do ustawienia koloru tła służy metoda void setBackground(Color c) z klasy

Component:JFrame f = new JFrame("Elo pamelo");f.getContentPane().setBackground(Color.BLUE);f.setVisible(true);Sam zapis f.setBackground(Color.BLUE) będzie widoczny tylko przy rozciąganiu bo

to nie ta warstwa ramki!

Można skorzystać z predefiniowanych nazw kolorów aktualnie używanych do rysowania elementów systemu użytkownika:

p.setBackground(SystemColor.window)

Aby sprawdzić jakie czcionki są dostępne w danym komputerze należy wywołać metodę getAvailableFontFamilyNames() z klasy GraphicsEnvironment:

String[] nazwy = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

for (String nazwa : nazwy)System.out.println(nazwa);

W bibliotece AWT występuje 5 odgórnie zdefiniowanych nazw czcionek:◦ SansSerif◦ Serif◦ Monospaced◦ Dialog◦ DialogInput

Czcionki te zawsze są zamieniane na te które znajdują się w systemie. Aby napisać znak daną czcionką należy utworzyć obiekt klasy Font

podając przy tym nazwę, styl czcionki i jej rozmiar w punktach drukarskich:

Font f1 = new Font(„Serif”, Font.BOLD, 14);

Dostępne są cztery style pisma:◦ Font.BOLD◦ Font.ITALIC◦ Font.PLAIN◦ Font.BOLD | Font.ITALIC

Przykład działania:Graphics2D g2d = (Graphics2D) g; Font f = new Font("Serif", Font.BOLD, 18);g2d.setFont(f);g2d.drawString("Test czcionek", 30, 30); Wycentrowanie tekstu:FontRenderContext ctx = g2d.getFontRenderContext();Font f = new Font("Serif", Font.BOLD, 18);Rectangle2D granice = f.getStringBounds(napis, ctx);

Należy dodać:import java.awt.font.*;

Linia bazowa – linia, na której opiera się dolna część litery. Wydłużenie górne – odstęp dzielący linię bazową i linię

górną pisma. Wydłużenie dolne – odległość pomiędzy linią bazową a linią

dolną pisma. Interlinia – odstęp pomiędzy wydłużeniem dolnym jednej

linii, a wydłużeniem górnym następnej linii. Wysokość czcionki – to odległość między następującymi po

sobie liniami bazowymi i jest równa sumie wydłużenia dolnego, interlinii i wydłużenia górnego.

Obrazy znajdujące się w plikach na dysku bądź pochodzące z internetu można w łatwy sposób wyświetlić na obiektach typu Graphics.

Jeśli obraz jest zapisy na dysku:String nazwa_obrazu = "C:\test.jpg";Image img = ImageIO.read(new File(nazwa_obrazu)); Jeśli obraz pobieramy z zasobu sieciowego:String lacze = "www.tomaszx.pl/test.jpg";Image img = ImageIO.read(new URL(lacze)); Należy pamiętać o obsłużeniu odpowiednich wyjątków

(IOException generowany przez metodę read() jeśli obraz nie jest dostępny, oraz MalformedUrlException).

Następnie można wyświetlić obraz korzystając z metody drawImage z klasy Graphics:

g2d.drawImage(img, 10, 10, null); Jeśli rysujemy dany obraz więcej niż raz można skorzystać z

przydatnej metody copyArea.

Należy dołączyć:import javax.imageio.ImageIO;import java.io.File;import java.net.URL;