Lekce 4 - Upomínač narozenin v Java Swing - Návrh formulářů
V předešlém cvičení, Řešené úlohy k 1.-3. lekci Java Swing, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
V dnešním dílu začneme pracovat na aplikaci k upomínání narozenin přátel. Aplikace bude vypadat následovně:

Vytvoříme si novou Java aplikaci bez hlavní třídy s názvem Vyroci.
Návrh formuláře
Jako vždy začneme návrhem formuláře. Tentokrát již budeme mít v aplikaci dva.
Přehledový formulář
Přehledový formulář je základní okno aplikace s přehledem osob a jejich narozenin. K projektu přidáme nový JFrame Form, pojmenovaný PrehledJFrame. Nastavíme mu titulek na Výročí. Kód v jeho metodě main upravíme tak, aby se formulář zobrazoval centrovaný:
public void run() { PrehledJFrame prehledJFrame = new PrehledJFrame(); prehledJFrame.setLocationRelativeTo(null); prehledJFrame.setVisible(true); }
Mimochodem, všimněte si, že se formuláře pojmenovávají PascalCasem (první písmeno velké) a komponenty camelCasem. Je to proto, že formulář je třída a komponenty jsou instance.
Dále budeme potřebovat následující komponenty:
- 8x JLabel
- 2x JButton
- 1x JList
Labely
Labely rozmístěte jako na obrázku výše. Labelům na levé straně nastavíme text podle obrázku. Labelům na straně pravé text nastavovat nebudeme, ale nastavíme jim jméno, abychom text mohli později nastavit z kódu. Labely na pravé straně se budou jmenovat: dnesJLabel, nejblizsiJLabel, narozeninyJLabel, vekJLabel.
Tlačítka
Dva JButtony umístíme dolů a nastavíme jim text na Přidat a Odebrat. Asi vás nepřekvapí, že jejich názvy budou pridatJButton a odebratJButton. Tlačítkům můžeme přidat nějaké ikony, já jsem ty na obrázku našel na http://www.iconfinder.com, velikost je 32x32 pixelů. Soubory s obrázky umístíme do adresáře 'src/main/resources/'. Obrázek nastavíme pomocí vlastnosti Icon, kde klikneme na tlačítko "...". Nyní můžeme obrázek naimportovat z projektu nebo nahrát z externího umístění. Vybereme 'Image Within Project' a v roletkovém menu zvolíme příslušný obrázek.
JList
JList je v podstatě rozbalený JComboBox, se kterým jsme se seznámili v minulé lekci. Jinak funguje úplně stejně a my ho využijeme pro zobrazení seznamu osob. List pojmenujeme osobyJList.
Přidávací formulář
Druhý formulář bude sloužit k přidávání nových osob a bude mít následující podobu:

