16. diel - Práca s vlastnými súbory v Jave - Zip archív
V minulej lekcii, Práca so súbormi a zložkami v Jave - Nové API , sme si ukázali prácu so súbormi a zložkami v Jave. Teraz už viete pracovať s množstvom druhov súborov, viete ich ukladať a otvárať, prehrávať, odchytávať chyby, ... Predstavte si však reálnu aplikáciu na evidenciu zamestnancov. Zamestnanec bude mať textové údaje (meno, priezvisko a email), dátum (dátum narodenia), číslo (telefónne číslo) a obrázok (fotografiu). Už len kvôli obrázku môže byť na prvý pohľad problém všetky tieto dáta uložiť a to ideálne do jedného jediného súboru. Teoreticky by sme mohli zvoliť nejaký binárny formát dát (kvôli obrázku) a vložiť do neho i textovej údaje. Prakticky sú binárne súbory pomerne nešikovné a zle sa s nimi reaguje na zmeny formátu.
Zips
Podobné aplikácie často využívajú na ukladanie dát archívy. Vezmite
si taký MS-Word a jeho dokumenty s príponou súborov .docx
. Keď
zmeníte príponu ľubovoľného .docx
súboru na
.zip
, zistíte, že dokument je v skutočnosti archív zips, len s
inou príponou. Skúste si to.
Windows skrývajú v predvolenom nastavení prípony známych
súborov, takže namiesto Dokument.docx
vidíte len
Dokument
. Nastavenie zmeníte v ovládacom paneli -> Zobraziť
podľa: Ikony -> Možnosti priečinka -> Zrušiť zatržítko Skryť
prípony známych typov.
Ako archív v sebe môže súbor obsahovať jednoducho niekoľko súborov a
navonok sa tvárou pre nič netušiaceho používateľa ako jeden. Presne
archívu zip využijeme aj k uloženiu nášho zamestnanca. A miesto
.zip
nastavíme súboru úplne inú príponu, ponúka zo
.zamestnanec
alebo ak sa chcete držať třípísmenných, tak len
.zam
.
Prípona súboru totiž slúžia len na to, aby operačný systém Windows
zistil v akej aplikácii má súbor otvoriť, keď na neho používateľ
poklepe. Väčšinou platí, že má každý súbor na konci názvu bodku a
3-písmenový príponu. V skutočnosti nemusí mať súbor príponu vôbec
žiadnu, môže ich mať viac, môžu byť dlhšie ako 3 znaky a dokonca nemusí
vôbec zodpovedať tomu, čo je v súbore uložené. My budeme súbor
.zip
maskovať ako súbor .zam
. Zips nenecháme z toho
dôvodu, aby to používateľa nezmátlo a nezačal súbory rozbaľovať a
meniť.
Formát súborov .zam
Štruktúra zazipované zložky by mohla byť nasledovné:
data.zam
zamestnanci.xml
obrazky/
jmenoprijmeni_1.png
jmenoprijmeni_2.png
zamestnanci.xml
by mohol vyzerať nasledovne:
<zamestnanci> <zamestnanec> <jmeno>Tomáš</jmeno> <prijmeni>Šeldosklepa</prijmeni> <email>[email protected]</email> <telefon>123456789</telefon> <narozeni>1.1.1970</narozeni> </zamestnanec> </zamestnanci>
Element <zamestnanci>
obaľujúca zamestnanca
je tu preto, že aplikácia môže niekedy v budúcnosti spracovávať viac
zamestnancov. Nad takými "drobnosťami" je potrebné pri návrhu
premýšľať.
Tvorba aplikácie Zamestnanec
Vytvorte si nový projekt, formulárové aplikáciu. Pod článkom je k dispozícii archív s projektom. V projekte už sú vygenerované všetky potrebné formulárové prvky a navěšené obsluhy tlačidiel.
Trieda Zamestnanec
Začneme tým, čo by malo byť jasné - vlastnosťami. Náš zamestnanec bude mať:
- meno,
- priezvisko,
- email,
- telefón,
- dátum narodenia
- a bude mať aj fotografiu:
public class Zamestnanec { private String jmeno; private String prijmeni; private String email; private String telefon; private LocalDate narozeniny; private BufferedImage obrazek; public Zamestnanec() { this("", "", "", "", LocalDate.now()); } public Zamestnanec(String jmeno, String prijmeni, String email, String telefon, LocalDate narozeniny) { this.jmeno = jmeno; this.prijmeni = prijmeni; this.email = email; this.telefon = telefon; this.narozeniny = narozeniny; } @Override public String toString() { return "Zamestnanec{" + "jmeno=" + jmeno + ", prijmeni=" + prijmeni + '}'; } }
Trieda má dva konštruktory. Prvý preťaženie vytvorí prázdneho zamestnanca. Pomocou druhého konstruktoru vytvoríme inštanciu zamestnanca so všetkými údajmi, okrem obrázku.
Getter a setter
Ďalej nasledujú iba Getter a setter pre tieto vlastnosti:
public String getJmeno() { return jmeno; } public void setJmeno(String jmeno) { this.jmeno = jmeno; } public String getPrijmeni() { return prijmeni; } public void setPrijmeni(String prijmeni) { this.prijmeni = prijmeni; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTelefon() { return telefon; } public void setTelefon(String telefon) { this.telefon = telefon; } public LocalDate getNarozeniny() { return narozeniny; } public void setNarozeniny(LocalDate narozeniny) { this.narozeniny = narozeniny; } public BufferedImage getObrazek() { return obrazek; } public void setObrazek(BufferedImage obrazek) { this.obrazek = obrazek; }
Do formulára si pridáme premennú typu Zamestnanec
, ale
nebudeme ju inštanciovať:
private Zamestnanec zamestnanec;
Správca zamestnancov
Aby sme dodržali oddelenie logiky a GUI, založíme si novú triedu, ktorá
sa bude starať o správu zamestnancov. Triedu nazvime jednoducho
SpravceZamestnancu
. Trieda bude obsahovať kolekciu zamestnancov.
Kolekcia bude typu DefaultListModel
, aby sme ju neskôr mohli
využiť pre viac zamestnancov.
private final DefaultListModel<Zamestnanec> zamestnanci = new DefaultListModel<>();
Ďalej vytvoríme v triede štyri metódy: uloz()
,
nacti()
, vratPrvniho()
a ulozPrvniho()
.
Metódy uloz()
a nacti()
budeme implementovať až v
nasledujúcej lekcii. Posledné dve metódy tu máme len pre jednoduchosť, aby
sme mohli pracovať s jedným zamestnancom. Ich implementácia bude
nasledujúci:
public Zamestnanec vratPrvniho() { return zamestnanci.size() == 0 ? new Zamestnanec() : zamestnanci.get(0); } public void ulozPrvniho(Zamestnanec zamestnanec) { this.zamestnanci.clear(); this.zamestnanci.addElement(zamestnanec); }
Úprava formulára
To by bolo zatiaľ v správcovi všetko. Presuňme sa ešte rýchlo do
formulára, kde vytvoríme inštanciu správcu a necháme si od neho
inštanciovať triedu Zamestnanec
:
private final SpravceZamestnancu spravce = new SpravceZamestnancu(); private Zamestnanec zamestnanec = spravce.vratPrvniho();
Ďalej do kódu formulára pridáme dve pomocné metódy, pomocou ktorých
budeme aktualizovať údaje na formulári a v inštanciu triedy
Zamestnanec
:
private void aktulizujFormular() { jTxtName.setText(zamestnanec.getJmeno()); jTxtSurname.setText(zamestnanec.getPrijmeni()); jTxtEmail.setText(zamestnanec.getEmail()); jTxtPhoneNumber.setText(zamestnanec.getTelefon()); jTxtBirthday.setText(Konstanty.FORMAT_DATA.format(zamestnanec.getNarozeniny())); jPanel1.getGraphics().drawImage(zamestnanec.getObrazek(), 0, 0, 123, 135, null); } private void nactiZFormulare() { zamestnanec.setJmeno(jTxtName.getText()); zamestnanec.setPrijmeni(jTxtSurname.getText()); zamestnanec.setEmail(jTxtEmail.getText()); zamestnanec.setTelefon(jTxtPhoneNumber.getText()); zamestnanec.setNarozeniny(LocalDate.parse(jTxtBirthday.getText(), Konstanty.FORMAT_DATA)); }
Obsluha tlačidiel
Nakoniec sa pozrieme na handlermi tlačidiel.
Výber obrázku
Prvý handler, na ktorý sa zameriame, je obsluha tlačidlá pre výber obrázku:
private void jBtnImageActionPerformed(java.awt.event.ActionEvent evt) { nactiZFormulare(); JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("Obrázky...", "png")); final int result = fileChooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { final File obrazek = fileChooser.getSelectedFile(); try { zamestnanec.setObrazek(ImageIO.read(obrazek)); aktulizujFormular(); } catch (IOException e) { e.printStackTrace(); } } }
Najskôr uložíme prípadné hodnoty z komponentov do inštancie triedy
Zamestnanec
. Ďalej vytvoríme nový JFileChooser
dialóg, pomocou ktorého vyberieme obrázok používateľa. Ak obrázok
vyberieme úspešne, metódou ImageIO.read()
načítame obrázok a
uložíme ho do zamestnanca. Nakoniec zavoláme metódu
aktualizujFormular()
, pomocou ktorej zobrazíme obrázok na
formulári.
Uloženie
Obsluha tlačidlá pre uloženie dát bude vyzerať nasledovne:
private void jBtnSaveActionPerformed(java.awt.event.ActionEvent evt) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("Soubory zaměstnanců...", "zam")); final int result = fileChooser.showSaveDialog(this); if (result == JFileChooser.APPROVE_OPTION) { final File souborZamestnancu = fileChooser.getSelectedFile(); try { nactiZFormulare(); spravce.ulozPrvniho(zamestnanec); spravce.uloz(souborZamestnancu); } catch (IOException | XMLStreamException e) { e.printStackTrace(); } } }
Pomocou JFileChooser
dialógu vyberieme súbor, do ktorého
chceme uložiť naše dáta. Ak súbor vyberieme, načítame dáta z formulára
do inštancie zamestnanca. Túto inštanciu odovzdáme do správcu, aby si
uložil dáta. Nakoniec metódou uloz()
zapíšeme všetky dáta do
súboru.
Načítanie
Nakoniec si ukážeme metódu pre načítanie dát:
private void jBtnLoadActionPerformed(java.awt.event.ActionEvent evt) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("Soubory zaměstnanců...", "zam")); final int result = fileChooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { final File souborZamestnancu = fileChooser.getSelectedFile(); try { spravce.nacti(souborZamestnancu); zamestnanec = spravce.vratPrvniho(); aktulizujFormular(); } catch (IOException | ParserConfigurationException | SAXException e) { e.printStackTrace(); } } }
V metóde opäť zobrazíme JFileChooser
dialóg pre výber
zamestnancov. Ak zvolíme súbor, zavoláme metódu nacti()
nad
inštanciu triedy SpravceZamestnancu
. Po úspešnom načítaní
zobrazíme dáta prvého zamestnanca na formulár.
Teraz máme aplikáciu navrhnutú. Nabudúce, v lekcii Práca s vlastnými súbory v Jave - Ukladanie a načítanie zips , sa už konečne pozrieme na samotné spracovávanie súborov ZIP v Jave a prvýkrát si vyexportuje a importuje zamestnanca.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 56x (43.15 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java