Table of Contents
Stromy
Podobně jako v první kapitole vytvoříme nový projekt, nazveme ho Tree.
Přidáme JFrame pojmenovaný TreeWindow.
( A můžeme odstranit původní třídu Tree. )
Do TreeWindow přidáme z palety prvek Tree, vytvořenému prvku ponecháme identifikátor jTree1.
Vytvoříme kořen stromu
DefaultMutableTreeNode root = new DefaultMutableTreeNode ("first");
Pod kořenový prvek přidáme další prvek stromu
DefaultMutableTreeNode node = new DefaultMutableTreeNode ("second"); root.add (node);
DefaultMutableTreeNode root = new DefaultMutableTreeNode ("first");
Prvky stromu budou typu javax.swing.tree.DefaultMutableTreeNode .
Na začátek programu přidáme import javax.swing.tree.*;
Na misto DefaultMutableTreeNode můžeme v NetBeans napsat velkými písmeny DMTN a stisknout Ctrl+Mezera
Vytvoříme “model” (třídu dodávající data našemu stromu)
DefaultTreeModel model = new DefaultTreeModel (root); jTree1.setModel (model);
Tím máme jednodychý strom se dvěma prvky vytvořen
package tree; import javax.swing.*; import javax.swing.tree.*; public class TreeWindow extends javax.swing.JFrame { DefaultMutableTreeNode root; DefaultTreeModel model; public TreeWindow() { initComponents(); root = new DefaultMutableTreeNode ("first"); DefaultMutableTreeNode node = new DefaultMutableTreeNode ("second"); root.add (node); model = new DefaultTreeModel (root); jTree1.setModel (model); } }
Menu
Z palety ze skupiny Swing Menus přidáme do našeho okna MenuBar.
Na záložce Navigator v kontextovém menu vyvolaném pravou myší vybereme change variable name a přejmenujeme na mainMenu
Položky hlavního menu můžeme přejmenovat na fileMenu a editMenu.
Pravou myší “klikneme” na menu File, z kontextov0ho menu vybereme Add From Palette a Menu Item.
- Položku přejmenujeme na quitMenuItem
- Nastavíme text na Quit.
- Můžeme nastavit mnemonic na Q
- accelerator nastavíme na Ctrl+Q
Podobně do menu Edit přidáme také Menu Item
- Položku přejmenujeme na addMenuItem
- Nastavíme text na Add Tree Item
- Můžeme nastavit mnemonic na A
- accelerator nastavíme na F7
Nakonec do Edit přidáme Menu Item
- Položku přejmenujeme na editMenuItem
- Nastavíme text na Edit Tree Item
- Můžeme nastavit mnemonic na E
- accelerator nastavíme na F8
V menu vybereme položku Quit.
Potom se v Properties přepneme na Events.
Vybereme řádku actionPerformed.
Do druhého sloupce napíšeme název funkce quickClick a stiskneme Enter
Do vzniklé funkce jen dopíšeme dispose (); , což uzavře naše okno a tím se ukončí náš program.
( Můžeme se podívat, že TreeWindow má nastavenu vlastnost defaultCloseOperation na EXIT_ON_CLOSE )
private void quitClick(java.awt.event.ActionEvent evt) { dispose (); }
Přidáme funkci getNode, kterou napíšeme celou včetně hlavičky (není to reakce na událost).
getNode zjistí právě vybraný prvek stromu (a nebo vrátí null)
private DefaultMutableTreeNode getNode () { return (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent (); }
Vložení prvku do stromu
Na položku menu Add Tree Item připojíme funkci addClick (podobě jako jsme připojovali funkci k položce Quit)
- node je právě vybraný prvek stromu
- item bude nově vytvořený prvek stromu
- nový prvek přidáme pod původní prvek node.add (item);
- pokud je strom již zobrazen na obrazovce, funkce model.nodesWereInserted upozorní okno, že je třeba zobrazit nový prvek
private void addClick(java.awt.event.ActionEvent evt) { DefaultMutableTreeNode node = getNode (); if (node != null) { DefaultMutableTreeNode item = new DefaultMutableTreeNode ("new item"); node.add (item); model.nodesWereInserted (node, new int [] {node.getIndex (item)}); } }
Editování prvku stromu
Na položku menu Edit Tree Item připojíme funkci editClick
- node je právě vybraný prvek stromu
- statická metoda showInputDialog ze třídy JOptionPane se uživatele zeptá na nové z třídy a uloží ho do proměnné name
- Text vložíme do původního prvky stromu node.setUserObject (name);
- funkce model.nodeChanged upozorní okno na změny
private void editClick(java.awt.event.ActionEvent evt) { DefaultMutableTreeNode node = getNode (); if (node != null) { String name = JOptionPane.showInputDialog (this, "enter new name"); node.setUserObject (name); model.nodeChanged (node); } }
Reakce na pohyb ve stromu
V “design režimu” našeho okna vybereme strom jTree1, z kontextového menu vybereme Events, Tree Selecttion a valueChanged
Pokud uživatel “klikne” na prvek stromu, pomocí setTitle zobrazíme text ze stromu jako nadpis na horním okraji našeho okna
private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent (); if (node != null) { setTitle (node.toString()); } }
Všechny přidané funkce
private void quitClick(java.awt.event.ActionEvent evt) { dispose (); } private DefaultMutableTreeNode getNode () { return (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent (); } private void addClick(java.awt.event.ActionEvent evt) { DefaultMutableTreeNode node = getNode (); if (node != null) { DefaultMutableTreeNode item = new DefaultMutableTreeNode ("new item"); node.add (item); model.nodesWereInserted (node, new int [] {node.getIndex (item)}); } } private void editClick(java.awt.event.ActionEvent evt) { DefaultMutableTreeNode node = getNode (); if (node != null) { String name = JOptionPane.showInputDialog (this, "enter new name"); node.setUserObject (name); model.nodeChanged (node); } } private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) { DefaultMutableTreeNode node = getNode (); if (node != null) { setTitle (node.toString()); } }
Strom se jmény souborů
Vyuužijeme třídu java.io.File
import java.io.*;
Vytvoříme objekt typu File, konstruktoru předáme jako parametr dvě tečky označující nadřazený adresář
Funkce f.getCanonicalFile () vrátí jiný objekt typu File, ve kterém bude uloženo skutečné jméno souboru
getCanonicalFile může způsobit výjimku, v Javě ji musíme zachytit pomocí try catch.
Pokud se převod jména nepovede, catch nedělá v našem případě vůbec nic a v proměnné f zůstane odkaz na soubor s dvěmi tečkami
/* root = new DefaultMutableTreeNode ("first"); DefaultMutableTreeNode node = new DefaultMutableTreeNode ("second"); root.add (node); */ File f = new File (".."); try { f = f.getCanonicalFile (); // prevedeme .. na opravdove jmeno adresare } catch (IOException ex) { } root = showFile (f);
Funkce showFile vytvoří uzel ve stromu se jménem souboru (bez jména adresáře).
Pokud je soubor adresářem, funkce listItems vrátí pole objektů typu File představující soubory v daném adresáři.
Pro jednotlivé soubory for (File t : items) opět zavoláme showFile a vzniklé uzly přidáme do stromu.
private DefaultMutableTreeNode showFile (File f) { DefaultMutableTreeNode node = new DefaultMutableTreeNode (f.getName()); if (f.isDirectory()) { File [] items = f.listFiles(); for (File t : items) { node.add (showFile (t)); } } return node; }