GUI v Javě

Z MiS
(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
(Přidána vyskakovací okna)
(Přidán kód vytvoření listeneru.)
 
(Není zobrazeno 15 mezilehlých verzí od 1 uživatele.)
Řádka 1: Řádka 1:
[[Category:VSE]][[Category:Škola]][[Category:Informatika]][[Category:Programování]][[Category:Java]]
+
[[Category:VSE]][[Category:Škola]][[Category:Informatika]][[Category:Programování]][[Category:Java]][[Category:GUI]]
  
 
Následující poznámky jsou jen velmi stručnou osnovou. Možností při vytváření grafického rozhraní je mnohem více. Pokud chcete více než jen minimalistický návod, doporučuji:
 
Následující poznámky jsou jen velmi stručnou osnovou. Možností při vytváření grafického rozhraní je mnohem více. Pokud chcete více než jen minimalistický návod, doporučuji:
Řádka 7: Řádka 7:
  
  
== Vytvoření okna ==
+
== Vytvoření okna &mdash; třída <tt>JFrame</tt> ==
  
=== Třída <code>JFrame</code>: ===
+
* Instance třídy <code>JFrame</code> vytváří okno s titulním pruhem a tlačítky.
* realizuje okno s titulním pruhem a tlačítky.
+
* My vytváříme vlastní potomky třídy <tt>JFrame</tt>.
 +
* Každý potomek má v&nbsp;sobě vloženy další objekty (komponenty), které jsou v okně obsaženy (tlačítka, textová pole,...).
  
Vlastnosti okna
+
; Vlastnosti okna
 
* <code>setTitle(String ''titulek'')</code>
 
* <code>setTitle(String ''titulek'')</code>
 
** nastavuje titulek okna (text v titulním pruhu).
 
** nastavuje titulek okna (text v titulním pruhu).
Řádka 18: Řádka 19:
 
** říká co se bude dít při stlačení zavíracího tlačítka.
 
** říká co se bude dít při stlačení zavíracího tlačítka.
 
** naše aplikace většinou mají jediné okno, chceme tedy, aby se při zavření okna zavřela celá aplikace.
 
** naše aplikace většinou mají jediné okno, chceme tedy, aby se při zavření okna zavřela celá aplikace.
*** k tomu slouží konstanta JFrame.EXIT_ON_CLOSE.
+
*** k tomu slouží konstanta <tt>JFrame.EXIT_ON_CLOSE</tt>.
  
Velikost okna
+
; Velikost okna
 
* <code>pack()</code>
 
* <code>pack()</code>
 
** zmenší velikost okna tak, aby se do něj vlezly komponenty, které jsou aktuálně v okně.
 
** zmenší velikost okna tak, aby se do něj vlezly komponenty, které jsou aktuálně v okně.
 +
* <code>setSize(sirka, vyska)</code>
 +
** Nastaví velikost okna na stanovený rozměr.
 +
* <code>setBounds(poziceX, poziceY, sirka, vyska)</code>
 +
** Umístí okno levým horním rohem na souřadnice <code>poziceX, poziceY</code> a nastaví jeho rozměry.
  
Zobrazení okna
+
; Zobrazení okna
 
* <code>setVisible(boolean maBytViditelne)</code>
 
* <code>setVisible(boolean maBytViditelne)</code>
 
** Zobrazí nebo zneviditelní okno.
 
** Zobrazí nebo zneviditelní okno.
  
=== Příklad ===
+
; Metoda <tt>initComponents()</tt>
 +
* Je zvykem v konstruktoru okna zavolat soukromou metodu <tt>initComponents()</tt>.
 +
* V rámci této metody připravíme všechny komponenty, které mají být součástí okna.
 +
 
 +
<div class="Priklad">
 +
; Příklad 1)
 
* Vytvořte aplikaci s oknem, které půjde přesunovat, minimalizovat a při jehož zavření se aplikace ukončí.
 
* Vytvořte aplikaci s oknem, které půjde přesunovat, minimalizovat a při jehož zavření se aplikace ukončí.
* V titulním pruhu bude zobrazen text „Hello world!“.
+
* V titulním pruhu bude zobrazen text ''„Hello world!“''.
 
+
 
+
  
 +
