Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME
Što su komponente? – labele – tri koraka u dodavanju
komponente – gdje je metoda paint()? – metode klase Label – buttoni – akcije na
buttonima – primjer appleta sa akcijom na buttonu – različiti obrasci za
događaje – višestruki ActionListeneri – metode za buttone – Action naredbe –
više buttona u istom appletu – unutarnje klase kao EventListeneri – tekstualna
polja – primjer tekstualnih polja u Javi – TextArea – klasa TextComponent –
sučelje TextListener i klasa TextEvent – klasa Canvas – klasa Choice – metode
klase Choice – klasa ItemListener – klasa Checkbox – događaji iz klase Checkbox
– klasa CheckboxGroup – primjer CheckboxGroup – klasa List – metode klase List –
događaji klase List – klasa Scrollbar
Komponente su sastavnice grafičkog korisničkog sučelja (GUI, graphical user interface).
U Javi, komponente su podklase od java.awt.Component
,
a najčešće korištene su:
Canvas
TextField
TextArea
Label
List
Button
Choice
Checkbox
Frame
JButton
JLabel
JComboBox
JMenu
Sve komponente se iscrtavaju samostalno (bez pisanja posebne paint() metode.
Najjednostavnija komponenta je java.awt.Label
.
U sljedećem primjeru je Label l
redak
teksta koji je read-only.
import java.applet.*;
import java.awt.*;
public class HelloContainer extends Applet {
public void init() {
Label l;
l = new Label("Hello Container");
this.add(l);
}
}
<APPLET
CODE="HelloContainer.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH=100
HEIGHT=100>
</APPLET>
Kao
i obično, program započinjete importiranjem potrebnih klasa. U ovom slučaju to
su java.applet.Applet
i java.awt.Label
.
Naša
klasa će imati samo jednu metodu, init()
. Ona će
obaviti tri stvari. Deklarirat će da je l
labela,
instancirati je pomoću konstruktora Label(String
s)
i dodati je razmještaju (layout). Općenito, to se ne
mora obaviti uvijek unutar metode init()
, ali
najčešća praksa je upravo takva.
public void init() {
Label l;
l = new Label("Hello Container");
this.add(l);
}
Ključna stvar koju valja zapamtiti o dodavanju komponenti appletu su sljedeća tri koraka:
Prva dva koraka moraju se obaviti prilikom kreiranja instance bilo koje klase, tako da nam samo treći korak predstavlja novost.
Možete to napraviti, naravno, i u jednoj naredbi, na primjer ovako:
this.add(new Label("Hello
Container"));
Nedostatak ovog kraćeg zapisa je taj što se izgubila referenca na labelu (varijabla l). Ipak, labele se u pravilu ne mijenjaju, tako da uglavnom nije posebna smetnja.
paint()
Primijetite
da u našem appletu nema paint()
, a
tekst se svejedno ispisuje na ekranu. Komponente se, naime, same iscrtavaju.
Svaki put kad se container kao što je applet ponovno iscrta, on pozove ne
samo svoju vlastitu paint()
metodu, nego i paint()
metode
svih svojih komponenti. Klasa java.awt.Label
ima svoju vlastitu paint()
metodu
koja zna kako se treba iscrtati. O iscrtavanju komponenti ne morate voditi
računa dok god ne kreirate vlastite klase komponenata ili izmijenite izgled
sistemskih komponenata.
Labele
su jednostavni objekti koji imaju tek nekoliko konstruktora i vlastitih, ako se
izuzmu one koje su naslijeđene od java.awt.Component
(kojoj je java.awt.Label
podklasa).
public final static int LEFT
public final static int CENTER
public final static int RIGHT
public Label()
public Label(String text)
public Label(String text, int alignment)
public void addNotify()
public int getAlignment()
public synchronized void setAlignment(int alignment)
public String getText()
public synchronized void setText(String text)
Već
smo vidjeli osnovni konstruktor za labele. Možete također kreirati labelu
koristeći konstruktor Label()
bez
argumenata, no to općenito nema smisla. Nadalje, možete odrediti da tekst bude
poravnat lijevo, desno ili centrirano, za što vam stoji na raspolaganju
odgovarajući konstruktor:
Label center = new Label("Ova labela je centrirana", Label.CENTER);
Label left = new Label("Ova labela je lijevo poravnata", Label.LEFT);
Label right = new Label("Ova labela je desno poravnata", Label.RIGHT);
Dvije
su metode iz java.awt.Label
koje će povremeno biti potrebne, a to su getText()
i
setText(String
s)
. One dozvoljavaju da doznate i promijenite tekst labele dok se
applet izvršava. Na primjer,
String s = l.getText();
l.setText("Ovo je nova labela");
Buttoni
su instance klase java.awt.Button
koja je podklasa od java.awt.Component
.
Buttoni se kreiraju pomoću konstruktora Button(String
label)
. On će kreirati novi button sa labelom koja će na njemu
biti ispisana. Kad ga kreirate, možete ga dodati razmještaju. Na primjer,
Button b;
b = new Button("My First Button");
this.add(b);
Sintaksa je gotovo identična kao za labele i vidjet ćete da je takva i za ostale komponente grafičkog sučelja. Jedino što se mijenja su konstruktori.
Kraći oblik je također isti:
add(new Button("My First
Button"));
Evo jednog appleta koji sadrži button:
import java.applet.*;
import java.awt.*;
public class FirstButton extends Applet {
public void init () {
this.add(new Button("Moj prvi Button"));
}
}
<APPLET
CODE="HelloContainer.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH=100
HEIGHT=100>
</APPLET>
Za
razliku od labela, buttoni čine nešto kad kliknete na njih. Kad miš klikne na
neki objekt tipa Button
, onda
će on ispaliti objekt tipa ActionEvent
.
Da biste bili spremni odgovoriti na taj događaj, potrebno je buttonu pridružiti
i odgovarajući ActionListener. Na primjer,
Button beep = new Button("Beep");
add(beep); // dodajemo buttom razmjestaju
beep.addActionListener(myActionListener); // pridruzujemo buttonu action listener
Ovdje
je myActionListener
referenca na objekt koji implementira sučelje (interface) java.awt.event.ActionListener
.
To sučelje propisuje samo jednu metodu:
public abstract void
actionPerformed(ActionEvent e)
Objekt
tipa ActionListener
učinit će nešto s rezultatom, objektom tipa ActionEvent
kojeg je ispalio button nakon što je zabilježio klik mišem. Na primjer, sljedeća
klasa će, kad dobije ActionEvent
,
proizvesti beep signal:
import java.awt.*;
import java.awt.event.*;
public class BeepAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}
}
Sljedeći
applet ima button označen labelom na kojoj piše "Beep". Button je na uobičajeni
način dodan razmještaju, a metoda addActionListener()
propisuje da će na buttonove ActionEvente reagirati odgovarajući
ActionListener, u ovom slučaju objekt klase BeepAction
.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class BeepApplet extends Applet {
public void init () {
// Konstruiramo button
Button beep = new Button("Beep");
// dodajemo button razmjestaju
this.add(beep);
// propisujemo da ce action evente koje ovaj button posalje
// obraditi novi objekt klase BeepAction
beep.addActionListener(new BeepAction());
}
}
<APPLET
CODE="BeepApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Beep.jar"
WIDTH=100
HEIGHT=100>
</APPLET>
Glavna
je prednost Javinog modela događaja je da se GUI može odvojiti od ostalog koda.
Kako je ActionListener
sučelje (interface), a ne klasa, on može biti implementiran gdje god nam
odgovara. Na primjer, applet može i sam obrađivati svoje događaje, što ćemo
vidjeti iz sljedećeg primjera:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class BeepApplet extends Applet
implements ActionListener {
public void init () {
// Construct the button
Button beep = new Button("Beep");
// add the button to the layout
this.add(beep);
// specify that action events sent by this
// button should be handled by the applet itself
beep.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}
}
<APPLET
CODE="BeepApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH=100
HEIGHT=100>
</APPLET>
Primijetite da niste ograničeni na samo jedan listener po događaju. Na primjer, sljedeći program generira pet beep-ova svaki put kad pritisnete button.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class BeepFiveApplet extends Applet {
public void init () {
// Construct the button
Button beep = new Button("Beep");
// add the button to the layout
this.add(beep);
// specify that action events sent by this
// button should be handled by a new BeepAction object
beep.addActionListener(new BeepAction());
beep.addActionListener(new BeepAction());
beep.addActionListener(new BeepAction());
beep.addActionListener(new BeepAction());
beep.addActionListener(new BeepAction());
}
}
<APPLET
CODE="BeepFiveApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="BeepFive.jar"
WIDTH=100
HEIGHT=100>
</APPLET>
Kad
pritisnete button, on će lansirati ActionEvent
, a
svaki od pet objekata klase BeepAction
dobit će kopiju tog događaja. Redosljed primanja tih kopija nije
specificiran.
Ako je vaše računalo prebrzo da biste čuli svih pet beep-ova, dodajte unutar metode ActionPerformed() iz klase BeepAction još i naredbu
System.out.println("Beep"
);
Pogledate li applet pomoću appletviewera, moći ćete pratiti ispis svaki put kad pritisnete button i vidjeti da se akcija zaista događa pet puta.
Buttoni
su jednostavni objekti. Uglavnom sve što trebate napraviti s njima je dodati ih
u razmještaj i pridružiti im ActionListener
.
Na raspolaganju su vam i sljedeće metode:
public void addNotify()
public String getLabel()
public synchronized void setLabel(String label)
public void setActionCommand(String command)
public String getActionCommand()
public void addActionListener(ActionListener l)
public void removeActionListener(ActionListener l)
addNotify()
kreira takozvani peer objekt
za zadani button, tj. native masku koja izgleda kao Windows button ili
Mac button ili Motif button, no ona se rijetko direktno poziva.
Metode
getLabel()
i
setLabel(String
s)
omogućuju dohvaćanje i mijenjanje teksta koji se pojavljuje na
buttonu za vrijeme izvršavanja appleta. Na primjer, za neki Button b
,
možemo imati:
String s = b.getLabel();
b.setLabel("Here's the new label");
Primijetite
da metoda unatoč sugestivnom imenu getLabel()
vraća objekt tipa String
, a ne
Label
.
Metode
setActionCommand()
i getActionCommand()
modificiraju komandni string koji sa sobom nosi ActionEvent
.
Po pretpostavci to je labela buttona, ali to se može promijeniti. Na primjer,
možete zadati broj ponvljanja beep signala koji će applet proizvesti na klik
mišem (pogledajte BeepFiveApplet).
Metoda
addActionListener()
registrira neki objekt kao onaj koji bi trebao primiti ActionEvent
koji će Button
ispaliti. Metoda removeActionListener()
poništava tu registraciju, tako da objekt tipa ActionListener
više neće primati ActionEvente koje button ispali.
Metode
setActionCommand()
i getActionCommand()
modificiraju komandni string koji putuje uz ActionEvent
.
Po pretpostavci, to je labela buttona, ali to se može promijeniti. Na primjer,
možete na taj način proslijediti broj ponaljanja beep signala koje applet treba
proizvesti.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class BeepFiveApplet extends Applet {
public void init () {
// Construct the button
Button beep = new Button("Beep");
// add the button to the layout
this.add(beep);
// specify that action events sent by this
// button should be handled by the applet itself
beep.addActionListener(new MultiBeepAction());
beep.setActionCommand("5");
}
}
class MultiBeepAction implements ActionListener {
public void actionPerformed(ActionEvent ae) {
int n;
try {
n = Integer.parseInt(ae.getActionCommand());
}
catch (NumberFormatException e) {
n = 1;
}
Toolkit tk = Toolkit.getDefaultToolkit();
for (int i = 0; i < n; i++) tk.beep();
}
}
<APPLET
CODE="BeepFiveApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="MultiBeep.jar"
WIDTH=200
HEIGHT=200>
</APPLET>
Naravno,
moguće je imati više od jednog buttona u appletu. Svaki button koji će izazvati
neku akciju mora registrirati bar jedan objekt koji je ActionListener
.
Različiti buttoni mogu registrirati različite ActionListener
e
, ali ih mogu i dijeliti. ActionListener
i
za buttone mogu pripadati istoj klasi, ali ne moraju. Ako dva buttona
registriraju isti ActionListener
,
uobičajeno je koristiti action komandu da bismo razlikovali akcije.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class TwoButtons extends Applet {
public void init() {
MultiBeepAction mba = new MultiBeepAction();
// Construct the button
Button beep = new Button("Beep Once");
// add the button to the layout
this.add(beep);
beep.addActionListener(mba);
beep.setActionCommand("1");
Button beepTwice = new Button("Beep Twice");
beepTwice.addActionListener(mba);
beepTwice.setActionCommand("2");
this.add(beepTwice);
}
}
class MultiBeepAction implements ActionListener {
public void actionPerformed(ActionEvent ae) {
int n;
try {
n = Integer.parseInt(ae.getActionCommand());
}
catch (NumberFormatException e) {
n = 1;
}
Toolkit tk = Toolkit.getDefaultToolkit();
for (int i = 0; i < n; i++) tk.beep();
}
}
<APPLET
CODE="TwoButtons.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="TwoButtons.jar"
WIDTH=200
HEIGHT=100>
</APPLET>
Uobičajeno
je da klasa koja realizira event listener bude unutarnja klasa. To se
najčešće primjenjuje na prilagođene podklase komponenata koje žele same
obrađivati svoje događaje.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class TwoButtons extends Applet {
public void init() {
MultiBeepAction mba = new MultiBeepAction();
// Construct the button
Button beep = new Button("Beep Once");
// add the button to the layout
this.add(beep);
// specify that action events sent by this
// button should be handled by the MultiBeepAction mba
beep.addActionListener(mba);
beep.setActionCommand("1");
Button beepTwice = new Button("Beep Twice");
beepTwice.addActionListener(mba);
beepTwice.setActionCommand("2");
this.add(beepTwice);
}
class MultiBeepAction implements ActionListener {
public void actionPerformed(ActionEvent ae) {
int n;
try {
n = Integer.parseInt(ae.getActionCommand());
}
catch (NumberFormatException e) {
n = 1;
}
Toolkit tk = Toolkit.getDefaultToolkit();
for (int i = 0; i < n; i++) tk.beep();
}
}
}
<APPLET
CODE="TwoButtons.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="TwoButtonsIC.jar"
WIDTH=200
HEIGHT=100>
</APPLET>
Klasa
java.awt.TextField
omogućuje ugradnju maske za unos i editiranje jedne linije teksta. Korisna je za
jednostavne operacije unosa malih količina podataka. Ima četiri
konstruktora:
public TextField()
public TextField(String text)
public TextField(int num_chars)
public TextField(String text, int num_chars)
Zbog
načina na koji Java razmješta tekst, konstruktor bez argumenata bi valjalo
izbjegavati. Koristite ili onaj koji ima String
ili
zadajte broj znakova koje će ta kućica sadržavati. Na primjer,
TextField name = new TextField("Type your name here");
TextField socialSecurity = new TextField(11);
Kad
korisnik pritisne tipku return ili enter unutar TextField
a,
ispali se jedan ActionEvent
.
Možete ga uloviti pomoću ActionListener
a,
isto kao u slučaju buttona. Imajte na umu da većina korisnika nije svjesna da se
nešto događa tek onda kad pritisnu return unutar TextField
a.
Zato uvijek osigurajte i alternativni način ispaljivanja ActionEvent
a,
na primjer pomoću buttona ili retka na izborniku.
Metoda
getText()
vraća sadržaj TextField
a.
Metoda setText(String
s)
ga mijenja.
Metoda
setEditable()
omogućuje da korisniku dozvolite ili zabranite modificiranje sadržaja
TextField
a.
Sljedeći
applet čita tekst iz jednog TextField
a i
ispisuje ga velikim slovima u drugi TextField
.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class CapitalizeApplet extends Applet {
private TextField input;
private TextField output;
public void init () {
// Konstruiramo tekstualna polja
this.input = new TextField(40);
this.output = new TextField(40);
this.output.setEditable(false);
Button b = new Button("Capitalize");
// dodajemo komponente u razmjestaj
this.add(input);
this.add(b);
this.add(output);
// odredjujemo da action evente koje salju
// button ili input TextField budu obradjeni od
// istog objekta tipa CapitalizerAction
CapitalizerAction ca = new CapitalizerAction(input, output);
b.addActionListener(ca);
this.input.addActionListener(ca);
// ActionEvents koje salje polje output se ignoriraju.
}
}
class CapitalizerAction implements ActionListener {
TextField in;
TextField out;
public CapitalizerAction(TextField in, TextField out) {
this.in = in;
this.out = out;
}
public void actionPerformed(ActionEvent ae) {
String s = in.getText();
out.setText(s.toUpperCase());
}
}
<APPLET
CODE="CapitalizeApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Capitalize.jar"
WIDTH=500
HEIGHT=100>
</APPLET>
U
ovom programu korišten je drugačiji obrazac za obradu događaja. Konstruktor
klase CapitalizerAction
je iskorišten za prosljeđivanje referenci različitim komponentama koje metoda
actionPerformed()
modificira.
Klasa
java.awt.TextArea
je podklasa od java.awt.TextComponent
koja osigurava masku za editiranje više linija teksta. Korisna je za input i
output.
Na raspolaganju su nam četiri konstruktora:
public TextArea()
public TextArea(String text)
public TextArea(int rows, int columns)
public TextArea(String text, int rows, int columns)
public TextArea(String text, int rows, int columns, int scrollbars)
Zbog
načina na koji Java raspoređuje komponente, izbjegavajte korištenje konstruktora
bez argumenata. Radije počnite sa onim koji zadaje String
ili
broj redaka i stupaca koje će ta površina zauzeti. Na primjer,
TextArea address = new TextArea("Upišite svoju adresu", 5, 80);
Po pretpostavci, TextAreas nema scrollbar. Možete ih dodati ako odgovarajućem konstruktoru prenesete neku od ovih konstanti:
TextArea.SCROLLBARS_BOTH
TextArea.SCROLLBARS_HORIZONTAL_ONLY
TextArea.SCROLLBARS_NONE
TextArea.SCROLLBARS_VERTICAL_ONLY
Na primjer,
TextArea instructions = new TextArea("", 15, 70,
TextArea.SCROLLBARS_VERTICAL_ONLY);
Za
razliku od TextField
a,
TextArea
ne
generira nikakav actionEvent kad korisnik pritisne return unutar polja.
Umjesto toga, linija se prekida, a kursor prenosi u novi red.
No
i nadalje, metoda getText()
vraća tekst koji sadrži TextArea
, a
setText()
ga
mijenja. Metoda setEditable()
dopušta vam da odredite da li će korisnik moći mijenjati sadržaj. Obje klase,
TextField
i
TextArea
,
nasljeđuju sve ove metode od svoje nadklase, TextComponent
.
Nadalje,
tekst možete dodavati na kraj pomoću metode append()
,
umetati pomoću metode insert()
, a
zamijeniti pomoću metode replaceRange()
:
public synchronized void insert(String text, int position)
public synchronized void append(String text)
public synchronized void replaceRange(String text, int start, int end)
I
TextArea
i
TextField
su
podklase od java.awt.TextComponent
.
Ova klasa sadrži metode koje su zajedničke za obje klase, uključujući i nekoliko
metoda koje smo već vidjeli.: getText()
,
setText()
, i
setEditable()
.
Klasa TextComponent
ima također i metode za manipuliranje selekcijom i kursorom te za procesiranje
TextEvent
a.
Selekcija
se koristi za copy/paste ali i za druge svrhe. Prvi znak u TextComponent
i
je znak broj 0; drugi je znak broj 1 i tako dalje.
public synchronized int getSelectionStart()
public synchronized void setSelectionStart(int selectionStart)
public synchronized int getSelectionEnd()
public synchronized void setSelectionEnd(int selectionEnd)
public synchronized void select(int selectionStart, int selectionEnd)
public synchronized void selectAll()
public synchronized String getSelectedText()
Kursor (caret) je mjesto insertiranja teksta. Tamo se pojavljuje tekst kad ga korisnik utipka. Dvije su metode koje to reguliraju:
public void setCaretPosition(int position)
public int getCaretPosition()
Klase
TextArea
i
TextField
mogu
instalirati sučelje java.awt.event.TextListener
koje hvata događaje iz klase java.awt.event.TextEvent
.
TextComponent
e
ispaljuju TextEvent
e
svaki put kad se njihov tekst promijeni. To se događa uglavnom svaki put kad
korisnik pritisne tipku unutar komponente.
Sučelje
TextListener
propisuje samo jednu metodu, textValueChanged()
:
public abstract void textValueChanged(TextEvent te)
Nekoj
TextComponent
i
pridružujete TextListener
tako da pozovete njenu metodu addTextListener()
.
Na primjer,
TextArea password = new TextArea(24)
password.addTextListener(new PasswordChecker());
Ipak, u najvećem broju slučajeva bit će posve dovoljno pročitati i postaviti tekst (get i set). Procesiranje znak po znak je relativno rijetko potrebno.
Napomenimo
da se TextListener
uklanja pozivanjem metode
removeTextListener()
.
public void removeTextListener(TextListener tl)
Klasa
java.awt.Canvas
definira pravokutnu površinu (podlogu, pozadinu) po kojoj možete pisati i crtati
koristeći metode iz klase java.awt.Graphics
.
Klasa Canvas
ima
samo tri metode:
public Canvas()
public void addNotify()
public void paint(Graphics g)
Podloge
uglavnom ne instancirate direktno. Umjesto toga pišete podklasu koja će
pregaziti paint()
metodu
kako biste nacrta li sliku koju trebate. Na primjer, sljedeća podklasa od
Canvas
crta
veliku crvenu elipsu koju možete dodati vašem appletu:
import java.awt.*;
public class RedOval extends Canvas {
public void paint(Graphics g) {
Dimension d = this.getSize();
g.setColor(Color.red);
g.fillOval(0, 0, d.width, d.height);
}
public Dimension getMinimumSize() {
return new Dimension(50, 100);
}
public Dimension getPreferredSize() {
return new Dimension(150, 300);
}
public Dimension getMaximumSize() {
return new Dimension(200, 400);
}
}
Applet
koji koristi komponente nikako ne bi smio pregaziti metodu paint()
jer će
to zbog načina na koji Java raspoređuje
komponente izazvati nepredvidljive rezultate. Umjesto toga treba kreirati
objekt tipa Canvas
i sva
crtanja obaviti pomoću njegove paint()
metode.
Podloge se dodaju apletima na isti način kao i ostale komponente. Na primjer,
public void init() {
this.add(new RedOval());
}
Podloge u pravilu ne ispaljuju nikakve događaje, no poslije ćete naučiti kako se to može promijeniti.
Klasa
java.awt.Choice
implementira popup izbornik sa fiksnom pozicijom (postoji također i klasa
java.awt.PopupMenu
kod koje pozicija nije fiksna i pojavljuje se kad korisnik klikne i drži desnu
tipku miša).
Kreiranje izbornika je nešto malo kompleksnije od kreiranja komponenti koje smo do sada vidjeli. Imamo, naime, dodatni korak, dodavanje pojedinačnih opcija u izbornik. Cijeli postupak izgleda ovako:
Choice
Choice
Choice
)
ItemListener
izborniku Na primjer, prva četiri koraka mogla bi izgledati ovako
public void init() {
Choice ch;
ch = new Choice();
ch.addItem("1");
ch.addItem("2");
ch.addItem("3");
ch.addItem("4");
ch.addItem("5");
add(ch);
}
Klasa
Choice
ima
više metoda za dodavanje, uklanjanje i vraćanje različitih opcija sa popisa.
Popis opcija se počinje brojiti od 0.
public int getItemCount()
public String getItem(int index)
public synchronized void add(String item)
public synchronized void addItem(String item)
public synchronized void insert(String item, int position)
public synchronized void remove(String item)
public synchronized void remove(int position)
public synchronized void removeAll()
Ipak, uglavnom ćete opcije ugraditi izbornik čim se applet pokrene i nećete ih kasnije mijenjati.
Sljedeće metode čitaju ili postavljaju trenutačno selektiranu opciju iz izbornika, dakle opciju koja je u tom trenutku vidljiva.
public synchronized void removeAll()
public synchronized String getSelectedItem()
public synchronized Object[] getSelectedObjects()
public int getSelectedIndex()
public synchronized void select(int position)
public synchronized void select(String item)
Kad
korisnik odabere novu opciju u izborniku, onda izbornik (objekt tipa Choice
)
ispaljuje dva događaja tipa java.awt.event.ItemEvent,
jedan koji indicira da je početna opcija deselektirana i drugi, da je
selektirana nova opcija. Te događaje možete procesirati tako da instalirate
sučelje java.awt.event.ItemListener,
a svom izborniku pridružite odgovarajući ItemListener
objekt koji će hvatati spomenute događaje.
No ima i drugih načina da se to napravi. Na primjer, odabranu vrijednost iz izbornika možete provjeravati kad se dogodi neki drugi događaj, na primjer pritisak na neki button.
Pogledaj mo primjer sljedećeg appleta koji prikazuje izbornik s brojevima od d1 do 5. Korisnik biranjem broja određuje koliko puta applet šalje beep signal.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class MultiBeep extends Applet {
public void init() {
Choice ch;
ch = new Choice();
ch.addItem("1");
ch.addItem("2");
ch.addItem("3");
ch.addItem("4");
ch.addItem("5");
this.add(ch);
ch.addItemListener(new BeepItem());
}
}
class BeepItem implements
ItemListener {
public void itemStateChanged(ItemEvent ie) {
if (
ie.getStateChange() == ItemEvent.SELECTED) {
String name = (String) ie.getItem();
Toolkit tk = Toolkit.getDefaultToolkit();
try {
int n = Integer.parseInt(name);
for (int i = 0; i < n; i++) tk.beep();
}
catch (Exception e) {
tk.beep();
}
}
}
}
<APPLET
CODE="MultiBeep.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="BeepChoice.jar"
WIDTH=200
HEIGHT=100>
</APPLET>
Klasa
BeepItem
implementira sučelje ItemListener
.
Ona pomoću metode ItemEvent.getStateChange()
filtrira događaje prouzrokovane deselektiranjem opcija i proizvodi beep samo kad
se opcija selektira. Konstante koje nam stoje na raspolaganju su:
ItemEvent.DESELECTED
ItemEvent.ITEM_FIRST
ItemEvent.ITEM_LAST
ItemEvent.ITEM_STATE_CHANGED
ItemEvent.SELECTED
Metoda
ItemEvent.getItem()
se koristi da se dobije trenutno selektirana opcija. Kao i prije, ako ne možete
čuti sve beepove, dodajte iza naredbi tk.beep();
u klasi BeepItem
još i naredbu System.out.println("
beep"
);
i pogledajte applet sa appletviewerom.
Klasa
java.awt.Checkbox,
se koristi za selektiranje boolean
vrijednosti. Svaki Checkbox
ima
labelu koja bi trebala reći korisniku što pojedini Checkbox
predstavlja. Na primjer Checkbox
sa
labelom "Olives" u appletu Ingredients
za naručivanje pizze (vidi dolje) bila bi čekirana ako korisnik želi masline, a
u protivnom nečekirana. Dodavanje Checkbox
a
appletu je jednostavno. Deklarirajte, konstruirajte i dodajte:
Checkbox c;
c = new Checkbox("Pepperoni"));
add(c);
Kao i obično, ovo se može napisati i u jednoj naredbi:
add(new Checkbox("Pepperoni"));
Po pretpostavci, checkboxovi su nečekirani kad se kreiraju. Ako želite da neki od njih bude odmah čekiran, koristite sljedeći konstruktor:
add(new Checkbox("Pepperoni", null, true));
Vrijednost
null
je ovdje
referenca na CheckboxGroup
i znači da ovaj Checkbox
ne
spada u CheckboxGroup
(vidi dalje).
Svaki
Checkbox
ima
boolean
vrijednost, bilo true
ili
false
. Kad je
Checkbox
čekiran, ta vrijednost je true
. Kad je
nečekiran, ona je false.
Toj vrijednosti pristupate pomoću Checkbox
ovih
metoda getState()
i
setState(boolean
b)
. Na primjer,
private void handleCheckbox(Checkbox c) {
if (c.getState()) price += 0.50f;
else price -= 0.50f;
}
Kad
Checkbox
promijeni stanje, što je u normalnim okolnostima rezultat korisnikove akcije,
ispaljuje se događaj tipa java.awt.event.ItemEvent.
Taj događaj uglavnom ignorirate i ispitujete stanje Checkbox
a
direktno kad vam treba. Ipak, ako želite odmah znati to stanje, registrirat ćete
uz njega ItemListener
i
u odgovarajućoj klasi implementirati sučelje java.awt.event.ItemListener.
Pripadni
ItemEvent
je
potpuno isti kao i onaj za Choice
. Taj se
događaj zapravo koristi za indiciranje selekcija i deselekcija u svim vrstama
popisa opcija, uključujući checkboxove, radio buttone, choice, i liste.
Sljedeći
program je applet koji pita "What do you want on your pizza?" Kad je dodatak
čekiran, cijena se povećava za 50 centa. Kad se dodatak dečekira, cijena se
smanjuje za 50 cdnta. Cijena je pokazana u TextField
u.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Ingredients extends Applet {
TextField t;
float price = 7.00f;
public void init() {
Checkbox c;
this.add(new Label("What do you want on your pizza?", Label.CENTER));
this.t = new TextField(String.valueOf(price));
// so people can't change the price of the pizza
t.setEditable(false);
Pricer p = new Pricer(price, t);
c = new Checkbox("Pepperoni");
this.add(c);
c.addItemListener(p);
c = new Checkbox("Olives");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Onions");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Sausage");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Peppers");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Extra Cheese");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Ham");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Pineapple");
c.addItemListener(p);
this.add(c);
c = new Checkbox("Anchovies");
c.addItemListener(p);
this.add(c);
this.add(t);
}
}
class Pricer implements ItemListener {
TextField out;
double price;
public Pricer(double baseprice, TextField out) {
this.price = baseprice;
this.out = out;
}
public void itemStateChanged(ItemEvent ie) {
if (ie.getStateChange() == ItemEvent.SELECTED) this.price += 0.50f;
else this.price -= 0.50f;
// Change the price
this.out.setText(String.valueOf(price));
}
}
<APPLET
CODE="Ingredients.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Pizza.jar"
WIDTH=200
HEIGHT=200>
</APPLET>
Checkbox
grupe su kolekcije checkboxa koje imaju specijalno svojstvo da unutar grupe ne
može biti čekirano više od jednog checkboxa istovremeno. Takvi checkboxovi iz
klase CheckboxGroup
se često zovu radio buttons. Checkboxovi koji pripadaju istoj CheckboxGroup
i
ne mogu se istovremeno čekirati. Kad korisnik čekira jednog, svi ostali se
automatski dečekiraju.
Konstruktor
za CheckboxGroup
je trivijalan. Nema argumenata i čak ne morate dodavati tu komponentu appletu
jer ona nije dio korisničkog sučelja nego naprosto način uređenja
checkboxova.
CheckboxGroup cbg = new
CheckboxGroup();
Da biste omogućili da se jedna grupa checkboxova ponaša kao radio buttons, konstruirajte svaki pojedini na ovaj način:
public Checkbox(String
label,
CheckboxGroup
cbg
, boolean
checked)
Labela label pripada određenom checkboxu, a cbg je grupa u koju stavljate taj checkbox. Ona mora u tom trenutku već postojati.
Kad god želite, možete pročitati ili odrediti koji checkbox je čekiran, koristeći se jednom od sljedeće dvije metode:
public Checkbox getSelectedCheckbox()
public synchronized void setSelectedCheckbox(Checkbox box)
Sljedeći
program pita korisnika kako želi platiti pizzu. Primijetite da za razliku od
prethodnog primjera u kojem je mogao izabrati više dodataka na pizzu, sada može
odabrati točno jedan način plaćanja.
import java.applet.*;
import java.awt.*;
public class PaymentMethod extends Applet {
public void init() {
this.add(new Label("How will you pay for your pizza?"));
CheckboxGroup cbg = new CheckboxGroup();
this.add(new Checkbox("Visa", cbg, false));
this.add(new Checkbox("Mastercard", cbg, false));
this.add(new Checkbox("American Express", cbg, false));
this.add(new Checkbox("Discover", cbg, false));
this.add(new Checkbox("Cash", cbg, true)); // the default
}
}
<APPLET
CODE="PaymentMethod.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Pizza.jar"
WIDTH=200
HEIGHT=200>
</APPLET>
U
ovom primjeru nije bilo nikakvih akcija. Ako želite dodati akcije, postupite
jednako kao i u slučaju bilo kojeg drugog Checkbox
a.
Liste sa scrollbarom, objekti klase java.awt.List, korisne su za spremanje duljih popisa red po red. Elementi liste su stringovi. Na primjer,
Novi
objekt tipa List
kreirate
jednim od sljedećih konstruktora:
public List()
public List(int numLines)
public List(int numLines, boolean allowMultipleSelections)
Na primjer,
List l = new List(8,
true);
Pri
tome je
numLines
broj redaka koje želite vidjeti na ekranu i on je u
pravilu manji od broja elemenata same liste, dok je allowMultipleSelections
argument koji određuje može li korisnik selektirati više od jednog retka
istovremeno (npr. pomoću Shift-click).
Sljedeće metode dodaju retke na kraj liste:
public void add(String item)
public void addItem(String item)
// deprecated! Koristite prvu metodu
Sljedeće dvije metode dodaju retke na zadanu poziciju u listi:
public synchronized void add(String item, int index)
public synchronized void addItem(String item, int index)
// deprecated!
Sljedeće metode uklanjaju retke iz liste:
public synchronized void removeAll()
public synchronized void remove(String item)
public synchronized void remove(int position)
public synchronized void delItem(int position)
Sljedeće metode dopuštaju vam da pročitate određene retke iz liste:
public int getItemCount()
public String getItem(int index)
public synchronized String[] getItems()
Možete također zamijeniti određeni redak:
public synchronized void replaceItem(String newValue, int index)
Ove metode omogućuju vam da doznate koje je retke korisnik selektirao::
public synchronized int getSelectedIndex()
public synchronized int[] getSelectedIndexes()
public synchronized String getSelectedItem()
public synchronized String[] getSelectedItems()
public Object[] getSelectedObjects()
Množinski
oblik ovih metoda koristit ćete ako lista dozvoljava višestruku selekciju. Da li
je ona dozvoljena, ustanovit ćete metodom isMultipleMode()
,
a to možete promijeniti pomoću setMultipleMode()
.
public boolean isMultipleMode()
public synchronized void setMultipleMode(boolean b)
Sljedeće metode omogućuju vam manipuliranje selektiranjem:
public synchronized void select(int index)
public synchronized void deselect(int index)
public boolean isIndexSelected(int index)
Sljedeće dvije metode određuju da li je redak na određenom indeksu vidljiv unutar kućice:
public int getVisibleIndex()
public synchronized void makeVisible(int index)
Lists
can fire two separate types of events. When a list item is selected or
deselected, the List
fires an
ItemEvent
.
However, when the user double clicks on a list item, the List
fires an
ActionEvent
.
Therefore, you can register both an ItemListener
to process selections and/or an ActionListener
to process double clicks.
public void addItemListener(ItemListener l)
public void removeItemListener(ItemListener l)
public void addActionListener(ActionListener l)
public void removeActionListener(ActionListener l)
The
action command in the ActionEvent
is
the list item which was double clicked.
Klase
List
,
TextArea
, i
ScrollPane
s
imaju gotove scrollbare. No ako želite scrollati neki drugi objekt, treba vam
klasa java.awt.Scrollbar
.
Scrollbari imaju puno primjena. Elementarna je pomicanje vidljivog područja.
Također se mogu koristiti za postavljanje vrijednosti između dva zadana broja.
Ili mogu prolaziti kroz više ekrana, kao u operacijama na bazama podataka koje
traže sukcesivne slogove.
Imamo tri konstruktora:
public Scrollbar()
public Scrollbar(int orientation)
public Scrollbar(int orientation, int value, int visible, int min, int max)
Argument
orientation
je
jedna od mnemoničkih konstanti, Scrollbar.HORIZONTAL
ili Scrollbar.VERTICAL
.
Prema očekivanju, one određuju da li je scrollbar razmješten s lijeva na desno
ili odozgo prema dolje.
Sve
vrijeme Scrollbar
ima
jednu an int
vrijednost. To je početna vrijednost koja mora biti između minimalne i
maksimalne koje se zadaju sa zadnja dva argumenta. Kad se Scrollbar
kreira, njegova početna vrijednost će biti value
. Default
je 0.
Argument
visible
predstavlja veličinu vidljivog dijela skrolabilne površine u pikselima. To se
koristi kod pomicanja po stranici.
Događaj
koji Scrollbar
ispaljuje je tipa java.awt.event.AdjustmentEvent.
Klasa koja će ga uhvatiti mora implementirati sučelje java.awt.event.AdjustmentListener.
Ona mora implementirati metodu adjustmentValueChanged()
sa sljedećom signaturom:
public void
adjustmentValueChanged(AdjustmentEvent e)
Sljedeći
program je applet koji mijenja broj u TextField
u
između 1 i 100 u ovisnosti o poziciji oznake na scrollbaru. U praksi bi taj
broj, naravno, morao nešto predstavljati.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scrollie extends Applet implements
AdjustmentListener {
TextField t;
Scrollbar sb;
public void init() {
int initialValue = 1;
sb = new Scrollbar(Scrollbar.HORIZONTAL, initialValue, 1, 1, 100);
sb.addAdjustmentListener(this);
this.add(sb);
this.t = new TextField(4);
this.t.setText(String.valueOf(initialValue));
this.add(t);
}
public void adjustmentValueChanged(AdjustmentEvent e) {
int val = sb.getValue();
this.t.setText(String.valueOf(val));
}
}
<APPLET
CODE="Scrollie.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH=200
HEIGHT=100>
</APPLET>