V aplikacφch s grafick²m u₧ivatelsk²m rozhranφm je obvyklΘ, ₧e uzav°enφm hlavnφho okna ukonΦφme celou aplikaci. V Jav∞ to ale - na rozdφl t°eba od Windows - neplatφ automaticky. Pokud v tomto jazyku programujete, jsou dalÜφ °ßdky prßv∞ pro vßs.
Okno je instance t°φdy java.awt.Frame nebo javax.swing.JFrame a uzav°enφ jakΘhokoli okna - a¥ je instancφ kterΘkoli z t∞chto t°φd nebo jejich potomk∙ - zp∙sobφ pouze jeho skrytφ, nic vφc. Program pob∞₧φ dßl a budeme ho muset ukonΦit nap°. stisknutφm kombinace Ctrl+C v konzolovΘm okn∞.
SouΦasnß Java ovÜem nabφzφ celkem t°i zp∙soby, jak za°φdit, aby p°i uzav°enφ okna odvozenΘho od JFrame skonΦila celß aplikace. Pro okna odvozenß od t°φdy Frame lze pou₧φt pouze druhΘ dva. Podφvejme se na mo₧nΘ postupy podrobn∞ji.
JDK 1.3
Asi nejjednoduÜÜφ zp∙sob nabφzφ JDK 1.3. T°φda JFrame v n∞m obsahuje metodu
public void setDefaultCloseOperation(int op);
kterΘ jako parametr m∙₧eme p°edat n∞kterou z konstant DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE a EXIT_ON_CLOSE. Poslednφ konstanta je definovßna p°φmo ve t°φd∞ JFrame, ostatnφ definice najdeme v rozhranφ javax.swing.WindowConstants (a byly k dispozici u₧ v JDK 1.2). Zavolßme-li tedy pro urΦitou instanci
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
uzav°enφ tohoto okna zp∙sobφ, ₧e aplikace skonΦφ. (V p°φpad∞ pot°eby je nutno doplnit identifikßtor JFrame cel²m jmΘnem balφku, tedy psßt javax.swing.JFrame.EXIT_ON_CLOSE.)
Vzhledem k tomu, ₧e aplikace m∙₧e vytvo°it vφce oken tΘ₧e t°φdy, volßme metodu setDefaultCloseOperation() typicky v mφst∞, kde okno vytvß°φme, nikoli v konstruktoru t°φdy okna.
Tato alternativa vypadß jednoduÜe a lßkav∞, ve skuteΦnosti se ale hodφ jen v situaci, kdy chceme po stisknutφ uzavφracφ ikony v zßhlavφ okna okam₧it∞ skonΦit - a to je mßlokdy. Zpravidla se p°edtφm chceme u₧ivatele programu zeptat, zda chce opravdu skonΦit, chceme zkontrolovat, zda jsou ulo₧eny soubory, v nich₧ doÜlo ke zm∞n∞, atd. A to takto nejde.
JDK 1.1
Patrn∞ nejΦast∞ji se pou₧φvß mo₧nost, kterß je k dispozici ji₧ od JDK 1.1 a kterß vypadß takto (p°edpoklßdßme, ₧e frame je instance p°edstavujφcφ hlavnφ okno aplikace):
frame.addWindowListener(
new java.awt.event.WindowAdapter(){
public void windowClosing(java.awt.event.WindowEvent e)
{
System.exit(0);
}
}
);
Zde zaregistrujeme novΘho posluchaΦe (p°φjemce) udßlostφ okna. P°φjemce t∞chto udßlostφ musφ, jak znßmo, implementovat rozhranφ java.awt.event.WindowListener; toto rozhranφ ovÜem obsahuje sedm metod a my pot°ebujeme jen jednu z nich - windowClosing(). Proto pou₧ijeme pomocnou t°φdu java.awt.event.WindowAdapter, kterß implementuje vÜechny metody rozhranφ, ovÜem jako prßzdnΘ (jejich t∞la neobsahujφ ₧ßdnΘ operace). Jako parametr metod∞ addWindowListener() p°edßme anonymnφ instanci anonymnφ vnit°nφ t°φdy, kterß je potomkem t°φdy WindowAdapter a ve kterΘ jsme p°edefinovali metodu windowClosing() (jedinou metodu, kterß nßs zajφmß). Tato metoda zavolß System.exit(0) a tφm ukonΦφ aplikaci. Sem lze vlo₧it operace, kterΘ zjistφ, zda chce u₧ivatel opravdu skonΦit atd.
Ve skuteΦnosti se obvykle pou₧φvß nepatrn∞ slo₧it∞jÜφ varianta tΘho₧ postupu, kterß ale zpravidla vede k p°ehledn∞jÜφmu programu. Z t∞la metody windowClosing() zavolßme metodu, kterou nazveme nap°. slus() a kterß se postarß o vÜe pot°ebnΘ:
frame.addWindowListener(
new java.awt.event.WindowAdapter(){
public void windowClosing(java.awt.event.WindowEvent e)
{
slus();
}
}
);
public void slus() {
// ...ukonΦovacφ operace
}
TakovΘto uspo°ßdßnφ umo₧nφ mj. pou₧φt tutΘ₧ metodu slus() i pro ukonΦenφ aplikace p°φkazem z nabφdky, p°i stisknutφ tlaΦφtka ap.
VÜimn∞te si, ₧e slus() je metoda t°φdy, ve kterΘ se p°φjemce udßlostφ registruje, nikoli metoda tohoto p°φjemce. P°esto ji v metod∞ windowClosing(), tedy v metod∞ p°φjemce, volßme, ani₧ bychom ji museli kvalifikovat jmΘnem instance. To proto, ₧e metody vnit°nφ t°φdy majφ v Jav∞ pln² p°φstup ke slo₧kßm a metodßm vn∞jÜφ t°φdy (bez ohledu na p°φstupovß prßva).
Poznamenejme, ₧e s tφmto zp∙sobem ukonΦenφ aplikace p°i uzav°enφ hlavnφho okna se setkßme v automaticky generovanΘm k≤du v n∞kter²ch javsk²ch v²vojov²ch nßstrojφch - nap°. ve Forte for Java od firmy Sun.
Uveden² postup m∙₧e mφt mnoho variant. M∙₧eme nap°. pou₧φt pojmenovanou instanci pojmenovanΘ vnit°nφ t°φdy. Lze si takΘ p°edstavit, ₧e t°φda okna implementuje rozhranφ WindowListener a zaregistruje se jako posluchaΦ; pak ovÜem bude muset implementovat vÜechny metody tohoto rozhranφ, i kdy₧ je nebude pot°ebovat. V²sledn² k≤d vÜak nebude zpravidla p°φliÜ p°ehledn².
JDK 1.0
Na konec jsme si ponechali mo₧nost, kterß se pou₧φvala u₧ v JDK 1.0 (a je k dispozici dodnes), i kdy₧ je asi nejmΘn∞ Üikovnß. Zde musφme do konstruktoru t°φdy okna p°idat p°φkaz
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
jφm₧ povolujeme vznik udßlostφ v okn∞. Krom∞ toho musφme ve t°φd∞ okna p°edefinovat zd∞d∞nou metodu processWindowEvent(), kterß tuto udßlost zpracuje:
Parametrem tΘto metody je instance t°φdy java.awt.event.WindowEvent, kterß v sob∞ nese mj. informaci o druhu udßlosti. Tuto udßlost musφme nejprve p°edat metod∞ p°edka; teprve pak pomocφ metody getID() zjistφme, zda jde o uzav°enφ okna, a pokud ano, ukonΦφme program.
S touto mo₧nostφ se setkßme v automaticky generovanΘm k≤du v n∞kter²ch v²vojov²ch nßstrojφch (nap°. ve vÜech dosavadnφch verzφch JBuilderu od firmy Borland, a to vzdor tomu, ₧e poslednφ verze JBuilderu pou₧φvajφ JDK 1.3).
Poznamenejme, ₧e povolovßnφ udßlostφ je nezbytnΘ pouze u t°φd odvozen²ch od java.awt.Frame. Pro instance t°φd odvozen²ch od javax.swing.JFrame jsou udßlosti automaticky povoleny, tak₧e volßnφ metody enableEvents() je zbyteΦnΘ. O tom se m∙₧eme p°esv∞dΦit pomocφ nßsledujφcφho progrßmku:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Vokno extends JFrame {
public Vokno() {
//enableEvents(AWTEvent.WINDOW_EVENT_MASK);
}
protected void processWindowEvent(WindowEvent e)
{
super.processWindowEvent(e);
if(e.getID() == WindowEvent.WINDOW_CLOSING)
{
System.exit(0);
}
}
public static void main(String[] args) {
Vokno vokno1 = new Vokno();
vokno1.setVisible(true);
}
}
Tento program pouze vytvo°φ instanci t°φdy Vokno a zobrazφ ji. Proto₧e jsme t°φdu Vokno odvodili od JFrame, nevadφ, ₧e je volßnφ metody enableEvents() v komentß°i; po stisknutφ tlaΦφtka s k°φ₧kem v pravΘm hornφm rohu okna program skonΦφ. Nahradφme-li vÜak t°φdu JFrame t°φdou Frame a ponechßme-li volßnφ metody enableEvents() v komentß°i, budeme program muset ukonΦit stisknutφm kombinace Ctrl+C v okn∞ javskΘ konzoly.