Formulář tentokrát nepřidáme k projektu jako JFrame Form, ale jako JDialog Form. Pokud v menu tuto možnost nemáte, musíte zvolit Other... a poté v sekci Swing GUI Forms vybrat právě JDialog Form.
Rozdíl mezi dialogem a formulářem je ten, že dialog je chápán jako jednoúčelový pomocný formulář, který slouží většinou k zadání určitých dat a poté se zas zavře. Z tohoto důvodu můžeme JDialog na rozdíl od JFrame označit jako modální. Modální dialog se zobrazí v popředí aplikace a celá aplikace následně čeká, až se zavře. To je velmi užitečné, můžeme tak např. zobrazit dialog k přidání osoby a poté obnovit vypsanou osobu. Po zobrazení modálního dialogu metoda čeká, až se zavře a teprve poté pokračuje dále, v našem případě tedy obnoví vypsanou osobu. Kdyby formulář nebyl modální, nedokázali bychom na jeho uzavření dost dobře reagovat. Někdy se nám také prostě jen hodí, že s aplikací nelze manipulovat se zobrazeným dialogem nebo že nelze zobrazit více dialogů najednou.
Modalitu dialogu můžeme také nastavit přímo v kódu pomocí
metody setModal()
.
Dialog pojmenujeme OsobaJDialog, titulek nastavíme na "Přidat osobu". NetBeans vám do zdrojového kódu JDialogu pravděpodobně vygeneroval metodu main, tu potřebovat nebudeme a tak ji celou odstraníme.
Do dialogu dále vložíme následující komponenty:
- 3x JLabel
- 1x JTextField
- 1x JFormattedTextField
- 1x JButton
JLabely
Dva JLabely zde slouží jen k popisu textových polí, čili jim pouze nastavte text podle obrázku výše a nemusíte je ani pojmenovávat. Třetí label slouží k zobrazení ikony nového uživatele, aby byl náš formulář uživatelsky přívětivější. Ikonu JLabelu nastavíte opět přes vlastnost icon.
Ikonu komponentě JLabel
můžeme nastavit i
přímo v kódu pomocí metody setIcon()
. Ta jako parametr
očekává instanci typu ImageIcon
.
label.setIcon(new ImageIcon(getClass().getResource("/add-user.png"));
Při vytváření instance ImageIcon
je potřeba
správně zadat, kde se má soubor hledat. Toto je velmi častý zdroj
chyb. V příkladu výše jsme použili konstrukci
getClass().getResource()
, která zjednodušeně řečeno odkazuje
tam, kde se nachází třída, ve které je tato konstrukce použita. Zde je
důležité pochopit, že mluvíme o zkompilované třídě
při běhu programu, neboli o souboru s koncovkou .class
. Projekt v
NetBeans důsledně odděluje zdrojové kódy (soubory s koncovkou
.java
) od zkompilovaných souborů s koncovkou .class
(ty umísťuje do adresáře build/
). Naštěstí je build proces
nastaven tak, aby do adresáře build/
zkopíroval úplně
všechno, co najde v adresáři se zdrojovými kódy, takže je zajištěno, že
pokud zde umístíme soubory s obrázky, budou při buildnutí aplikace
zkopírovány na správné místo a budou tam, kde mají být při spuštění
aplikace.
Text tomuto labelu vymažte, aby se nezobrazoval.
Změna velikosti obrázku pro použití v JLabel
Výše uvedené použití JLabel
pro zobrazení obrázku má
bohužel jedno velké omezení. Zřejmě velmi záhy zjistíte, že velikost
obrázku se nepřizpůsobuje velikosti JLabel
, ale tvrdošíjně
zůstává na své vlastní velikosti. Pokud JLabel
v návrháři
roztáhnete, vzniknou okolo obrázku prázdné okraje. Pokud JLabel
zmenšíte na velikost menší než velikost obrázku, uvidíte z obrázku jenom
výřez. Pokud máte obrázek předem připravený ve velikosti, v jaké ho
chcete zobrazit, tak jako my v našem příkladu, je to v pořádku. Pokud ale
potřebujete obrázek zvětšit či zmenšit, musíte to udělat "ručně"
přímo v kódu.
Řekněme, že máme velký obrázek obrazek.png
ve stejném
adresáři jako zdrojový kód třídy a chceme ho zmenšit na poloviční
velikost. Nejprve je potřeba vytvořit instanci ImageIcon
. V
dalším kroku z ní získáme obrázek Image
a z něj poté ikonu
s novými rozměry pomocí metody getScaledInstance()
:
ImageIcon original = new ImageIcon(getClass().getResource("/obrazek.png")); Image image = original.getImage(); ImageIcon resizedIcon = image.getScaledInstance(original.getIconWidth() / 2, original.getIconHeight() / 2, Image.SCALE_SMOOTH); // tento ImageIcon už můžeme použít v setIcon() label.setIcon(resizedIcon);
Třetí parametr metody getScaledInstance()
říká, jaký typ
algoritmu se má pro změnu velikosti použít.
JTextField
JTextField je jak asi tušíte pole, kam může uživatel aplikace zadat libovolný text. K účelu zadání jména je ideální. Někteří začátečníci ho používají i k zadávání čísel nebo datumů, což je ovšem špatně, jak jsme si již vysvětlili minule. TextField pojmenujte jmenoJTextField.
JFormattedTextField
Komponenta JFormattedTextField umožňuje zadat text podobně jako JTextField, ale udržuje určitý předepsaný formát. Pokud poté z programu čteme to, co uživatel zadal, je nám vždy vrácen smysluplný vstup.
Komponentu pojmenujeme narozeninyJFormattedTextField a přesuneme se do nastavení její vlastnosti formatterFactory:

Naleznete zde mnoho předpřipravených formátů pro zadávání čísel, data a času, procent a měny. My využijeme možnost custom z kategorie date, kam zadáme následující formát:
d.M.yyyy
Tím jsme určili, že se do TextFieldu bude zadávat datum ve formátu den.měsíc.rok. Formát lze vždy otestovat tlačítkem Test. Po potvrzení si komponenta sama hlídá zadaný formát a i když uživatel zadá nějaký nesmysl, např. 13. měsíc, vrátí vždy smysluplnou hodnotu.
JButton
Tlačítko k potvrzení dialogu pojmenujeme okButton a nastavíme mu text na OK.
Až aplikaci spustíte, nezapoměňte nastavit jako hlavní formulář prehledJFrame.
Formuláře máme připravené.
V příští lekci, Upomínač narozenin v Java Swing - Logická vrstva, si vytvoříme třídy s logikou aplikace. Naklikané formuláře jsou ke stažení níže.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 642x (16.18 kB)
Aplikace je včetně zdrojových kódů v jazyce Java