Java a základy GUI #5 – InternalFrame
Program, který nemá grafické rozhraní, nikdy nemůže konkurovat programu s grafickým rozhraním. V tomto již 5. článku na téma GUI si řekneme něco o InternalFrame.
Internal Frames, neboji vnitřní okna, mohou být u grafického rozhraní dost často používaným elementem.
Jedná se o okna, které jsou vkládány do některého dalšího elementu, například panelu a tímto panelem omezeny. V praxi to vypadá tak, že okno vytvořené jako InternalFrame se nedostane za hranice elementu, ve kterém je umístěno.
InternalFrame
Použití InternalFrames je stejné jako například použití Frame (importujeme JFrame z javax.swing a dědíme JFrame k třídě s rozhraním), jenom v tomto případě potřebujeme importovat javax.swing.JInternalFrame a ke třídě dědíme JInternalFrame.
Tím nám vzniká okno, kterému můžeme stejně jako u JFrame nastavit například rozměry, velikost, titulek a podobně.
Otevřené okno je pouze omezeno elementem, do kterého je přidáno, ale chová se jako klasické okno, můžeme jej přesouvat, měnit velikost (toto záleží na nastavení, ke kterému se dostanu), nebo třeba minimalizovat.
Příprava hlavního okna
Vytvoříme si jednoduchý příklad, ze kterého bude použití InternalFrame snad všem jasné.
Jako první si musíme připravit okno, do kterého budeme naše vnitřní okno vkládat. Vytvoříme si klasické JFrame Window, ve kterém si dále vytvoříme Jpanel, do kterého přidáme JDesktopPane. Tento JDesktopPane bude sloužit právě pro zobrazování vnitřních oken.
Celému oknu nastavíme větší velikost, abychom do něj mohli vkládat další okna:
1 2 3 4 5 6 7 8 9 10 11 12 |
public class GUI extends JFrame{ private final JDesktopPane desktop = new JDesktopPane(); public JPanel contentPane; public GUI() { setTitle("Window"); setSize(new Dimension( 800, 800) ); setVisible(true); contentPane = (JPanel) getContentPane(); contentPane.add(desktop, BorderLayout.CENTER); } } |
Tím máme vytvořené prázdné okno o rozměrech 800×800, ve kterém je JDesktopPane.
Konečně se můžeme vrhnout do vytvoření „vnitřního okna“. Jak jsem již napsal, je to stejné jako vytvoření JFrame, jenom s drobnými odlišnostmi.
Vytvoříme jej tak, že dědíme JInternalFrame z javax.swing:
1 2 3 4 5 6 7 |
import javax.swing.JInternalFrame; public class Frame1 extends JInternalFrame { public Frame1() { setSize(100, 100); setVisible(true); } } |
Vidíte že použití je stejné jako u Frame, jenom s tím rozdílem že dědíme jinou třídu.
Základní nastavení okna
Hned na začátku se InternalFrame ale od klasického okna Frame liší. Internal Frame Window můžeme jednoduše nastavit jeho základní vlastnosti. Tyto vlastnosti se týkají práce s oknem a to konkrétně horní lišty pro práci s oknem (minimalizace, zavření okna, maximalizace) a změny rozměrů okna.
Všechny tyto vlastnosti nastavujeme voláním Super(), jehož prvním parametrem je nastavení titulku okna a dalšími parametry změna vlastností dosazením true/false a to v tomto pořadí:
- změna rozměrů
- zavření okna křížkem
- maximalizace okna
- minimalizace okna
Všechny tyto parametry jsou nepovinné, to znamená že je nemusíte všechny zadávat:
1 2 3 4 5 6 |
//nelze maximalizovat super("Window", true, true, false, true); //nelze zavřít křížkem super("Window", true, false ); //nelze měnit velikost, nelze zavřít křížkem, nelze maximalizovat super("Window", false, false, false); |
Ovšem v případě že nejsou parametry zadány jsou brány jako FALSE.
Nyní již můžeme vytvořit celé okno:
1 2 3 4 5 6 7 8 |
import javax.swing.JInternalFrame; public class Frame1 extends JInternalFrame { public Frame1() { super("Window", false, true, true, true); setSize(200, 200); setVisible(true); } } |
Pokud je hotovo, vrátíme se do třídy GUI, kde máme hotový JFrame a připravený JDesktopPane pro vkládání oken. V této třídě už pouze vytvoříme novou instanci třídy Frame1 a přidáme ji do JdesktopPane:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class GUI extends JFrame{ private final JDesktopPane desktop = new JDesktopPane(); public JPanel contentPane; public GUI() { setTitle("Window"); setSize(new Dimension( 800, 800) ); setVisible(true); contentPane = (JPanel) getContentPane(); contentPane.add(desktop, BorderLayout.CENTER); JInternalFrame c = new Frame1(); desktop.add(c, BorderLayout.SOUTH); } } |
Po zkompilování a spuštění by mělo vzniknout velké okno JFrame, ve kterém bude zobrazeno jedno okno malé ve formě právě JInternalFrame.
Základní práce s InternalFrame
Pro přístup k otevřeným oknům nám java nabízí metodu getAllFrames(), která vrací Array všech otevřených oken vázaných k elementu se kterým je metoda volána.
V našem příkladě si tedy vytvoříme několik instancí třídy Frame1, a všechny přidáme do panelu abychom mohli vyzkoušet práci s těmito okny:
1 2 3 4 5 6 7 8 9 |
desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); desktop.add(new Frame1(), BorderLayout.SOUTH); |
Nyní stačí pouze zavolat metodu getAllFrames(); která vrátí všechna tato okna. V cyklu for jim můžeme například nastavit Location, tak aby se vzájemně překrývala a byla postupně posunuta:
1 2 3 4 |
JInternalFrame[] sub = desktop.getAllFrames(); for (int i = 0; i < sub.length; i++) { sub[i].setLocation(i*20, i*20); } |
Podobným způsobem bychom mohli všechna okna například zavřít:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public void closeall() { JInternalFrame[] sub = desktop.getAllFrames(); if (sub.length == 0) { JOptionPane.showMessageDialog(null, "Neexistují žádná otevřená okna"); return; } int option = JOptionPane.showConfirmDialog(null, "Opravdu chcete zavřít všechna okna?", "Otázka", JoptionPane.OK_CANCEL_OPTION); if (option == 0) { for (int i = 0; i < sub.length; i++) { sub[i].dispose(); } } } |