Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME
Što je izbornik? – klase izbornika – kreiranje izbornika –
primjer izbornika – događaji vezani uz izbornike – izborničke kratice – padajući
izbornici (popup menus) – slike – kamo staviti slike? – učitavnje slika –
crtanje slika – uporaba povratne vrijednosti metoda drawImage() – primjer
crtanja slika – promjena veličine slike – ustanovljavanje veličine slike – paket
java.awt.image – Sučelja ImageProducer, ImageObserver, ImageConsumer – sučelje
ImageConsumer – čekanje na učitavanje slike – prekrivanje metode imageUpdate() –
što je zapravo slika? – operator << - kreiranje slika – primjer kreiranja
slika – metoda getRGB() – pretapanje boja – filtriranje slika – klasa
RGBImageFilter – primjer plavog filtra – primjer filtra sivih tonova – filtri
koji ovise o položaju – filtri koji ovise o adjungiranim pixelima – audio –
kontinuirana izvedba
Java omogućuje postavljanje izbornika na frameove (dijalozima se izbornici ne mogu dodavati). Za applete to i nije tako bitno, ali u aplikacijama je najčešće nužno.
Izbornici su sastavljeni od tri hijerarhijska elementa Prvi element je izbornička letvica (menu bar) i sastoji se od različitih izbornika. Nalazi se na gornjem rubu ekrana kod Macintosha ili na gornjem rubu prozora kod Windowsa ili Motifa.
![]()
Svaka izbornička letvica sadrži bar jedan izbornik (menu). Izbornici su organizirani poi temama. Često susrećemo File, Edit i tako dalje.
Svaki izbornik sadrži bar jednu opciju (menu item). Opcije su obično pojedinačne akcije kao Open, Print, Cut ili Copy. Opcije nisu prikazane dok izbornik nije aktivan. Dva ili više izbornika ne mogu biti istodobno aktivni.

Na primjer ovaj Edit izbornik ima onemogućenu Undo opciju nakon koje dolazi separator, a iz njega omogućene opcije Cut, Copy, paste i Clear, zatim još jedan separator pa omogućena opcija Select All.
Paket AWT sadrži nekoliko glavnih klasa za upravljanje izbornicima:
Da biste izbornike koristili u svojim aplikacijama, bit će
vam potreban bar jedan primjerak iz klase MenuBar sa
jednim ili više primjeraka klase Menu, a za
svakog nekoliko primjeraka MenuItem.
Izbornici iz klase PopupMenu
se pojavljuju kao samostalni element.
Klasa java.awt.MenuComponent
je zadnja nadklasa svih ovih klasa, a ona je opet podklasa od java.lang.Object.
Prema tome, izborničke letvice, izbornici i opcije nisu komponente i ne
mogu se dodavati kontejnerima na uobičajeni način.
java.lang.Object | +--java.awt.MenuComponent | +--java.awt.MenuBar | +--java.awt.MenuItem | +--java.awt.Menu | +--java.awt.PopupMenuPrimijetite
da su MenuBar i
MenuItem
podklase od MenuComponent.
Menu je
podklasa od MenuItem (ovo
zvuči malo neobično, ali izbornike je zaista opcija, samo se dodaje izborničkoj
letvici). Nadalje, MenuBar
implementira sučelje java.awt.MenuContainer.
Izbornike je poželjno potpuno izgraditi prije nego ih prikažete. Tipični redosljed je ovakav:
MenuBar.
Menu.
Menu.
MenuBar
objektu tipa Frame.
Konstruktori
koji su vam potrebni su jednostavni. Novi objekt tipa MenuBar
kreirat ćete ovako:
MenuBar myMenubar = new MenuBar();Za
kreiranje novog objekta tipa Menu koristite
konstruktor Menu(String
title). Dodajte mu naslov koji želite dati izborniku. Na primjer,
za kreiranje izbornika File i Edit, napravite:
Menu fileMenu = new Menu("File"); Menu editMenu = new Menu("Edit");Opcije,
MenuItemare
kreiraju se slično, pomoću konstruktora MenuItem(String
menutext). Dajte mu potreban naslov, na primjer:
MenuItem Cut = new MenuItem("Cut");Objekte
tipa MenuItem
kreirate unutar odgovarajućih objekata tipa Menu kojima
pripadaju, isto kao što ste komponente kreirali unutar odgovarajućih
razmještaja. Izbornici imaju add()
metode koje kao argument uzimaju objekte tipa MenuItem. Evo
kako biste napravili Edit izbornik i dodali mu oipcije Undo,
Cut, Copy, Paste, Clear i Select All:
Menu editMenu = new Menu("Edit"); editMenu.add(new MenuItem("Undo")); editMenu.addSeparator(); editMenu.add(new MenuItem("Cut")); editMenu.add(new MenuItem("Copy")); editMenu.add(new MenuItem("Paste")); editMenu.add(new MenuItem("Clear")); editMenu.addSeparator(); editMenu.add(new MenuItem("Select All"));Metoda
addSeparator()
dodaje horizontalnu crtu preko izbornika. Koristi se za logičko razdvajanje
funkcija na izborniku.
Kad
kreirate izbornike, dakle objekte tipa Menu, dodat
ćete ih letvici, objektu tipa MenuBar
koristeći MenuBarovu
metodu add(Menu
m) ovako:
myMenubar.add(fileMenu); myMenubar.add(editMenu);Konačno,
kad je MenuBar gotov,
dodat ćete ga okviru, dakle objektu tipa Frame
koristeći se frameovom metodom setMenuBar(MenuBar
mb). Ako imate Frame f onda
bi to izgledalo ovako:
f.setMenuBar(myMenuBar);
Aplikacija
može imati mnogo opcija, čak i po više stotina. Sve njih staviti u init() metodu
bilo bi nepraktično. Uobičajeno je kreirati odvojene metode koje grade svaki
pojedini izbornik i dodaju ih izborničkoj letvici. Sljedeći program kreira dva
standardna izbornika, File i Edit.
import java.applet.*;import java.awt.*; public class MenuTester extends Applet { public void init () { Frame f = new Frame("Prozor s izbornicima"); f.add("Center", new Label("Pogledajte izbornike", Label.CENTER)); f.setSize(this.getSize().width, this.getSize().height); f.setLocation(320,240); MenuBar myMenuBar = new MenuBar(); this.makeFileMenu(myMenuBar); this.makeEditMenu(myMenuBar); f.setMenuBar(myMenuBar); f.show(); } void makeEditMenu(MenuBar mb) { Menu editMenu = new Menu("Edit"); editMenu.add("Undo"); editMenu.addSeparator(); editMenu.add("Cut"); editMenu.add("Copy"); editMenu.add("Paste"); editMenu.add("Clear"); mb.add(editMenu); } void makeFileMenu(MenuBar mb) { Menu fileMenu = new Menu("File"); fileMenu.add("New"); fileMenu.add("Open..."); fileMenu.addSeparator(); fileMenu.add("Close"); fileMenu.add("Save"); fileMenu.add("Save As..."); fileMenu.addSeparator(); fileMenu.add("Page Setup..."); fileMenu.add("Print"); fileMenu.addSeparator(); fileMenu.add("Quit"); mb.add(fileMenu); } }
<APPLET
CODE="MenuTester.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH=200
HEIGHT=100>
</APPLET>
Kad korisnik odabere opciju, izbornik lansira objekt tipa java.awt.event.ActionEvent. Njega može pokupiti bilo koji actionListener, dakle objekt iz klase koja implementira sučelje java.awt.event.ActionListener koji smo registrirali uz opciju, dakle objekt tipa MenuItem. Action komanda koju možemo pročitati metodom getActionCommand() sadržat će tekst opcije.
Na
primjer, sljedeći applet stavlja tekst odabrane opcije u tekstualno polje
theChoice.
import java.applet.*;import java.awt.*;import java.awt.event.*; public class ActiveMenuTester extends Appletimplements ActionListener{
TextField theChoice = new TextField(20); public void init () { Frame f = new Frame("Prozor s izbornicima "); f.add("North", new Label("Pogledajte izbornike ", Label.CENTER)); f.add("South", theChoice); f.setSize(300, 200); f.setLocation(220,240); MenuBar myMenuBar = new MenuBar(); this.makeFileMenu(myMenuBar); this.makeEditMenu(myMenuBar); f.setMenuBar(myMenuBar); f.addWindowListener(new WindowCloser()); f.show(); } protected void addItem(Menu m, String s) { MenuItem mi = new MenuItem(s); mi.addActionListener(this); m.add(mi); } protected void makeEditMenu(MenuBar mb) { Menu editMenu = new Menu("Edit"); this.addItem(editMenu, "Undo"); editMenu.addSeparator(); this.addItem(editMenu, "Cut"); this.addItem(editMenu, "Copy"); this.addItem(editMenu, "Paste"); this.addItem(editMenu, "Clear"); mb.add(editMenu); } protected void makeFileMenu(MenuBar mb) { Menu fileMenu = new Menu("File"); this.addItem(fileMenu, "New"); this.addItem(fileMenu, "Open..."); fileMenu.addSeparator(); this.addItem(fileMenu, "Close"); this.addItem(fileMenu, "Save"); this.addItem(fileMenu, "Save As..."); fileMenu.addSeparator(); this.addItem(fileMenu, "Page Setup..."); this.addItem(fileMenu, "Print"); fileMenu.addSeparator(); this.addItem(fileMenu, "Quit"); mb.add(fileMenu); } public void actionPerformed(ActionEvent e) { theChoice.setText(e.getActionCommand()); } class WindowCloser extends WindowAdapter { public void windowClosing(WindowEvent e) { Window w = (Window) e.getSource(); w.setVisible(false); w.dispose(); } } }
<APPLET
CODE="ActiveMenuTester.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="ActiveMenuTester.jar"
WIDTH=200
HEIGHT=100>
</APPLET>
Izborničke kratice, poznate i pod nazivom akceleratori ili tipovni ekvivalenti naredbe, obično ne ubrzavaju ništa, ali budući da ih korisnici vole, komercijalne aplikacije ih trebaju sadržavati.
Klasa
java.awt.MenuShortcut
predstavlja takve kratice u Javi. Ima sljedeće konstruktore:
public MenuShortcut(int key) public MenuShortcut(int key, boolean useShiftModifier)U
oba slučaja argument key je zapravo
keycode tipke koja će aktivirati tu opciju.
Ako
je useShiftModifier
postavljen na true, onda
tipka shift mora biti pritisnuta da bi kratica aktivirala opciju. Po
pretpostavci, useShiftModifier
je false.
Da
biste opciji izbornika pridružili kraticu, pozovite metodu setShortcut()
iz klase java.awt.MenuItem.
Na primjer,
MenuShortcut pShortcut = new MenuShortcut(KeyEvent.VK_P); MenuItem mi = new MenuItem("Print..."); mi.setShortcut(pShortcut);Kraticu
možete definirati i pomoću odgovarajućeg konstruktora MenuItem()ovako:
MenuShortcut pShortcut = new MenuShortcut(KeyEvent.VK_P); MenuItem mi = new MenuItem("Print...", pShortcut);Kraticu
možete ukloniti pomoću metode deleteShortcut()
iz klase java.awt.MenuItem,
na primjer:
mi.deleteShortcut();
Već
smo se susreli s klaslom already encountered the java.awt.Choice
čiji se objekti ponašaju kao padajući izbornici, no imaju fiksnu lokaciju.
Klasa
java.awt.PopupMenu
class, on the other hand, is activated when the user holds the right mouse
button or otherwise indicates that they want to pop up a menu. Typically this is
used for context sensitive menus.
Klasa
java.awt.PopupMenu
je podklasa od java.awt.Menu.
Uglavnom je koristite kao i obične izbornike. Stavke se dodaju metodom
add(),
a na korisnikove izbore odgovara se pomoću ActionListenera
instaliranog na MenuItem.
Na primjer, da biste napravili padajući izbornik sa raznim URL-ovima, možete
postupiti ovako:
PopupMenu pm = new PopupMenu(); MenuItem mi = new MenuItem("http://www.javasoft.com/"); mi.addActionListener(URLActionListener); pm.add(mi); mi = new MenuItem("http://home.netscape.com/"); mi.addActionListener(URLActionListener); pm.add(mi); mi = new MenuItem("http://metalab.unc.edu/javafaq"); mi.addActionListener(URLActionListener); pm.add(mi); mi = new MenuItem("http://www.roaster.com/news/"); mi.addActionListener(URLActionListener); pm.add(mi); Međutim,
padajući izbornici ne pripadaju nekom određenom MenuBaru.
Umjesto toga, oni se dodaju komponenti. Na primjer, za dani okvir, Frame f,
instalirali biste PopupMenu pm u
taj okvir tako da ga proslijedite metodi add()
iz klase java.awt.Component,
ovako:
f.add(pm);Primijetite
da to nije ona ista add()
metoda koju koristite za dodavanje komponente okviru.
Točan
način pokretanja padajućih izbornika ovisi o platformi. Na primjer, na
Windowsima se PopupMenu
pokreće podizanjem desne tipke miša. Na Motifu se pokreće pritiskanjem desne
tipke miša. Neovisno o egzaktnoj sekvenci događaja koja pokreće padajući
izbornik, kad korisnik odabere neku opciju, odnosno kad odabere neki MenuItem,
lansira se ActionEvent
kojeg treba uhvatiti odgovarajući listener registriran uz tu stavku.
Objekt
tipa PopupMenu se
može ukloniti iz komponente tako da ga se proslijedi komponentinoj metodi
remove(),
na primjer ovako:
f.remove(pm);Uz jednu komponentu može biti instaliran najviše jedan padajući izbornik. Ako je instaliran uz kontejner, onda će trigeri iz komponenata koje se nalaze u tom kontejneru također pokretati padajuće izbornike pod uvjetom da kontejner nema svoj vlastiti padajući izbornik.
Slike
u Javi su bitmapirane GIF ili JPEG datoteke koje mogu sadržavati proizvoljnu
sliku. Možete ih kreirati bilo kojim programom koji je u stanju napraviti GIF
ili JPEG format. Jednom kad su učitane u Javu, slike postaju instance apstraktne
klase java.awt.Image.
Ta klasa ima sljedeće (apstraktne) metode:
public abstract int getWidth(ImageObserver observer) public abstract int getHeight(ImageObserver observer) public abstract ImageProducer getSource() public abstract Graphics getGraphics() public abstract Object getProperty(String name, ImageObserver observer) public Image getScaledInstance(int width, int height, int hints) public abstract void flush()Najveći
dio posla oko slika obavlja se ipak u drugim klasama, posebno u java.awt.Graphics,
java.awt.Component,
i java.awt.Toolkit.
Metodama iz tih klasa prosljeđujete objekt tipa Image da biste
učitali i prikazali sliku.
Skuje koje prikazuju Java appleti učitavaju se s weba preko URL-a koji pokazuje na datoteku sa slikom. Applet koji prikazuje sliku mora poznavati taj URL. Slike mogu biti spremljene na web poslužitelju, lokalnom disku ili bilo gdje kamo applet može stići pomoću URL-a. Pazite da slike stavljate tamo gdje ih applet može dohvatiti. URL koji pokazuje na vaš lokalni disk može biti od koristi dok razvijate applet, ali ne može poslužiti nekome tko dolazi preko weba.
Tipično, slike se stavljaju u isti direktorij u kojem se nalazi applet ili u onaj u kojem se nalazi HTML document. Iako to nije obavezno, stavljanje slika na neku od tih lokacija je obično praktično. Stavite sliku zajedno sa appletovom class datotekom ako će se ona koristiti sa svim instancama appleta. Ili je stavite u HTML direktorij ako će razne instance appleta koristiti razne slike. Treća alternativa je staviti sve slike na zajedničku lokaciju i koristiti oznaku <PARAM> za dojavljivanje mjesta gdje se one nalaze.
Ako znate točan URL slike koju želite učitati, možete to učiniti ovako:
URL imageURL = new URL("http://student.math.hr/~vedris/java/images/sun.jpg");Image img = getImage(imageURL);To se može zapisati i na kraći način:
Image img = getImage(new URL( "http://student.math.hr/~vedris/java/images/sun.jpg"));Metoda
getImage()
je iz klase java.applet.Applet
pa ona funkcionira unutar appleta. Izvan appleta možete koristiti metodu getImage()
iz klase java.awt.Toolkit.
URL imageURL = new URL("http://student.math.hr/~vedris/java/images/sun.jpg"); Image img = Toolkit.getDefaultToolkit.getImage(imageURL);Ako
ne znate točan URL slike, ali znate njeno ime i znate da se nalazi u istom
direktoriju kao i applet, koristit ćete appletovu metodu getCodeBase()
koja će vam vratiti URL appletovog direktorija:
Image img = getImage(getCodeBase(), "sun.jpg");
Konačno,
ako je slika u istom direktoriju kao HTML datoteka, koristit ćete appletovu
metodu getDocumentBase()
koja će vratiti URL direktorija HTML stranice:
Image img = getImage(getDocumentBase(), "sun.jpg");Ako se slika učitava sa Interneta, to može potrajati. U pravilu ne morate voditi posebnog računa o tom i možete iscrtati sliku čim ste je povezali sa URL-om. Java će sama, bez vaše intervencije, prikazati sliku čim pristigne dovoljno podataka za to.
Sve
slike koje applet treba učitajte već u init() metodi.
Posebno, nemojte ih učitavati u paint() metodi
jer će se tada ponovno učitavati svaki put kad applet napravi repaint(),
što će drastično sniziti performanse.
Sliku
koja se koristi u sljedećim primjerima možete skinuti sa http://student.math.hr/~vedris/java/images/sun.jpg.
Jednom
kad ste sliku učitali s nekog URL-a, relativno je jednostavno iscrtati je. To
ćete učiniti u paint()
metodi, koristeći neku od metoda drawImage() iz
klase java.awt.Graphics,
npr.
public boolean drawImage(Image img, int x, int y, ImageObserver io) Ovdje
je img member
klase Image koji je
u tom trenutku već učita. Atributi x i
y
su koordinate lijevog gornjeg ugla slike, dok je io instanca
klase koja implementira sučelje java.awt.image.ImageObserver.
To
sučelje propisuje kako Java rukuje asinhronim ažuriranjem slike. Ono je
implementirano u klasi java.awt.Component
pa možete za sada jednostavno staviti ključnu riječ this u metodu drawImage(),
čime ćete naznačiti da je sam applet taj koji će obaviti poslove ažuriranja
slike.
Metoda
paint() ne
radi ništa drugo osim crtanja slike, počevši od lijevog gornjeg ugla i može
izgledati na primjer ovako:
public void paint(Graphics g) { g.drawImage(img, 0, 0, this);}Pretpostavljamo
da atribut img
referencira objekt koji je prethodno već bio inicijaliziran.
drawImage()Metoda
drawImage()
vraća vrijednost tipa boolean. Iako
se na nju često zaboravlja, ona vam kaže da li je slika uspješno nacrtana ili
nije. Ako jest, metoda će vratiti true, u
protivnom false.
Na primjer, sljedeći applet učitava sliku s mreže. Dok se slika učitava, applet će na njenom mjestu prikazivati tekst "Slika se ucitava. Molim, pricekajte". Kad slika bude učitana u potpunosti, applet će je prikazati.
import java.awt.*;import java.applet.*;import java.awt.image.*; public class ImageDisplay extends Applet { Image picture; public void init() { this.picture = this.getImage(this.getCodeBase(), "sun.jpg"); } public void paint(Graphics g) { if(!g.drawImage(this.picture, 0, 0, this)) { g.drawString("Slika se ucitava. Molim, pricekajte", 25, 50); } } }
<APPLET
CODE="ImageDisplay.class"
CODEBASE="http://student.math.hr/~vedris/java/classes/ImageProcessing"
WIDTH=435
HEIGHT=300>
</APPLET>
U sljedećem primjeru slika će se iscrtati ako je njeno ime dobiveno iz oznake <PARAM>, a u protivnom bit će ispisana poruka "nema slike! ".
import java.awt.*;import java.applet.*; public class DisplayImage extends Applet { private Image picture; public void init() { String filename = this.getParameter("imagefile"); if (filename != null) { this.picture = this.getImage(this.getCodeBase(), filename); } } public void paint(Graphics g) { if (this.picture != null) { g.drawImage(this.picture, 0, 0, this); } else { g.drawString("Nema slike!", 20, 20); } } }
<APPLET
CODE="DisplayImage.class"
CODEBASE="http://student.math.hr/~vedris/java/classes/ImageProcessing"
WIDTH=435
HEIGHT=300>
<PARAM
NAME="imagefile" VALUE="sun.jpg">
</APPLET>
Ne
morate se ograničiti na crtanje slike samo u njenoj prirodnoj veličini. Sljedeća
varijacija paint() metode
dopušta vam određivanje širine i visine slike, slično primjeru MagnifyImage
iz predavanja o appletima (peto predavanje).
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver io)
import java.awt.*;import java.applet.Applet; public class MagnifyImageDisplay extends Applet { private Image picture; private double scalefactor; public void init() { String filename=this.getParameter("imagefile"); if (filename != null) { this.picture = this.getImage(getCodeBase(), filename); } try { scalefactor = Double.valueOf( this.getParameter("scalefactor")).doubleValue(); } catch (Exception e) { this.scalefactor = 1.0; } } public void paint (Graphics g) { if (this.picture != null) { int width = picture.getWidth(this); int height = picture.getHeight(this); int scaleWidth = (int) (width * scalefactor); int scaleHeight = (int) (height * scalefactor); g.drawImage(picture, 0, 0, scaleWidth, scaleHeight, this); } else { g.drawString("Missing imagefile PARAM element in HTML page", 10, 10); } } }
<APPLET
CODE="MagnifyImageDisplay.class"
CODEBASE="http://student.math.hr/~vedris/java/classes/ImageProcessing"
WIDTH=435
HEIGHT=300>
<PARAM
NAME="imagefile" VALUE="sun.jpg">
<PARAM
NAME="scalefactor" VALUE="0.5">
</APPLET>
Ako pravokutnik u koji ucrtavate sliku nije proporcionalan veličini slike, onda ona može biti izobličena.
Da
bismo izbjegli nepravilno skaliranje koje dovodi do izobličenja, koristit ćemo
metode getHeight()
i getWidth()
iz klase java.awt.Image
kako bismo doznali veličinu slike. Tada je možemo, ako je potrebno, skalirati
proporcionalno. Na primjer, ovako biste smanjili sliku na jednu četvrtinu
izvorne širine i visine:
g.drawImage(img, 0, 0, img.getWidth(this)/4, img.getHeight(this)/4, this);
Pogledajmo primjer koji crta sliku u pravoj veličini bez obzira na veličinu appletovog pravokutnika:
import java.awt.*;import java.applet.Applet; public class FillWithImage extends Applet { private Image picture; public void init() { String filename = this.getParameter("imagefile"); if (filename != null) { this.picture = this.getImage(this.getCodeBase(), filename); } } public void paint (Graphics g) { if (this.picture != null) { g.drawImage(this.picture, 0, 0, this.getSize().width, this.getSize().height, this); } else { g.drawString("Nedostaje PARAM imagefile u HTML dokumentu", 10, 10); } } }
<APPLET
CODE="FillWithImage.class"
CODEBASE="http://student.math.hr/~vedris/java/classes/ImageProcessing"
WIDTH=700
HEIGHT=500>
<PARAM
NAME="imagefile" VALUE="sun.jpg">
</APPLET>
java.awt.image