[[#Příklad 1|Řešení viz dále]]
 +
</div>
  
== Textová pole, tlačítka ==
+
== Základní komponenty ==
  
 
Do okna vkládáme součásti (komponenty). Komponenty jsou potomky třídy <code>JComponent</code>.  
 
Do okna vkládáme součásti (komponenty). Komponenty jsou potomky třídy <code>JComponent</code>.  
Řádka 44: Řádka 54:
 
* popisky (<code>JLabel</code>).
 
* popisky (<code>JLabel</code>).
  
Je-li komponent v okně mnoho, můžeme je uspořádat na
+
Je-li komponent v okně mnoho, můžeme je [[Layout v Javě|uspořádat]]. K tomu slouží:
* panely (<code>JPanel</code>).
+
* panely (<code>JPanel</code>),
 +
* „Layout Managery“ (<code>LayoutManager</code>).
  
 
=== Třída <code>JButton</code> ===
 
=== Třída <code>JButton</code> ===
Řádka 52: Řádka 63:
 
**: <code>JButton tlStart = new JButton("Start");</code>
 
**: <code>JButton tlStart = new JButton("Start");</code>
 
* reakci na stisk tlačítka nastavíme [[#Zpracování událostí, posluchač | přiřazením posluchače viz dále]]
 
* reakci na stisk tlačítka nastavíme [[#Zpracování událostí, posluchač | přiřazením posluchače viz dále]]
* <code>String getText()</code>
+
* <code>String getText()</code>, <code>setText(String novy)</code>
** vrací popis tlačítka.
+
** vrací/nastavuje popis tlačítka.
 +
* <code>setIcon(ImageIcon obr)</code>
 +
** Nastavení obrázku místo textu.
 +
<div class="Priklad">
 +
ImageIcon obr;
 +
obr = new ImageIcon("res/krizek.png");
 +
JButton tlacitko = ...
 +
...
 +
tlacitko.setIcon(obr);
 +
</div>
  
 
=== Třída <code>JLabel</code> ===
 
=== Třída <code>JLabel</code> ===
Řádka 70: Řádka 90:
 
* <code>setEditable(boolean lzeUpravovat)</code>
 
* <code>setEditable(boolean lzeUpravovat)</code>
 
** nastaví, zda do textového pole lze psát, nebo zda je šedivé a úpravy jsou zakázány.
 
** nastaví, zda do textového pole lze psát, nebo zda je šedivé a úpravy jsou zakázány.
 +
; Další nastavení
 +
* <code>setFont(new java.awt.Font("Lucida Sans", 0, 24))</code>
 +
** Nastavení fontu.
 +
* <code>setHorizontalAlignment(javax.swing.JTextField.RIGHT)</code>
 +
** nastaví zarovnání vpravo.
 +
* Ve vývojovém prostředí je určitě pohodlnější nastavit vše přes grafický nástroj Properties.
  
 
Pokud potřebujete z textového pole načíst číslo, můžete použít následující metodu:
 
Pokud potřebujete z textového pole načíst číslo, můžete použít následující metodu:
Řádka 96: Řádka 122:
 
* Abychom komponentu zobrazili, musíme ji umístit do některého okna.
 
* Abychom komponentu zobrazili, musíme ji umístit do některého okna.
 
* Seskládání okna obvykle provádíme v soukromé metodě <code>initComponents()</code> okna, kterou pro tento účel vytvoříme.
 
* Seskládání okna obvykle provádíme v soukromé metodě <code>initComponents()</code> okna, kterou pro tento účel vytvoříme.
* Pokud chceme mít komponent v okně více, je třeba je uspořádat pomocí [[GUI v Javě#Layout Manager | „layout manageru“]].
+
* Pokud chceme mít komponent v okně více, je třeba je uspořádat pomocí [[Layout v Javě | „layout manageru“]].
  
 
=== Třída <code>JFrame</code> ===
 
=== Třída <code>JFrame</code> ===
Řádka 129: Řádka 155:
 
* <code>public Object getSource()</code>
 
* <code>public Object getSource()</code>
 
** vrací objekt, který událost vyvolal. V našem případě instanci třídy <code>JButton</code>, reprezentující tlačítko, které bylo stisknuto.
 
** vrací objekt, který událost vyvolal. V našem případě instanci třídy <code>JButton</code>, reprezentující tlačítko, které bylo stisknuto.
** je potřeba provést [[Přetypování | přetypování]] z <code>Object</code> na <code>JButton</code>.
+
** je potřeba provést [[Java: Abstraktní třídy, dědičnost a rozhraní#Přetypování | přetypování]] z <code>Object</code> na <code>JButton</code>.
  
 
=== <code>interface ActionListener</code> ===
 
=== <code>interface ActionListener</code> ===
Řádka 135: Řádka 161:
 
** v této metodě popíšeme, co se má stát při stisku tlačítka
 
** v této metodě popíšeme, co se má stát při stisku tlačítka
  
=== Příklad ===
+
=== Ukázka kódu ===
* Přidejte k tlačítku z příkladu v předchozím odstavci reakci.
+
* Při stisku tlačítka se do textového výstupu programu opíše text z popisu tlačítka.
+
  
 +
* V&nbsp;metodě <code>initComponents</code> nebo obdobné:
 +
JButton tlacitko = new JButton("Popis");
 +
tlacitko.addActionListener(event -> metodaPoStisknuti(event));
  
 +
* Dále přidejte metodu:
 +
private void metodaPoStisknuti(ActionEvent event) {
 +
    // ... co se má stát po stisku tlačítka
 +
}
  
== Layout Manager ==
+
* Parametr <code>event</code> můžete vynechat, pokud nepotřebujete získávat informace o tlačítku, které událost vyvolalo.
* Použijeme, když chceme do okna umístit více než jednu komponentu.
+
* Instance třídy LayoutManager, resp. jejích dceřinných tříd.
+
  
=== Nejběžnější třídy layout managerů v Javě ===
 
* <code>FlowLayout</code>
 
** Nejjednodušší layout manager.
 
** Umisťuje prvky jeden za druhý do řádků v takovém pořadí, v jakém jsou přidány.
 
* <code>GridLayout</code>
 
** umisťuje komponenty do pravidelné mřížky M×N.
 
** počet řádků a počet sloupců zadáváme jako parametry konstruktoru při vytváření instance třídy GridLayout.
 
** pokud některý z parametrů konstruktoru zadáme nulový, pak je počet řádků resp. sloupců neomezený.
 
** při přidávání komponent se mřížka zaplňuje zleva a shora.
 
* <code>BorderLayout</code>
 
** umisťuje komponenty do oblastí North, South, East, West a Center.
 
** při zvětšování a zmenšování okna se zvětšuje a zmenšuje oblast Center, ostatní zůstávají pokud možno stejně veliké.
 
** přidávání komponent: <code>panel.add(tlacitko, BorderLayout.EAST)</code>
 
 
=== Třídy <code>JFrame</code> a <code>JPanel</code> ===
 
* <code>void setLayout(LayoutManager lm)</code>
 
** nastaví panelu nebo oknu daný layout manager
 
* <code>void add(Component komponenta[, umisteni])</code>
 
** přidá další komponentu do okna.
 
** některé layout managery vyžadují další informaci o umístění komponenty v okně.
 
  
 
=== Příklad ===
 
=== Příklad ===
 +
* Přidejte k tlačítku z příkladu v předchozím odstavci reakci.
 +
* Při stisku tlačítka se do textového výstupu programu opíše text z popisu tlačítka.
 +
 +
<div class="Priklad">
 +
Příklad
 
* Přidejte k předchozímu příkladu dvě textová pole s popiskami (label) „Originál“ a „Kopie“.
 
* Přidejte k předchozímu příkladu dvě textová pole s popiskami (label) „Originál“ a „Kopie“.
 
* Textové okno s popisem „Kopie“ nebude editovatelné.
 
* Textové okno s popisem „Kopie“ nebude editovatelné.
Řádka 172: Řádka 186:
 
* Při stisknutí tlačítka se text z pole „Originál“ zkopíruje do pole „Kopie“.
 
* Při stisknutí tlačítka se text z pole „Originál“ zkopíruje do pole „Kopie“.
 
* Při stisku tlačítka se do textového výstupu programu opíše text z popisu tlačítka.
 
* Při stisku tlačítka se do textového výstupu programu opíše text z popisu tlačítka.
 +
</div>
  
== Vyskakovací okna ==
 
* Vyskakovací okno (message box) je modální &mdash; běh aplikace se přeruší, dokud uživatel nepotvrdí okno.
 
* K vyvolání okna slouží třída <code>JOptionPane</code> z balíčku <code>javax.swing</code>
 
* Vyskakovací okno by mělo vyskočit uprostřed okna, ze kterého je vyvoláno, proto potřebuje odkaz na své rodičovské okno.
 
** Rodičovské okno předáváme jako první parametr.
 
** Pokud předáme <code>null</code>, bude vyskakovací okno uprostřed obrazovky.
 
* Jako poslední parametr předáváme typ okna:
 
** <code>JOptionPane.ERROR_MESSAGE</code>
 
** <code>JOptionPane.WARNING_MESSAGE</code>
 
** <code>JOptionPane.INFORMATION_MESSAGE</code>
 
  
;Příklad:
+
== Rozšíření ==
  if (chyba > 3) {
+
 
    JOptionPane.showMessage(null, "Tohle píši ve vyskakovacím okně!", "Titulek okna", JOptionPane.WARNING_MESSAGE);
+
=== Umístění okna na střed obrazovky ===
 +
 
 +
    private static void setToTheMiddle(JFrame frame) {
 +
        GraphicsConfiguration gc = frame.getGraphicsConfiguration();
 +
        Rectangle bounds = gc.getBounds();
 +
        Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
 +
        Rectangle effectiveScreenArea = new Rectangle();
 +
   
 +
        effectiveScreenArea.x = bounds.x + screenInsets.left;
 +
        effectiveScreenArea.y = bounds.y + screenInsets.top;
 +
        effectiveScreenArea.height = bounds.height - screenInsets.top - screenInsets.bottom;
 +
        effectiveScreenArea.width = bounds.width - screenInsets.left - screenInsets.right;
 +
 +
        // Umístění doprostřed:
 +
        int middleX = effectiveScreenArea.x + (effectiveScreenArea.width - frame.getWidth()) / 2;
 +
        int middleY = effectiveScreenArea.y + (effectiveScreenArea.height - frame.getHeight()) / 2;
 +
        frame.setLocation(middleX, middleY);
 +
    }
 +
 
 +
 
 +
== Související stránky ==
 +
* [[Layout v Javě]], [[Dialogy a vyskakovací okna]], [[Menu v Javě]], [[Tabulky v Javě]]
 +
 
 +
== Další zdroje ==
 +
* [https://www.youtube.com/watch?v=vuQdLKq2LaY Youtube.com > First Java Swing GUI Application with IntelliJ IDEA IDE (2022)]
 +
 
 +
 
 +
== Řešení příkladů ==
 +
=== Příklad 1 ===
 +
; Okno.java
 +
public class Okno extends JFrame {
 +
    public Okno() {
 +
      this.initComponents();
 +
    }
 +
    public void initComponents() {
 +
      this.setTitle("Hello world!");
 +
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 +
      this.pack();
 +
    }
 +
}
 +
; Main.java
 +
public static void main(String[] args) {
 +
    Okno okno = new Okno();
 +
    okno.setVisible(true);
 
  }
 
  }

Aktuální verze z 9. 1. 2024, 11:42


Následující poznámky jsou jen velmi stručnou osnovou. Možností při vytváření grafického rozhraní je mnohem více. Pokud chcete více než jen minimalistický návod, doporučuji: tutoriál ze stránek Oracle.com



Obsah

Vytvoření okna — třída JFrame

Vlastnosti okna
Velikost okna
Zobrazení okna
Metoda initComponents()
Příklad 1)
  • Vytvořte aplikaci s oknem, které půjde přesunovat, minimalizovat a při jehož zavření se aplikace ukončí.
  • V titulním pruhu bude zobrazen text „Hello world!“.

Řešení viz dále

Základní komponenty

Do okna vkládáme součásti (komponenty). Komponenty jsou potomky třídy JComponent.

Nejběžnější komponenty jsou:

Je-li komponent v okně mnoho, můžeme je uspořádat. K tomu slouží:

Třída JButton

ImageIcon obr;
obr = new ImageIcon("res/krizek.png");
JButton tlacitko = ...
...
tlacitko.setIcon(obr);

Třída JLabel

Třída JTextField

Další nastavení

Pokud potřebujete z textového pole načíst číslo, můžete použít následující metodu:

   /**
    * Získá číslo z textového pole
    *
    * @param textovePole Textové pole, jehož hodnota se má převést na číslo
    * @return Vrátí hodnotu čísla, zapsaného v textovém poli.
    *     Pokud text v poli nelze převést na číslo (pole je prázdné apod.),
    *      vrátí 0
    *      a navíc do textového pole zapíše výzvu k vložení čísla.     */
   private int ziskejCislo(JTextField textovePole) {
       int vysledek;
       try {
           vysledek = Integer.parseInt(textovePole.getText());
       } catch (NumberFormatException e) {
           textovePole.setText("Nastavte platné číslo!");
           vysledek = 0;
       }
       return vysledek;
   }

Vkládání komponent do okna

Třída JFrame

Příklad



Zpracování událostí, posluchač

Postup zpracování události tlačítka

  1. uživatel klikne na tlačítko
  2. objekt reprezentující tlačítko vygeneruje událost (event)
    prakticky vytvoří novou instanci třídy ActionEvent), která nese podrobnější informace (které tlačítko myši bylo stisknuto, na jakých souřadnicích,...
  3. objekt reprezentující tlačítko událost pošle všem svým „posluchačům“ (posluchači jsou objekty, které splňují rozhraní (interface) ActionListener)
    prakticky se „poslání události“ realizuje tak, že tlačítko zavolá metodu actionPerformed(ActionEvent e), kterou předepisuje rozhraní ActionListener. Jako parametr metody se předá objekt události
  4. posluchač provede akci, která se má provést
    programátor tedy akci popíše v kódu metody actionPerformed(ActionEvent e) v posluchači

Aby bylo možné na stisk tlačítka reagovat, musíme:

  1. mít třídu posluchače (interface ActionListener)
  2. vytvořit instanci třídy posluchače
  3. zaregistrovat instanci třídy posluchače u tlačítka.

class ActionEvent

interface ActionListener

Ukázka kódu

JButton tlacitko = new JButton("Popis");
tlacitko.addActionListener(event -> metodaPoStisknuti(event));
private void metodaPoStisknuti(ActionEvent event) {
    // ... co se má stát po stisku tlačítka
}


Příklad

Příklad

  • Přidejte k předchozímu příkladu dvě textová pole s popiskami (label) „Originál“ a „Kopie“.
  • Textové okno s popisem „Kopie“ nebude editovatelné.
  • Tlačítko upravte tak, že na něm bude popis „Kopíruj“.
  • Při stisknutí tlačítka se text z pole „Originál“ zkopíruje do pole „Kopie“.
  • Při stisku tlačítka se do textového výstupu programu opíše text z popisu tlačítka.


Rozšíření

Umístění okna na střed obrazovky

   private static void setToTheMiddle(JFrame frame) {
       GraphicsConfiguration gc = frame.getGraphicsConfiguration();
       Rectangle bounds = gc.getBounds();
       Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
       Rectangle effectiveScreenArea = new Rectangle();

       effectiveScreenArea.x = bounds.x + screenInsets.left;
       effectiveScreenArea.y = bounds.y + screenInsets.top;
       effectiveScreenArea.height = bounds.height - screenInsets.top - screenInsets.bottom;
       effectiveScreenArea.width = bounds.width - screenInsets.left - screenInsets.right;

       // Umístění doprostřed:
       int middleX = effectiveScreenArea.x + (effectiveScreenArea.width - frame.getWidth()) / 2;
       int middleY = effectiveScreenArea.y + (effectiveScreenArea.height - frame.getHeight()) / 2;
       frame.setLocation(middleX, middleY);
   }


Související stránky

Další zdroje


Řešení příkladů

Příklad 1

Okno.java
public class Okno extends JFrame {
   public Okno() {
      this.initComponents();
   }
   public void initComponents() {
      this.setTitle("Hello world!");
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.pack();
   }
}
Main.java
public static void main(String[] args) {
   Okno okno = new Okno();
   okno.setVisible(true);
}
Osobní nástroje
Jmenné prostory
Varianty
Akce
Výuka
Navigace
Nástroje