1 / 44

AWT cd.. Java

AWT cd.. Java. Wykład 4. mgr inż. Michał Misiak. Plan wykładu. Manager rozkładu Zdarzenia w AWT Grafika 2D w AWT Omówienie przykładowych pakietów Wyjątki. Layout Manager. Menadżer rozkładu przypisany jest do każdego kontenera Ustala pozycję i wielkość dla komponentu w oknie

maik
Download Presentation

AWT cd.. Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. AWT cd..Java Wykład 4 mgr inż. Michał Misiak

  2. Plan wykładu • Manager rozkładu • Zdarzenia w AWT • Grafika 2D w AWT • Omówienie przykładowych pakietów • Wyjątki

  3. Layout Manager • Menadżer rozkładu przypisany jest do każdego kontenera • Ustala pozycję i wielkość dla komponentu w oknie • Pomocny przy organizowaniu zawartości okna, które zmienia rozmiar lub jest wyświetlane na różnych systemach • Prosty dla prostych rozkładów, jednakże bardzo ciężko jest projektować programy zawierające wiele elementów w pojedynczym menadżerze rozkładu. • W celu zarządzania złożonymi rozkładami należy: • Używać zagnieżdżonych kontenerów – każdy z własnym layout manager • Używać niewidzialne komponenty oraz opcji menadżerów rozkładów • Pisać własne layout manager • Wyłączyć niektóre layout manager i zarządzać komponentami manualnie. • Wszystkie Layout Manager implementują Layout Manager Interface • add() metod wykorzystywana jest do dodawania komponentu. Pierwszym argumentem jest nazwa strefy, a drugim komponent.

  4. FlowLayout Manager • Domyśłny dla Panel, JPanel, Applet • Zachowanie: • Zmienianie rozmiaru komponentów do ich najlepszego rozmiaru • Umieszczanie komponentów w rzędzie od lewej do prawej od góry do dołu • Wiersze są wyśrodkowane domyślnie • Konstruktor • FlowLayout() – wyśorodkowuje każdy wiersz i utrzymuje 5 px. odstępy pomiędzy komponentami i wierszami • FlowLayout(int alignment) – utrzymuje 5px odstępy w wierszu, ale zmienia wyrównanie w wierszach: FlowLayout.LEFT, FlowLayout.RIGHT, FlowLayout.CENTER • FlowLayout(int alignment, int hGap, int vGap) – pozwala specyfikować wyrównanie w wierszach jak i również odstęp poziomy i poionowy pomiędzy komponentami w [px].

  5. Każdy z komponentów może być włożony do kontenera w jedną z lokalizacji: North South East West Center BorderLayout Manager

  6. Zachowanie Podział okna na równej wielkości prostokąty bazujące na liczbie wierszy i kolumn podanych jako argument. Komponenty umieszczane są w komórkach w kolejności od lewej do prawej od góry do dołu w porządku dodawania do kontenera posiadającego ten rozkład Ignoruje preferowany rozmiar komponentu. Każdy komponent jest skalowany i dopasowywany do komórki Zbyt mała liczba komponentów powoduje pozostawienie wolnego miejsca w postaci białych prostokątów Zbyt wiele komponentów powoduje nieplanowane dodanie nowych kolumn GridLayout() Tworzy pojedynczy wiersz z jedną kolumną zaalokowana dla każdego komponentu. GridLayout(int rows, int cols) Dzieli okno zgodnie z podaną liczbą kolumn oraz wierszy Liczba kolumn lub wierszy może być zero GridLayout(int rows, int cols,int hGap, int vGap) Pozwala na wyspecyfikowanie przestrzeni pomiędzy poszczególnymi komórkami GridLayout

  7. GridBagLayout • Zachowanie • Dzieli okno na komórki, w których komponenty mogą mieć różne rozmiary • Dużo wygodniejsze i bardziej elastyczne niż inne standardowe menadżerzy rozkładów, jednakże dużo trudniejsze w użyciu: • Każdy komponent zarządzany przez GridBagLayout skojarzony jest z GridBagConstraints, który definiowany jest przez: • jak komponent jest rozkładany w wyświetlanym obszarze • w której komórce komponent się rozpoczyna i kończy • jak komponent rozciąga się, kiedy przestrzeń się zwiększa • wyrównanie w komórkach • Java 5 wprowadziła SpringLayout, który jest podobny jednakże bardziej funkcjonalny/elastyczny ale również bardzo złożony. Stosowany przy projektowaniu GUI np. w netbeans.

  8. Użycie GridBagLayout • Ustawienie rozkładu i zachowanie go w zmiennej referencyjnej: • GridBagLayout layout = new GridBagLayout(); • setLayout(layout); • Przygotowanie objektu GridBagConstraints • GridBagConstraints constraints =new GridBagConstraints(); • Ustawienie GridBagConstraints dla jednego komponentu: • constraints.gridx = x1; • constraints.gridy = y1; • constraints.gridwidth = width1; • constraints.gridheight = height1; • Dodanie 1 komponentu do okna uwzględniając jego GridBagConstraints • add(component1, constraints); • Powtórzenie kroków dla pozostałych komponentów

  9. Pola w GridBagConstrains • gridx, gridy • Specyfikuje górny lewy róg komponentu • Najwyższa komórka jest lokowana w (gridx, gridy)=(0,0) • Ustawienie GridBagConstraints.RELATIVE w sytuacji autoinkrementacji kolumn wierszy • GridBagConstraints constraints = new GridBagConstraints(); • constraints.gridx = GridBagConstraints.RELATIVE; • container.add(new Button(„1"), constraints); • container.add(new Button („2"));

  10. Wyłączenie menadżera rozkładu • Zachowanie • Jeśli rozkład jest ustawiony jako null, wówczas komponenty muszą być rozmieszczane i skalowane ręcznie. • Pozycjonowanie i skalowanie komponentów: • component.setSize(width, height) • component.setLocation(left, top) • lub component.setBounds(left, top,width, height)

  11. Wskazówki przy używaniu Layout Manager • Używaj zagnieżdżonych kontenerów • Nie próbuje dopasować na siłę swojego złożonego rozkładu elementów do jednego menadżera rozkładu. Staraj się podzielić projekt w sekcje. • Skorzystaj z Panel jako sekcji wykorzystując do tego jego własny layout manager • Wyłącz menadżera rozkładu dla niektórych kontenerów, w których nie ma zbyt wielu elementów i można zarządzać nimi ręcznie. • Dopasuj puste miejsce wokół komponentów: • Po przez zmianę rozmiaru przestrzeni przydzielonej standardowo przez menadżera rozkładu • Użyj Płótna lub Box (w Swing) jako niewidzialnych elementów oddzielających komponenty

  12. Menadżer rozkładu - podsumowanie • Inne rozkłady: BoxLayout, CardLayout • Domyślne layout managers • Dla apletu i panelu: FlowLayout • Dla okienka i dialog BorderLayout • Menadżer rozkładu respektuje preferowany rozmiar komponentu w różny sposób • GridBagLayout jest najbardziej skomplikowanym rozkładem ale jednocześnie najbardziej funkcjoanlnym/elastycznym • GridBagConstraints wykorzstywany w przypadku konieczności wyspecifikowania rozkładu dla każdego komponentu • Złożone rozkłady mogą być uproszczone przez zastosowanie zagnieżdżonych kontenerów • W AWT jako element odzielający wykorzystuje się Canavas a w Swing Box

  13. Zdarzenia (Events) • Cel: potrzeba dowiedzenia się o czymś, co wydarzyło się poza obiektem. • Zdarzenie (Event) – nośnik informacji o zajściu określonej sytuacji • Przykład 1: użytkownik wciska przycisk na ekranie • Przykład 2: Przyjście pewnej porcji informacji na port serwera (aplikacja web chat) • Obiekt, w którym pojawiło się zdarzenie – generator zdarzeń (event generator). Np. przycisk na ekranie. • Obiekt, który wykona pewne zadanie po otrzymaniu zdarzenia – event handler. Dla wybranego zdarzenia może być wiele event handlers, które mogą wykonać różne zadania.

  14. Mechanizm obsługi zdarzeń • Archaiczne podejście do obsługi zdarzeń: polling. Przebieganie stanu obiektów w pętli. Podejście absorbujące dużą ilość zasobów (olbrzymia pętla). • Generator zdarzeń udostępnia usługę rejestracji – pamięta, do których event handlers powinien przekazać zdarzenia • Rejestracja event handlers u generatora zdarzeń • Wykorzystanie diagramów MSC do modelowania systemów sterowanych zdarzeniami. • Message Driven Application - Zastosowania w systemach rozproszonych.

  15. Generatory zdarzeń udostępnia JVM. Programista implementuje wyłączenie zachowanie event handlers – tzw. nasłuchiwaczy (listeners) . W razie wyszukanych potrzeb programista może jednak zaimplementować własne generatory zdarzeń. Po implementacji event handlers należy zarejestrować go u właściwego generatora zdarzeń Przykład: Java Button Generuje zdarzenia ActionEvents Nasłuchiwacz rejestruje się u Java Button po przez wywołanie metody addActionListner z parametrem wskazującym kto będzie nasłuchiwał. Metoda ta generuje wiadomość addActionListener Java Button pamięta, kto się u niego zarejestrował (automatyczny mechanizm dostarczany przez JVM) W momencie wystąpienia zdarzenia w Java Button, Java Button generuje wiadomość actionPerformed, do każdego z zarjestrowanych nasłuchiwaczy. Listner powinien mieć zaimplementowaną metodę actionPerformed, która zostanie wywołana przez JVM w momencie otrzymania wiadomości Mechanizm obsługi zdarzeń w Javie

  16. Mechanizm obsługi zdarzeń diagram MSC Button Button = new Button(„Klik!"); Button.addActionListener(new Nasluchiwacz()); // rejestracja class Nasluchiwacz implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println(„nasinieto przycisk"); // wykonanie zadania } }

  17. public boolean handleEvent(Event e) e – parametr z referencją na zdarzenie, które powstało Ważna jest wartość zawracana przez handleEvent. Informuje JVM, czy zdarzenie zostało w pełni obsłużone Zdarzenie propaguje w górę drzewa, do momentu, kiedy nie zostanie poprawnie obsłużone Przykład 2 – hierarchia generowania zdarzeń przez komponenty. Źródło: http://www.javaworld.com/javaworld/jw-08-1996/jw-08-event.html?page=1

  18. W przypadku konieczności obsłużenia wybranych zdarzeń można skorzystać z funkcji pomocniczych Metoda pomocnicza zwraca wartość false w przypadku, gdy zdarzenie nie zostanie w pełni obsłużone Przykład 3 action(Event evt, Object what) gotFocus(Event evt, Object what) lostFocus(Event evt, Object what) mouseEnter(Event evt, int x, int y) mouseExit(Event evt, int x, int y) mouseMove(Event evt, int x, int y) mouseUp(Event evt, int x, int y) mouseDown(Event evt, int x, int y) mouseDrag(Event evt, int x, int y) keyDown(Event evt, int key) keyUp(Event evt, int key) Metody pomocnicze do obsługi zdarzeń

  19. Window Events WINDOW_DESTROY (201) WINDOW_EXPOSE (202) WINDOW_ICONIFY (203) WINDOW_DEICONIFY (204) WINDOW_MOVED (205) Keyboard Events KEY_PRESS (401) KEY_RELEASE (402) KEY_ACTION (403) KEY_ACTION_RELEASE Mous Events MOUSE_DOWN 501 MOUSE_UP 502 MOUSE_MOVE 503 MOUSE_ENTER504 MOUSE_EXIT505 MOUSE_DRAG Różne zdarzenia ACTION_EVENT 1001 LOAD_FILE 1002 SAVE_FILE 1003 GOT_FOCUS 1004 LOST_FOCUS Przykładowy zestaw zdarzeń Przykłady zdarzeń Źródło: http://www.unix.org.ua/orelly/java/javanut/figs/jn2_2001.gif

  20. Klasa Event • longwhenChwila, w które zdarzenie wystąpiło. • int idTyp zdarzenia (patrz następny slajd) • int xWspółrzędna X określająca miejsce, w którym zdarzenie się pojawiło w odniesieniu do komponentu, który jest aktualnie przetwarzany. Początkowa wartość x jest to górny lewy róg. • int yWspółrzędna X określająca miejsce, w którym zdarzenie się pojawiło w odniesieniu do komponentu, który jest aktualnie przetwarzany. Początkowa wartość x jest to górny lewy róg. • int keyDla zdarzeń pochodzących z klawiatury. Jest to kod wciśniętego klawisza. Przeważnie jest to wartość zapisana w postaci unicode. • int modifiers arytmetyczna reprezentacja wartości SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK. Wartość zostaje zmieniona odpowiednio dla zmiany stanu klawiszy shift, control, meta, alt. • int clickCountLiczba kliknięć myszy. Pole te jest istotne wyłącznie przy zdarzeniu MOUSE_DOWN. • ObjectargZależny od zdarzenia argument. Dla obiektów Button, object jest ciągiem znaków, który zawiera jego etykietę.

  21. Przykład 1. Aplikacja obsługująca zdarzenia Źródło: http://www.javaworld.com/javaworld/jw-08-1996/jw-08-event.html

  22. Java 2D • Java 2D API umożliwia pracę z obrazami, tekstem i grafiką jako rozszerzenie AWT • Zakres dostarczanej funkcjonalności: • Ujednolicony model renderingu dla różnych rodzajów wyświetlaczy i drukarek (user space) • Duży zbiór różnych podstawowych kształtów geometrycznych takich jak: prostokąty, krzywe, elipsy jak i również mechanizm do renderowania dowolnych kształtów. • Mechanizm dla wykrywania kilknięć na kształtach, tekście i obrazkach • Sterowanie sposobem rednerowania zachodzących na siebie obiektów • Zarządzanie kolorami • Wsparcie dla wydruków złożonych dokumentów • Sterowanie jakością renderowanych obiektów (anty-aliasing)

  23. Java 2D rozróżnia dwa układy współrzędnych Przestrzeń użytkownika (user space) – miejsce, w którym obiekty są specyfikowane Przestrzeń urządzeń (device space) – układ współrzędnych związanych z urządzeniem, na którym ma zostać wyświetlona wyspecyfikowana grafika np. monitor, drukarka, Układ współrzędnych Typem dla x i y jest integer. Wspierany jest również float i double. x (0,0) y Przy transformacji przestrzeni użytkownika do przestrzeni urządzenia punktem odniesienia jest lewy górny róg. Wartości x, y rosną odpowiednio w dół i w prawo

  24. Java udostępnia wspólny mechanizm modelowania grafiki dla różnych urządzeń W przypadku konieczności wyświetlenia/wykreślenia danego kształtu wywoływane są automatycznie metody paint() lub update() z kontekstem graficznym Graphics. Metody te zawiera każdy obiekt rozszerzający Component. Pakiet java.awt.Graphics2D oferuje następujące możliwości: rysowanie podstawowych kształtów geometrycznych z uwzględnieniem krawędzi (metody draw) wypełnianie kształtów kolorem lub określonym wzorem (metody fill) rysowanie tekstu (drawString). Określenie czcionki wskazuje w jaki sposób ma być danych tekst przekształcony w obiekt graficzny, który jest wypełniony kolorem lub wzorem rysowanie obrazków (metoda drawImage) Java 2D rendering

  25. Metody do rysowania można podzielić na dwie grupy Metody definiujące kształt (metody draw, fill) Metody określające w jaki sposób ten kształt ma być narysowany – zmiana atrybutów kontekstu (Graphics) W celu użycia dodatkowych funkcjonalności oferowanych przez Java 2D należy rzutować obiekt typu Graphics na Graphics2D Możliwość modyfikacji atrybutów związanych z określonym kontekstem modyfikacja szerokości linii/krawędzi rysunku zmiana sposobu łączenia linii/krawędzi przekształcanie rysunku: obracanie skalowanie lub przycinanie określanie koloru i wzoru wypełnienia kształtu określenie w jaki sposób obiekty są ze sobą skomponowane określanie czcionki definiowanie współczynnika jakość/wydajność (aliasing) Metody wykorzystywane przy rysowaniu w Java 2D public void paint (Graphics g) { Graphics2D g2 = (Graphics2D) g; ... }

  26. public void paint(Graphics g) { // ustawianie atrybutów pędzela g.setColor(someColor); g.setFont(someLimitedFont); // kreślenie kształtów g.drawString(…); g.drawLine(…) g.drawRect(…); // outline g.fillRect(…); // solid g.drawPolygon(…); // outline g.fillPolygon(…); // solid g.drawOval(…); // outline g.fillOval(…); // solid //etc… } public void paintComponent(Graphics g) { // czyszczenie obrazu super.paintComponent(g); // rzutowanie kontekstu na konteskt Java2D Graphics2D g2d = (Graphics2D)g; // Set pen parameters g2d.setPaint(fillColorOrPattern); g2d.setStroke(penThicknessOrPattern); g2d.setComposite(someAlphaComposite); g2d.setFont(anyFont); g2d.translate(…); g2d.rotate(…); g2d.scale(…); g2d.shear(…); g2d.setTransform(someAffineTransform); // definiowanie własnego kształtu SomeShape s = new SomeShape(…); // rysowanie kształtu g2d.draw(s); // outline g2d.fill(s); // solid } Java 2D vs AWT

  27. Figury podstawowe - rysowanie (1) • Java 2D API udostępnia podstawowe kształty: linia, punkt, prostokąt, etc… w pakiecie java.awt.geom • Klasy reprezentujące kształty implementują interfejs • Shape: pozwala opisać krzywą • PathIterator: określa w jaki sposób są pobierane elementy krzywej. • Należy uzyskać obiekt typu Graphics2D • Każda funkcja wymaga zdefiniowana punktu zaczepienia • np. java.awt.Graphics.drawLine(int x1, int y1, int x2, int y2). • (x1, y1) początek linii, a (x2, y2) koniec linii. • Jeśli chcemy narysować kształt z Java 2D możemy użyć funkcji draw • g2.draw(new Line2D.Double(x1, y1, x2, y2)); • lub Line2D.Float(float X1, float Y1, float X2, float Y2) ; • lub Line2D.Float(Point2D p1, Point2D p2);

  28. Krzywe kwadratowe: QuadCurve2D Metoda setCurve – pozwala na określenie dwóch punktów końcowych oraz punktu sterującego krzywą Krzywe sześcienne: CubicCurve2D Kawałek parametryzowanej krzywej sześciennej Metoda setCurve analogiczna do metody setCurve z krzywej kwadratowej poszerzona o drugi punkt kontrlony Figury podstawowe - rysowanie (2) • CubicCurve2D q = • new CubicCurve2D.Float(); • q.setCurve(0, 0, 50, 50, 10,100, 400, 0); • g2d.draw(q); • QuadCurve2D q = • new QuadCurve2D.Float(); • q.setCurve(0, 0, 200, 600, 400, 0); • g2d.draw(q);

  29. Klasa Rectangle dziedziczy po RectangularShape i implementuje interfejs Shape oraz kilka dodatkowych metod pozwalających na określenie położenia, rozmiaru, środka, etc… Klasa RoundRectangle definiuje prostokąt z zaokrąglonymi wierzchołkami. Do wyspecyfikowania prostokąta wymagane są: położenie, wysokość, szerokość, wartość wysokości kąta zaokrąglenia, wartość szeorkości kąta zaokrąglenia Figury podstawowe - rysowanie (3) g2.draw(new RoundRectangle2D.Double(x, y, rectwidth, rectheight, 10, 10)); g2.draw(new rectangle2D.Double(x, y, rectwidth, rectheight));

  30. Elipsa – krzywa zdefiniowana w typie Ellipse2d Do narysowania wymagana jest położenie oraz wysokość i szerokość Łuk – część elipsy. Zdefiniowana w klasie Arc2D. Do opisania potrzebne jest: położenie, wysokość i szerokość prostokąta w który jest wpisana elipsa, początek i koniec kąta, typ zamknięcia. Typy zamknięcia: OPEN, PIE, CHORD Figury podstawowe - rysowanie (4) g2.draw(new Arc2D.Double(x, y, rectwidth, rectheight, 90, 135, Arc2D.OPEN)); g2.draw(new Ellipse2D.Double(x, y, rectwidth, rectheight));

  31. Do rysowania własnych kształtów została stworzona klasa GeneralPath. GeneralPath implementuje interfejs Shape i pozwala rysować krzywe, które złożone są z podstawowych kształtów: linie, krzywe sześcienne i kwadratowe, Metody do kształtowania GeneralPath moveTo(float x, float y) – przesuń aktualny punkt ścieżki do danego punktu lineTo(float x, float y) – dodaj kawałek linii do obecnej ścieżki quadTo(float ctrlx, float ctrly, float x2, floaty2) – dodaj krzywą sześcienną do aktualnej ścieżki. curveTo(float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x3, floaty3) – dodaj krzywą sześcieną do aktualnej ścieżki closePath() – zamknij aktualną ścieżkę. Własne kształty int x2Points[] = {0, 90, 0, 90}; int y2Points[] = {0, 40, 40, 0}; GeneralPath lamana = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length); lamana.moveTo (x2Points[0], y2Points[0]); for (int index = 1; index < x2Points.length; index++) { lamana.lineTo(x2Points[index], y2Points[index]); }; g2.draw(lamana);

  32. Wygląd kształtów możemy modyfikować po przez: wypełnienie (filling) – wypełnianie kształtu określonym kolorem, gradientem lub wzorem określanie krawędzi (stroking) – krawędź może mieć grubość, kolor, styl Ażeby narysować kształty należy zmienić przed wywołaniem metody draw ustawienia kontsktu Graphics2D. Określenie grubości i rodzaju krawędzi (stroking) oraz wypełnienia Zaokrąglony prostokąt z przerywaną linią final static float przer1[] = {10.0f}; final static BasicStroke przer = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, przer1, 0.0f); g2.setStroke(przer); g2.draw(new RoundRectangle2D.Double(x, y, rectWidth, rectHeight, 10, 10)); Gradient na elpisie czerwon2bialy = new GradientPaint(0,0, color.RED,100, 0,color.WHITE); g2.setPaint(czerwony2bialy); g2.fill (new Ellipse2D.Double(0, 0, 100, 50));

  33. Style linii są definiowane przez atrybut krawędzi dla danego kontekstu Graphics W celu ustawienia wybranego stylu linii należy utworzyć instancje BasicStroke i ustawić dla kontekstu Graphics za pomocą funkcji setStroke. Metoda draw narysuje kształt zgodnie z ustawioną definicją linii Właściwości stylu linii: Grubość linii Rodzaj połączenia linii: JOIN_BEVEL, JOIN_MITER, JOIN_ROUND Styl zakończenia linii: CAP_BUTT, CAP_ROUND, CAP_SQUARE Przerywanie linii. Ażeby zdefiniować przerywanie linii należy określić długość części widocznej i niewidocznej i umieścić w tablicy Style linii

  34. Wzory wypełnienia • Wzory wypełnienia są definiowane jako atrybut procesu malowania • Wybranie wzoru wypełnienia wymaga utworzenia obiektu implementującego interfejs Paint oraz ustawienia go dla wybranego kontekstu graficznego Graphics za pomocą metody setPaint • Trzy klasy implementują interfejs Paint: • Color, • GradientPaint – określony przez punkt, w którym rozpoczyna się dany kolor oraz punkt, w którym kończy się dany kolor. • TexturePaint – definiowany przez BufferImage. Należy wskazać obraz oraz rozmiar prostokąta z obrazem, który będzie powielany

  35. Praca z obrazami • Obrazy są obiektami, które posiadają wysokość i szerokość oraz własny układ współrzędnych • Możliwe akcje do wykonania na obrazach: • Ładowanie zewnętrznych obrazów w formatach GIF, PNG, JPEG do wewnętrznej reprezentacji obrazu w Java 2D • Bezpośrednie tworzenie obrazu i jego renderowanie • Bezpośrednie rysowanie zawartości obrazu na powierzchni przeznaczonej do rysowania • Zapisywanie obrazów w plikach w następujących formatachGIF, PNG, JPEG.

  36. Klasy związane z obrazami • java.awt.Image – jest to klasa bazowa dla pozostałych klas związanych z obrazami przechowująca informację o obrazie jako tablica pikseli • java.awt.image.BufferdImage – klasa dziedzicząca po Image umożliwiająca bezpośrednią pracę nad obrazem (np. ustawianie kolorów pikseli). Aplikacje mogą bezpośrednio tworzyć instancję tej klasy

  37. Przeprowadzane operacje na obrazie realizowane są bezpośrednio w pamięci Udostępnia metody do przechowywania, interpretacji i uzyskiwania danych dotyczących pikseli Może być renderowany przez Graphics lub Graphcis2D BufferedImage określony jest przez: Raster Model Koloru (ColorModel). Funkcje Raster’a: Reprezentuje układ współrzędnych związanych z obrazem Zarządza danymi dot. obrazu bezpośrednio w pamięci Udostępnia mechanizm tworzenia różnych podobrazów z pojedynczego bufora z danymi o obrazie Oferuje metody pozwalające na dostęp do poszczególnych pikseli obrazu Klasa BufferedImage

  38. Java 2D umożliwia ładowanie obrazu z zewnętrznego formatu za pomocą Image I/O API. Image I/O API obsługuje następujące formaty: GIF, PNG, JPEG, BMP, WBMP Rozpoznanie typu kodowania obrazu realizowane jest automatycznie Wczytywanie obrazu może być realizowane również nie tylko z pliku, ale także ze strumienia danych Więcej informacji na temat Image I/O API: http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/imageio_guideTOC.fm.html Przykład wczytania obrazu BufferedImage img = null;try {img = ImageIO.read(new File("strawberry.jpg")); } catch (IOException e) {} Czytanie/ładowanie obrazu

  39. Rysowanie obrazów • Do rysowania obrazów w danym położeniu służy funkcja: • boolean Graphics.drawImage(Image img, int x, int y, ImageObserver observer); • x, y – określają pozycję obrazu • observer informuje aplikację o fakcie załadowania obrazu w przypadku asynchronicznym. Nie jest wymagany dla BufferedImage • Obraz jest rysowany 1:1 w przestrzeni użytkownika (user space) • Przykład metody umożliwiającej rysowanie części obrazu, skalowanie oraz stosowanie filtrów: • boolean Graphics.drawImage(Image img, int dstx1, int dsty1, int dstx2, int dsty2, int srcx1, int srcy1, int srcx2, int srcy2, ImageObserver observer); • src – reprezentuje obszar, który będzie skopiowany i odrysowany • dst – określają obszar, w którym będą przerysowane dane z src • Rozmiary obrazka obliczane są analogicznie dla wysokości i szerokości w następujący sposób: srcx2-scrx1

  40. Filtrowanie danego obrazka polega na utworzeniu nowego z użyciem pewnego algorytmu modyfikującego poszczególne piksele (np. modyfikacja kanału alpha, czyli przeźroczystości) void Graphics2D.drawImage(BufferedImage img, BufferedImageOp op, int x, int y) BufferedImageOp – klasa implementująca określony filtr Przykładowe filtry: ConvolveOp. Każdy z wyjściowych pikseli jest obliczany z pośród go otaczających. Może być wykorzystany do rozmywania lub wyostrzania obrazów. AffineTransformp. Filtr ten mapuje piksele ze źródłowej pozycji do innego położenia docelowego dokonującą transformacji na lokalizacji pikseli LookupOp. Filtr dokonuje zamiany kolorów na podstawie dostarczonej tablicy kolorów. RescaleOp. Filtr mnoży wartości opisujące kolor przez ten sam współczynnik. Może być wykorzystany do rozjaśniania lub przyciemnia obrazu lub zmiany przeźroczystości. Stosowanie filtrów

  41. Tworzenie i rysowanie obrazów • Dowolny obraz może być utworzony z wykorzystaniem następujący konstruktorów: • new BufferedImage(width, height, type) – konstruuje BufferedImage dla wybranego predefiniowanego typu obrazu of • new BufferedImage(width, height, type, colorModel) – konstruuje BufferedImage dla wybranego typu obrazu: TYPE_BYTE_BINARY lub TYPE_BYTE_INDEXED. • new BufferedImage(colorModel, raster, premultiplied, properties) – konstruuje nowy BufferedImage z określonym Modelem Kolorów i Rastrem. • Obraz może być stworzony nie tylko na ekranie. Obraz może być rozważany w kontekście powierzchni po której można rysować. Do tego celu służy metoda createGraphics() • BufferedImage off_Image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = off_Image.createGraphics();

  42. Podwójne buforowanie • Obraz tworzony w pamięci może być wykorzystany do budowy mechanizmu podwójnego buforowania. • Mechanizm podwójnego buforowania zmniejsza użycie zasobów dzięki czemu animacja jest płynna • W tym przypadku przetworzenie obrazu realizowane w pamięci po czym obraz jest kopiowany na ekran • Java 2D umożliwiających dostęp do mechanizmów przyśpieszających obróbkę obrazów w buforze: • Metoda getCapabilities pozwala określić, czy wyświetlanie obrazu jest przyśpieszone (accelerated). • Metoda setAccelerationPriority pozwala na ustawienie współczynnika określającego jak ważne jest przyśpieszenie wyświetlania danego obrazu • Metoda getAccelerationPriority zwraca informacje na temat priorytetu przyśpieszenia wyświetlania obrazu.

  43. Zapisywanie obrazu • Zapisanie obrazu na dysku z BufferedImage z użyciem Image I/O API • static boolean ImageIO.write(RenderedImage im,String formatName,File output) throws IOException • Metoda ImageO.write woła plug-in dla danego typu obrazka, które nazwa przekazywana jest w parametrze formatName. Dzięki temu można łatwo rozszerzyć listę obsługiwanych formatów. • Standardowo obsługiwane formaty: JPEG, PNG, GIF, BMP i WBMP • Metoda String writerNames[] = ImageIO.getWriterFormatNames(); zwraca listę wspieranych formatów przez JRE try { BufferedImage bi = getMyImage(); // zapisanie obrazu File outputfile = new File("saved.png"); ImageIO.write(bi, "png", outputfile); } catch (IOException e) { }

  44. Właściwości obrazów

More Related