Dogodkovno programiranje in Swing
Swing in AWT (Abstract Widget Toolbox) sta
knjižnici, s katerima v Javi programiramo grafične uporabniške
vmesnike. Vsebujeta razrede za izdelavo oken, menujev, gumbov,
slik, za delo z miško in tipkovnico itn. AWT je osnovna knjižnica,
Swing pa je njena nadgradnja.
Kadar uporabljamo Swing in AWT, moramo napisati ustrezni
Pozor, knjižnica Swing je v sklopu
import
ukaz:
import java.awt.*; import javax.swing.*; |
javax.swing.*
(dodatna črka x
)! V poštev prideju tudi razne
podknjižnice, na primer java.awt.event.*
.
Naloga 1
Kje v dokumentaciji za Javo se vidi, kakšnen
import
ukaz je treba napisati, če uporabimo neki razred iz
knjižnice? Na primer, v kateri knjižnici je razred
HTMLWriter
?
Swing in AWT sta seveda zasnovana v objektnem stilu
programiranja. Vsak uporabniški element je objekt. Nekateri
objekti so vidni na zaslonu (okno, menu, gumb, slika, besedilo,
...), ostali pa so uporabniku nevidni, v to skupino spadajo t.i.
dogodki (event) in razporejevalci (layout manager).
Naštejmo nekaj osnovnih elementov v Swingu:
JFrame
- To je samostojno okno. Preprosti programi, kakršne bomo pisali mi, imajo eno samo tako okno. Okno vsebuje ostale elemente, kot je glavni menu, področje za risanje ali vpisovanje besedila, razni gumbi ipd.
JButton
- To je gumb, ki prikazuje besedilo ali sliko. Ko ga uporabnik pritisne, se zgodi "dogodek", na katerega lahko program ustrezno reagira.
JLabel
- To je področje, ki prikazuje besedilo ali sliko. Uporabnik takega besedila ne more spreminjati.
JTextArea
- To je področje za prikazovanje in urejanje besedila.
JFileChooser
- To je element, s katerim uporabnik izbere datoteko.
- Razred
JPanel
- To je področje, ki vsebuje ostale elemente, nanj pa lahko tudi rišemo, podobno kot v
Applet
.
Poleg tega vsebuje Swing še razrede, ki ne predstavljajo
grafičnih elementov, ki so vidni uporabniku. Nekateri izmed njih
so:
ActionEvent
- To je poseben objekt, ki se naredi, kadar pride do "dogodka". Dogodek je na primer pritisk na gumb, pritisk na tipko, premik miške, ipd.
MouseEvent
- To je poseben objekt, ki se naredi vsakič, ko uporabnik premakne miško ali pritisne na gumb na miški.
BorderLayout
- Okno običajno vsebuje več elementov (gumbe, področja za pisanje, drsnike), ki jih je treba ustrezno razporediti. Razporejanje grafičnih elementov nadzoruje objekt razreda
LayoutManager
. Takemu objektu pravimo razporejevalnik. Še posebej preprost razporejevalnik jeBorderLayout
, ki zna v okno razporediti do 5 elementov (na sever, jug, vzhod, zahod in center). Mi bomo uporabiliBorderLayout
. GridBagLayout
- To je bolj zahteven razporejvalnik, ki zna razporediti elemente v poljubno matriko.
GridBagLayout
je bolj zapleten za uporabo, zato v tej lekciji ne bomo razlagali, kako se ga uporabi. Kdor bo delal bolj zahtevne uporabniške vmesnike, naj si prebere dokumentacijo sam.
Napišimo preprost program, ki prikazuje rdečo elipso in krog.
Uporabnik lahko vtipka polmer kroga, elipsa pa se vedno razteza
čez celoten zaslon. Program sestoji iz glavnega okna, slike in
nekaterih komponent:
Program sestoji iz treh razredov:
- Razred Krog vsebuje glavni program, ki odpre okno.
- Razred GlavnoOkno je podrazred JFrame. To je glavno okno, v katero postavimo ostale elemente. Eden od elementov je objekt razreda Slika, ki prikazuje elipso in krog.
- Razred Slika je podrazred JPanel in prikazuje sliko.
Glavni program
Glavni program je preprost, ker je njegova edina naloga odpreti glavno okno:
Krog.java | |
---|---|
1 2 3 4 5 6 7 8 9 | import javax.swing.*; public class Krog { public static void main(String[] args) { JFrame okno = new GlavnoOkno(); okno.pack(); okno.setVisible(true); } } |
V 5. vrstici smo naredili novo okno. S tem se okno še ne
prikaže na zaslonu, ampak se naredi samo objekt.
V 6. vrstici pokličemo metodo pack(), ki izračuna
razporeditev elementov znotraj okna in njegovo velikost. Okno še
vedno ni vidno uporabniku.
V 7. vrstici pokličemo metodo setVisible(true), s
katero dejansko aktiviramo okno, da se prikaže na zaslonu.
Okno
Objekt razreda GlavnoOkno vsebuje vsebuje pet
elementov: besedilo nad sliko, slika, besedilo "r = "
spodaj levo, polje za vnos in gumb.
Elemente naredimo in dodamo v okno v konstruktorju. Element
x dodamo s klicem metode
getContentPane().add().
Pritisk na gumb se obravnava kot dogodek (ActionEvent),
zato mora okno ustrezati vmesniku actionListener().
GlavnoOkno.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import java.awt.*; // potrebujemo za Dimension import java.awt.event.*; // potrebujemo za ActionListener import javax.swing.*; // potrebujemo za Swing public class GlavnoOkno extends JFrame implements ActionListener { private JTextField besedilo; private JLabel naslov; private JButton narisiGumb; private Slika slika; private Dimension preferredSize = new Dimension(500, 300); public GlavnoOkno() { getContentPane().setLayout(new BorderLayout()); slika = new Slika(); getContentPane().add(slika, BorderLayout.CENTER); naslov = new JLabel("Krog"); getContentPane().add(naslov, BorderLayout.NORTH); JPanel p = new JPanel(); getContentPane().add(p, BorderLayout.SOUTH); p.add(new JLabel("r = ")); besedilo = new JTextField(20); p.add(besedilo); narisiGumb = new JButton("Narisi"); p.add(narisiGumb); narisiGumb.addActionListener(this); // ce uporabnik zapre okno, se program zakljuci setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // nastavimo naslov okna setTitle("Elipsa in krog"); } public Dimension getPreferredSize() { return preferredSize; } public void actionPerformed(ActionEvent e) { Object m = e.getSource();; if (m == narisiGumb) { try { double r = Double.parseDouble(besedilo.getText()); slika.nastaviPolmer(r); naslov.setText("Krog (r = " + r + ")"); } catch (NumberFormatException ex) { naslov.setText("Krog (neveljaven r)"); } } } } |
Slika
Razred Slika je podrazred JPanel, ki je
element podoben razredu Applet. To je splošen grafični
element, v katerega lahko rišemo in pišemo tako, da definiramo
metodo paintComponent(Graphics g) (v appletu se ta
metoda imenuje paint()). Kadar želimo na novo narisati
sliko, pokličemo metodo repaint(), kot v 9. vrstici.
Slika.java | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import javax.swing.*; import java.awt.*; public class Slika extends JPanel { private double r; public void nastaviPolmer(double q) { r = q; repaint(); } public void paintComponent(Graphics g) { int width = getWidth(); int height = getHeight(); g.setColor(Color.white); g.fillRect(0, 0, width, height); g.setColor(Color.red); g.fillOval(0, 0, width, height); g.setColor(Color.blue); g.fillOval(width/2 - (int)r, height/2 - (int)r, 2 * (int)r, 2 * (int)r); } } |