Java: PopUp Window
Jednoduchý způsob jak vytvořit animované PopUp okno v Javě. Okno se plynule vysune do rohu obrazovky, určený čas počká a zase se plynule schová.
Čas od času může nastat situace, kdy chcete uživateli sdělovat informace o běhu programu, který ale může být v pozadí, nebo minimalizovaný. V takovémto případě není moc platné vypisovat informace do okna programu, ale musíme nají jiný způsob, například uživateli nechat vyskočit PopUp okno, které jej na danou skutečnost upozorní.
Pro příklad jsem využil dvě třídy, jednu pro vyvolání PopUp okna a druhou pro samotné PopUp okno.
Třída pro vyvolání PopUp okna pouze dědí JFrame, zobrazí okno, ve kterém je jedno tlačítko, které vyvolá pomocí ActionListeneru akci a spustí třídu pro zobrazení PopUp okna.
Pro názornost příkladu jsou nastaveny všechny rozměry a texty ve vyskakovacím oknu napevno.
Po kliknutí na tlačítko se okno zobrazí v pravém horním rohu a to tak, že plynule vyjede z horního okraje obrazovky. Po čas zobrazení zůstane nehybně vyset a poté se opět plynule schová, tentokrát za pravý okraj obrazovky.
Třída TopWindow
Třída TopWindow, jak již bylo zmíněno, je pouze pro názornost a umožňuje vyvolání vyskakovacího okna. Obsahuje jedno jediné tlačítko, které je pomocí ActionListeneru svázáno s metodou RunPopup. Tato metoda vytvoří novou instanci druhé třídy – PopupWindow.
Třída dědí JFrame, jímž je okno zobrazeno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
//trida topwindow public class TopWindow extends JFrame{ //konstruktor tridy topwindow public TopWindow() { //nastaveni zaklanich udaju JFrame this.setSize(new Dimension(100, 100)); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cont = getContentPane(); cont.setLayout(new FlowLayout()); //vytvoreni tlacitka pro spusteni PopUp okna JButton bt = new JButton("Run PopUp"); cont.add(bt); bt.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { //pro spusteni PopUp okna se spusti metoda RunPopup(); RunPopup(); } }); } //metoda RunPopup(); private void RunPopup(){ //vytvori se nova instance tridz PopupWindow PopupWindow popup = new PopupWindow(); } public static void main(String[] args) { new TopWindow(); } } |
Třída PopupWindow
Třída PopupWindow obstarává samotné zobrazení PopUp okna.
Obsahuje napevno dané rozměry vyskakovacího okna, jako private proměnné a do třídy nepřecházení žádné parametry.
PopupWindow dědí JWindow, abychom dosáhli pěkného okna bez okrajů a navíc implementuje rozhraní Runnable.
Konstruktor obsahuje vytvoření okna o daných rozměrech, ve kterém vytvoří Container.
Do Containeru je umístěn text, zobrazovaný v okně.
Navíc jsou v konstruktoru zjištěny rozměry plochy pomocí java.awt.Toolkit, abychom mohli okno umístit přesně na dané rozměry.
Pokud by nebylo možné, například kvůli verzi javy, zjistit rozměry plochy, museli bychom okno zobrazit v pravém horním rohu, kde by byly souřadnice nulové.
Na konci konstruktoru je spuštěn nový Thread, který se bude starat o plynulé vysunutí a opětné schování okna:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class PopupWindow extends JWindow implements Runnable{ //privatatni promenne private int size_x = 200; private int size_y = 30; private int width = 0; public PopupWindow(){ //nastaveni rozmeru okna z privatnich promennych this.setSize(new Dimension( this.size_x, this.size_y ) ); //zjisteni rozmeru obrazovky Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); //zakladni umisteni okna this.setLocation(size.width - this.size_x, 0 ); //vytvoreni containeru Container cont = new Container(); cont = getContentPane(); FlowLayout layout = new FlowLayout(); cont.setLayout(layout); cont.setBackground(Color.ORANGE); //umisteni textu do containeru JLabel jl = new JLabel("My PopUp Java Window"); cont.add(jl); setContentPane(cont); //zobrazeni okna this.setVisible(true); //vypocet sirky plochy this.width = size.width-this.size_x; //vytvoreni noveho threadu Thread th = new Thread(this); th.start(); } } |
Nakonec už zůstává pouze metoda Run, která se spouští v důsledku nového Threadu.
Metoda postupně mění pozici okna pomocí setLocation, a s využitím Thread.sleep dosáhne plynulého vysunutí a zasunutí.
Nejprve je okno v cyklu While vysunuto z pravého horního rohu směrem dolů. Na této pozici okno 2 sekundy zůstane a plynule se zasune, s využitím druhého cyklu while, za pravý okraj plochy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public void run(){ //zjisteni pozice okna int position = 0-this.size_y; //v cyklu se okno postupne vysune zeshora while( ++position < 1 ){ this.setLocation(width, position); try { //cekame, aby bylo vysouvani plynule Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } try { //okno zustane 2 sekundy zobrazene Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //vypocet pozice position = this.width - this.size_x; //v cyklu se okno posutpne schova doprava while( ++position < this.width ){ this.setLocation(position+this.size_x, 0); try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } //zrusime okno this.dispose(); } |
Celý zdrojový kód si můžete prohlídnout zde:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JWindow; //trida topwindow public class TopWindow extends JFrame{ //konstruktor tridy topwindow public TopWindow() { //nastaveni zaklanich udaju JFrame this.setSize(new Dimension(100, 100)); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cont = getContentPane(); cont.setLayout(new FlowLayout()); //vytvoreni tlacitka pro spusteni PopUp okna JButton bt = new JButton("Run PopUp"); cont.add(bt); bt.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { //pro spusteni PopUp okna se spusti metoda RunPopup(); RunPopup(); } }); } //metoda RunPopup(); private void RunPopup(){ //vytvori se nova instance tridz PopupWindow PopupWindow popup = new PopupWindow(); } //trida PopupWindow - dedi JWindow a implementuje Runnable class PopupWindow extends JWindow implements Runnable{ //privatatni promenne private int size_x = 200; private int size_y = 30; private int width = 0; public PopupWindow(){ //nastaveni rozmeru okna z privatnich promennych this.setSize(new Dimension( this.size_x, this.size_y ) ); //zjisteni rozmeru obrazovky Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); //zakladni umisteni okna this.setLocation(size.width - this.size_x, 0 ); //vytvoreni containeru Container cont = new Container(); cont = getContentPane(); FlowLayout layout = new FlowLayout(); cont.setLayout(layout); cont.setBackground(Color.ORANGE); //umisteni textu do containeru JLabel jl = new JLabel("My PopUp Java Window"); cont.add(jl); setContentPane(cont); //zobrazeni okna this.setVisible(true); //vypocet sirky plochy this.width = size.width-this.size_x; //vytvoreni noveho threadu Thread th = new Thread(this); th.start(); } //metoda run public void run(){ //zjisteni pozice okna int position = 0-this.size_y; //v cyklu se okno postupne vysune zeshora while( ++position < 1 ){ this.setLocation(width, position); try { //cekame, aby bylo vysouvani plynule Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } try { //okno zustane 2 sekundy zobrazene Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //vypocet pozice position = this.width - this.size_x; //v cyklu se okno posutpne schova doprava while( ++position < this.width ){ this.setLocation(position+this.size_x, 0); try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } //zrusime okno this.dispose(); } } public static void main(String[] args) { new TopWindow(); } } |
Jej. Já jsem tohle kdysi davno resil prez vyskakovaci okno v JFrame, ale tohle je lepsi.
Vyzkousim.
Další super inspirativní článek, děkuji! 😉
Určitě přidávej další o Javě, píšeš to moc hezky.
viz 60. a 62. řádek:
Container cont = new Container();
cont = getContentPane();
To si napřed vytvoříš nový container a pak ho vzápětí zrušíš? (Ztráta reference na objekt = zrušení objektu v příštím volání GC).
Nevím jak je tomu u AWT ale u Swingu je důrazně nedoporučeno (zakázáno až na výjimky) měnit obsah GUI z jiného než z EDT vlákna. Takže by změna pozice okna měla vypadat nějak takto:
SwingUtilities.invokeLater( "setLocation()" )