Zadanie programistyczne:
Stworzyć strukturę drzewiasta do opisania na przykład:
– układu folderów i zawartych w nich plików
– struktury zatrudnienia w firmie: szef i podlegli pracownicy
– struktury wojskowej: dowódcy i żołnierze z których jeden jest liściem (np. pracownik) i nie może mieć podwładnych a drugi jest szefem i ma podwładnych.
Rozwiązanie:
- stworzyć klasę abstrakcyjna
AbstractPracownik
- dodać klasę 'gałęzi’ –
Szef
- dodać klasę 'liścia’ –
Pracownik
- stworzyć klasę pozwalającą na pokazanie drzewka podległości –
DrzewkoPodleglosci
Uwagi: Ten przykład jest silnie wzorowany na przykładzie z książki J. W. Coopera 2001. Java. Wzorce projektowe. Wyd. Helion, Gliwice.
Klasy
Klasa AbstractPracownik
package composite; import java.util.Enumeration; import java.util.NoSuchElementException; public abstract class AbstractPracownik { protected String nazwisko; protected long pensja; protected Pracownik kierownik = null; protected boolean podwladny = true; public abstract long getPensja(); public abstract String getNazwisko(); public abstract boolean add(Pracownik pracownik) throws NoSuchElementException; public abstract void remove(Pracownik pracownik) throws NoSuchElementException; public abstract Enumeration<Pracownik> podwladni(); public abstract Pracownik getPodwladny(String podwladny); public abstract long getPensje(); public boolean jestPodwladnym() { return podwladny; } }
DrzewkoPodleglosci
package composite; import javax.swing.*; import javax.swing.border.BevelBorder; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; public class DrzewkoPodleglosci extends JFrame implements TreeSelectionListener { private static final long serialVersionUID = 4432519732860863315L; Pracownik prac1, prac2, prac3; Pracownik prac4, prac5; Pracownik prac6, prac7; JScrollPane sp; JPanel treePanel; JTree tree; DefaultMutableTreeNode troot; JLabel cost; public DrzewkoPodleglosci() { super("Drzewko podleglości"); makeEmployees(); String laf = UIManager.getSystemLookAndFeelClassName(); try { UIManager.setLookAndFeel(laf); } catch (UnsupportedLookAndFeelException exc) { System.err.println("Ostrzeżenie: brak " + laf); } catch (Exception exc) { System.err.println("Błąd ładowania " + laf + ": " + exc); } setGUI(); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } // -------------------------------------- private void setGUI() { treePanel = new JPanel(); getContentPane().add(treePanel); treePanel.setLayout(new BorderLayout()); sp = new JScrollPane(); treePanel.add("Center", sp); treePanel.add("South", cost = new JLabel(" ")); treePanel.setBorder(new BevelBorder(BevelBorder.RAISED)); troot = new DefaultMutableTreeNode(prac1.getNazwisko()); tree = new JTree(troot); tree.setBackground(Color.lightGray); loadTree(prac1); sp.getViewport().add(tree); setSize(new Dimension(200, 300)); setVisible(true); } // ------------------------------------ public void loadTree(Pracownik topDog) { DefaultMutableTreeNode troot; troot = new DefaultMutableTreeNode(topDog.getNazwisko()); treePanel.remove(tree); tree = new JTree(troot); tree.addTreeSelectionListener(this); sp.getViewport().add(tree); addNodes(troot, topDog); tree.expandRow(0); repaint(); } // -------------------------------------- private void addNodes(DefaultMutableTreeNode pnode, Pracownik emp) { DefaultMutableTreeNode node; Enumeration<Pracownik> e = emp.podwladni(); if (e != null) { while (e.hasMoreElements()) { Pracownik newEmp = e.nextElement(); node = new DefaultMutableTreeNode(newEmp.getNazwisko()); pnode.add(node); addNodes(node, newEmp); } } } // -------------------------------------- private void makeEmployees() { prac1 = new Szef("Smok Marszałek", 200000); prac1.add(prac2 = new Szef("Dowódca Armii Ludowej", 100000)); prac1.add(prac3 = new Szef("Dowódca Floty", 100000)); prac2.add(prac4 = new Szef("Dowódca Robotów", 50000)); prac2.add(prac5 = new Szef("Dowódca Tajnych Agentów", 50000)); // add salesmen reporting to sales manager for (int i = 0; i < 5; i++) prac4.add(new Pracownik("Oficer " + i, rand_sal(30000))); prac5.add(new Pracownik("Smok 007", 20000)); prac3.add(prac6 = new Szef("Dowodca Floty Morskiej", 40000)); prac3.add(prac7 = new Szef("Dowodca Floty Powietrznej", 35000)); // add manufacturing staff for (int i = 0; i < 4; i++) prac6.add(new Pracownik("Kapitan " + i, rand_sal(25000))); // add shipping clerks for (int i = 0; i < 3; i++) prac7.add(new Pracownik("Pilot " + i, rand_sal(20000))); } // -------------------------------------- private long rand_sal(long salary) { return salary + (long) (Math.random() - 0.5) * salary / 5; } // -------------------------------------- @Override public void valueChanged(TreeSelectionEvent evt) { TreePath path = evt.getPath(); String selectedTerm = path.getLastPathComponent().toString(); Pracownik emp = prac1.getPodwladny(selectedTerm); if (emp != null) cost.setText(Float.valueOf(emp.getPensje()).toString()); } // -------------------------------------- static public void main(String argv[]) { new DrzewkoPodleglosci(); } }
Pracownik
package composite; import java.util.Enumeration; import java.util.NoSuchElementException; import java.util.Vector; public class Pracownik extends AbstractPracownik { public Pracownik(String nazwisko, long pensja) { this.nazwisko = nazwisko; this.pensja = pensja; podwladny = true; } // -------------------------------------- public Pracownik(Pracownik kierownik, String nazwisko, long pensja) { this.nazwisko = nazwisko; this.pensja = pensja; this.kierownik = kierownik; podwladny = true; } // -------------------------------------- @Override public long getPensja() { return pensja; } // -------------------------------------- @Override public String getNazwisko() { return nazwisko; } // -------------------------------------- @Override public boolean add(Pracownik pracownik) throws NoSuchElementException { throw new NoSuchElementException("Brak podwładnych"); } // -------------------------------------- @Override public void remove(Pracownik pracownik) throws NoSuchElementException { throw new NoSuchElementException("Brak podwładnych"); } // -------------------------------------- @Override public Enumeration<Pracownik> podwladni() { Vector<Pracownik> v = new Vector<>(); return v.elements(); } // -------------------------------------- @Override public Pracownik getPodwladny(String podwladny) throws NoSuchElementException { throw new NoSuchElementException("Bez potomków"); } // -------------------------------------- @Override public long getPensje() { return pensja; } // -------------------------------------- public Pracownik getKierownik() { return kierownik; } }
Szef
package composite; import java.util.Enumeration; import java.util.NoSuchElementException; import java.util.Vector; public class Szef extends Pracownik { final Vector<Pracownik> podwladni; public Szef(String nazwisko, long pensja) { super(nazwisko, pensja); podwladny = false; podwladni = new Vector<>(); } // -------------------------------------- public Szef(Pracownik kierownik, String nazwisko, long pensja) { super(kierownik, nazwisko, pensja); podwladny = false; podwladni = new Vector<>(); } // -------------------------------------- public Szef(Pracownik pracownik) { super(pracownik.getNazwisko(), pracownik.getPensja()); podwladni = new Vector<>(); podwladny = false; } // -------------------------------------- @Override public boolean add(Pracownik pracownik) throws NoSuchElementException { podwladni.add(pracownik); return true; } // -------------------------------------- @Override public void remove(Pracownik pracownik) throws NoSuchElementException { podwladni.removeElement(pracownik); } // -------------------------------------- @Override public Enumeration<Pracownik> podwladni() { return podwladni.elements(); } // -------------------------------------- @Override public Pracownik getPodwladny(String podwladny) throws NoSuchElementException { Pracownik nowyPracownik = null; if (getNazwisko().equals(podwladny)) return this; else { boolean znaleziony = false; Enumeration<Pracownik> pracownicy = podwladni(); while (pracownicy.hasMoreElements() && (!znaleziony)) { nowyPracownik = pracownicy.nextElement(); znaleziony = nowyPracownik.getNazwisko().equals(podwladny); if (!znaleziony) { if (!nowyPracownik.jestPodwladnym()) { nowyPracownik = nowyPracownik.getPodwladny(podwladny); } else nowyPracownik = null; znaleziony = (nowyPracownik != null); } } if (znaleziony) return nowyPracownik; else return null; } } // -------------------------------------- @Override public long getPensje() { long suma = pensja; for (int i = 0; i < podwladni.size(); i++) { suma += (podwladni.elementAt(i)).getPensje(); } return suma; } }
Wynik
Po uruchomieniu klasy DrzewkoPodleglosci
otrzymamy na konsoli: