IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 19 - Práce s vlastními soubory v Javě - Zip archiv

V minulé lekci, Práce se soubory a složkami v Javě - Nové API, jsme si ukázali práci se soubory a složkami v Javě.

Nyní již umíte pracovat se spoustou druhů souborů, umíte je ukládat a otevírat, přehrávat, odchytávat chyby, ... Představte si ovšem reálnou aplikaci k evidenci zaměstnanců. Zaměstnanec bude mít textové údaje (jméno, příjmení a email), datum (datum narození), číslo (telefonní číslo) a obrázek (fotografii). Už jen kvůli obrázku může být na první pohled problém všechna tato data uložit a to ideálně do jednoho jediného souboru. Teoreticky bychom mohli zvolit nějaký binární formát dat (kvůli obrázku) a vložit do něj i textové údaje. Prakticky jsou binární soubory poměrně nešikovné a špatně se s nimi reaguje na změny formátu.

Zip

Podobné aplikace často využívají k ukládání dat archivy. Vezměte si takový MS-Word a jeho dokumenty s příponou souborů .docx. Když změníte příponu libovolného .docx souboru na .zip, zjistíte, že dokument je ve skutečnosti archiv zip, pouze s jinou příponou. Zkuste si to.

Windows skrývají ve výchozím nastavení přípony souborů známých typů, takže místo Dokument.docx vidíte jen Dokument. Nastavení změníte v Ovládacích panelech -> Zobrazit podle: Ikony -> Možnosti složky -> Zrušit zatržítko Skrýt přípony známých typů.

Jako archiv v sobě může soubor obsahovat jednoduše několik souborů a navenek se tváří pro nic netušícího uživatele jako jeden. Přesně archivu zip využijeme i k uložení našeho zaměstnance. A místo .zip nastavíme souboru úplně jinou příponu, nabízí ze .zamestnanec nebo pokud se chcete držet třípísmenných, tak jen .zam.

Přípona souboru totiž slouží jen k tomu, aby operační systém Windows zjistil v jaké aplikaci má soubor otevřít, když na něj uživatel poklepe. Většinou platí, že má každý soubor na konci svého názvu tečku a třípísmennou příponu. Ve skutečnosti nemusí mít soubor příponu vůbec žádnou, může jich mít více, mohou být delší než 3 znaky a dokonce nemusí vůbec odpovídat tomu, co je v souboru uložené. My budeme soubor .zip maskovat jako soubor .zam. Zip neponecháme z toho důvodu, aby to uživatele nezmátlo a nezačal soubory rozbalovat a měnit.

Formát souborů .zam

Struktura zazipované složky by mohla být následující:

  • data.zam
    • zamestnanci.xml
    • obrazky/
      • jmenoprijmeni_1.png
      • jmenoprijmeni_2.png

Soubor zamestnanci.xml by mohl vypadat následovně:

<zamestnanci>
    <zamestnanec>
        <jmeno>Tomáš</jmeno>
        <prijmeni>Šeldosklepa</prijmeni>
        <email>[email protected]</email>
        <telefon>123456789</telefon>
        <narozeni>1.1.1970</narozeni>
    </zamestnanec>
</zamestnanci>

Element <zamestnanci> obalující zaměstnance je zde proto, že aplikace může někdy v budoucnu zpracovávat více zaměstnanců. Nad takovými "drobnostmi" je potřeba při návrhu přemýšlet.

Tvorba aplikace Zamestnanec

Vytvořte si nový projekt, formulářovou aplikaci. Pod článkem je k dispozici archiv s projektem. V projektu již jsou vygenerované všechny potřebné formulářové prvky a navěšeny obsluhy tlačítek.

Formulář pro správu zaměstnanců v Javě - Soubory v Javě

Třída Zamestnanec

Začneme tím, co by mělo být jasné - vlastnostmi. Náš zaměstnanec bude mít:

  • jméno,
  • příjmení,
  • email,
  • telefon,
  • datum narození
  • a bude mít i fotografii:
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 + '}';
    }
}

Třída má dva konstruktory. První přetížení vytvoří prázdného zaměstnance. Pomocí druhého konstruktoru vytvoříme instanci zaměstnance se všemi údaji, kromě obrázku.

Gettery a settery

Dále následují pouze gettery a settery pro tyto 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áře si přidáme proměnnou typu Zamestnanec, ale nebudeme ji instancovat:

private Zamestnanec zamestnanec;

Správce zaměstnanců

Abychom dodrželi oddělení logiky a GUI, založíme si novou třídu, která se bude starat o správu zaměstnanců. Třídu nazvěme jednoduše SpravceZamestnancu. Třída bude obsahovat kolekci zaměstnanců. Kolekce bude typu DefaultListModel, abychom ji později mohli využít pro více zaměstnanců.

private final DefaultListModel<Zamestnanec> zamestnanci = new DefaultListModel<>();

Dále vytvoříme ve třídě čtyři metody: uloz(), nacti(), vratPrvniho() a ulozPrvniho(). Metody uloz() a nacti() budeme implementovat až v následující lekci. Poslední dvě metody tu máme pouze pro jednoduchost, abychom mohli pracovat s jedním zaměstnancem. Jejich implementace bude následující:

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áře

To by bylo prozatím ve správci vše. Přesuňme se ještě rychle do formuláře, kde vytvoříme instanci správce a necháme si od něj instancovat třídu Zamestnanec:

private final SpravceZamestnancu spravce = new SpravceZamestnancu();
private Zamestnanec zamestnanec = spravce.vratPrvniho();

Dále do kódu formuláře přidáme dvě pomocné metody, pomocí kterých budeme aktualizovat údaje na formuláři a v instanci třídy 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čítek

Nakonec se podíváme na handlery tlačítek.

Výběr obrázku

První handler, na který se zaměříme, je obsluha tlačítka pro výběr 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();
        }
    }
}

Nejdříve uložíme případné hodnoty z komponent do instance třídy Zamestnanec. Dále vytvoříme nový JFileChooser dialog, pomocí kterého vybereme obrázek uživatele. Pokud obrázek vybereme úspěšně, metodou ImageIO.read() načteme obrázek a uložíme ho do zaměstnance. Nakonec zavoláme metodu aktualizujFormular(), pomocí které zobrazíme obrázek na formuláři.

Uložení

Obsluha tlačítka pro uložení dat bude vypadat následovně:

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();
        }
    }
}

Pomocí JFileChooser dialogu vybereme soubor, do kterého chceme uložit naše data. Pokud soubor vybereme, načteme data z formuláře do instance zaměstnance. Tuto instanci předáme do správce, aby si uložil data. Nakonec metodou uloz() zapíšeme veškerá data do souboru.

Načtení

Nakonec si ukážeme metodu pro načtení dat:

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 metodě opět zobrazíme JFileChooser dialog pro výběr zaměstnanců. Pokud zvolíme soubor, zavoláme metodu nacti() nad instanci třídy SpravceZamestnancu. Po úspěšném načtení zobrazíme data prvního zaměstnance na formulář.

Nyní máme aplikaci navrženou.

V následujícím kvízu, Kvíz - Práce se soubory a složkami v Javě, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

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 56x (43.15 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Práce se soubory a složkami v Javě - Nové API
Všechny články v sekci
Soubory v Javě
Přeskočit článek
(nedoporučujeme)
Kvíz - Práce se soubory a složkami v Javě
Článek pro vás napsal Petr Štechmüller
Avatar
Uživatelské hodnocení:
16 hlasů
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity