Lekce 2 - Java Swing pod pokličkou
V minulém dílu seriálu tutoriálů o Java Swing, Úvod do formulářových aplikací v Java Swing, jsme naprogramovali, tedy spíše naklikali, svou první formulářovou aplikaci v Javě.
V dnešním dílu si vysvětlíme, jak funguje uvnitř.
Pod pokličkou
Samotný formulář je samozřejmě objekt (jak jinak ). Je definován třídou
HlavniJFrame
, kterou nalezneme v souboru
HlavniJFrame.java
.
Přepněme se do kódu třídy pomocí tlačítka "Source". Některé části
kódu jsou zašedlé a sklapnuté. Když ho celý rozbalíme a odstraníme
komentáře, vypadá asi takto (nelekněte se ):
public class HlavniJFrame extends javax.swing.JFrame { public HlavniJFrame() { initComponents(); } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jLabel1 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Pozdrav"); jLabel1.setText("Pozdrav z formuláře"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(41, 41, 41) .addComponent(jLabel1) .addContainerGap(47, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap(45, Short.MAX_VALUE) .addComponent(jLabel1) .addGap(43, 43, 43)) ); pack(); }// </editor-fold> public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(HlavniJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(HlavniJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(HlavniJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(HlavniJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new HlavniJFrame().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JLabel jLabel1; // End of variables declaration }
Vidíme, že formulář je třída, dědící z třídy JFrame
.
To je právě třída reprezentující okno. V konstruktoru se volá podivná
metoda initComponents()
, jejíž kód byl sklapnutý. I když ho
rozbalíme, NetBeans nám do této části třídy neumožní psát.
Metodu initComponents()
automaticky generuje NetBeans podle
toho, co na formulář naklikáme. I když vypadá složitě, nedělá nic
jiného, než že vytvoří postupně všechny prvky na formuláři a nastaví
jim patřičné vlastnosti, které jsme zvolili. Vidíme zde, jak se tvoří
náš label a nastavují se mu vlastnosti. Metoda se poté volá v konstruktoru,
čímž se formulář inicializuje. Nezasvěcený programátor je tedy plně
odstíněn od kódu, co generuje návrhář. Je to samozřejmě hlavně proto,
aby ho nemohl rozbít
Nicméně je důležité vědět, jak to funguje, abyste byli schopni např.
přidávat kontrolky za běhu aplikace.
Protože Swing používá stejně jako např. HTML relativní pozicování prvků, generuje NetBeans spoustu dalších neviditelných komponent, jako jsou různé mezery, oddělovače a tzv. layouty. V tomto kurzu se jim věnovat nebudeme, jelikož to kvůli přítomnosti grafického návrháře nebudeme potřebovat. Jsou však detailně vysvětleny v kurzu o ručním návrhu formulářů v Java Swing, kde se nepoužívá grafický návrhář a je tedy důležité, aby programátor rozuměl přesně tomu, jak se prvky na formulář umisťují, protože to musí dělat on sám.
Ve třídě nalezneme dále hlavní metodu main()
, která
vytvoří formulář a nastaví mu tzv. Look and Feel. To je jednoduše řečeno
Skin. Jako výchozí je v NetBeans vzhled Nimbus, hodnotu můžete přepsat na
Windows, vaše aplikace poté bude vypadat jako jste zvyklí z Windows. Na konci
metody se vytváří instance hlavního formuláře.
Úprava pozice a velikosti okna
Ve výchozím nastavení se okno aplikace po jejím spuštění objeví v levém horním rohu obrazovky. Uživatel by ho očekával spíše uprostřed a bohužel to nelze nastavit v Properties. Podobně je to s velikostí okna. Ukažme si, jak se tyto vlastnosti okna mění.
Vycentrování okna
Proto kód vytvoření formuláře upravíme a přidáme jeho vycentrování:
public void run() { HlavniJFrame hlavniJFrame = new HlavniJFrame(); hlavniJFrame.setLocationRelativeTo(null); hlavniJFrame.setVisible(true); }
Když aplikaci spustíme, bude okno uprostřed obrazovky.
Zakázání zmenšování okna
Na stejném místě můžeme specifikovat i další vlastnosti hlavního
okna. Někdy třeba budeme chtít, aby uživatel nemohl okno aplikace
zvětšovat či zmenšovat, to se dělá pomocí
setResizable()
:
hlavniJFrame.setResizable(false);
Minimální velikost
Občas se nám může hodit nastavit oknu minimální velikost. To je
velikost, pod kterou už nepůjde okno ručně zmenšit. Můžeme k tomu
použít metodu setMinimumSize()
. Tato metoda bere jako parametr
objekt typu Dimension
, takže pokud bychom chtěli, aby naše okno
mělo minimální velikost 100
x100
pixelů, tak bychom
zadali:
hlavniJFrame.setMinimumSize(new Dimension(100,100));
Obvykle ale chceme, aby tato minimální velikost byla právě ta velikost,
jakou má naše okno hned po spuštění aplikace. Swing totiž vytváří nová
okna tak, aby byla co nejmenší, ale zároveň byly vidět všechny komponenty.
Toto je mimochodem účel volání pack()
v samotném závěru
initComponents()
, přepočítá a nastaví optimální velikost
okna podle velikostí komponent v něm. Velikost okna vrací metoda
getSize()
, takže aby naše okno nešlo zmenšit pod jeho
optimální velikost, stačí ihned po jeho vytvoření zavolat:
HlavniJFrame hlavniJFrame = new HlavniJFrame();
hlavniJFrame.setMinimumSize(hlavniJFrame.getSize());
Takto vytvořené okno půjde ručně libovolně zvětšovat, ale zmenšit půjde jen do velikosti, v jaké se otevřelo.
Ikona
Nakonec si ukážeme, jak se dá nastavit ikonka, která se zobrazuje v
levém horním rohu okna. Defaultně je použita standardní javovská ikonka.
Abychom to změnili, je třeba mít vlastní ikonku nejlépe ve formátu
.png
. Soubor s ikonkou pojmenovaný například
ikona.png
umístíme do složky src/main/resources
(pokud neexistuje, je potřeba ji vytvořit). V metodě run()
poté
provedeme:
public void run() { HlavniJFrame hlavniJFrame = new HlavniJFrame(); ImageIcon icon = new ImageIcon(getClass().getResource("/ikona.png")); hlavniJFrame.setIconImage(icon.getImage()); }
Na úplném konci souboru nalezneme samotné komponenty, které jsme na
formulář naklikali. Všimněme si, že název jejich tříd vždy začíná na
J
, např. JLabel
. Je to z toho důvodu, aby se
odlišily od starších komponent z AWT a také proto, že se jedná o Java
třídy.
Dnešní projekt je ke stažení v příloze článku včetně zdrojových kódů.
Příště, Jednoduchá kalkulačka v Java Swing, si vysvětlíme, jak fungují události a naprogramujeme si jednoduchou kalkulačku.
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 399x (4.27 kB)
Aplikace je včetně zdrojových kódů v jazyce Java