Java: Minimize to Tray
Občas chceme ve svém programu umožnit uživateli minimalizovat otevřený frame programu tak, aby nebyl vidět ani na liště start. V takovém případě můžeme použít tray, ve kterém si program vytvoří ikonu, přes niž může uživatel k programu přistupovat a popřípadě jej i odsud ovládat.
V příkladu si vytvoříme jednoduchý program, který po spuštění vytvoří tray ikonu. Tato ikona bude obsahovat jednoduché PopUp menu, z něhož bude možno program částečně ovládat.
Navíc bude možné po kliknutí na ikonu program „skrýt do tray“ (pouze nastavení vlastnosti setVisible), což se projeví tak, že program zmizí jak z plochy tak nebude vidět na panelu start v podobě otevřených oken a zůstane pouze identifikační ikona. Navíc bude fungovat klasické minimalizování programu.
Základem bude jednoduchý JFrame, který bude tray ikona reprezentovat. U tohoto framu nastavíme hodnotu Visible na TRUE.
1 2 3 4 5 6 7 |
public class TrayMinimize extends JFrame { TrayMinimize() { setSize(100, 100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } } |
Pro tray ikonu si vytvoříme novou metodu, ve které si teprve uděláme podporu tray ikony. Pro ikonu budeme potřebovat SystemTray, který se nachází v java.awt. Bohužel tato vlastnost nemusí existovat ve všech verzích javy, musíme tedy nejpve zkontrolovat, zda je podporována:
1 2 3 4 5 6 7 8 |
private void trayicon() { // pokud je tray ikon podporovana if (SystemTray.isSupported()) { //kod, který se provede, pokud je podporovana SystemTray } else { //V pripade ze SystemTray není podporovan; } } |
Dále si uděláme jednoduché PopUp menu. Toto menu bude mít jenom dva menuItems, a to pro minimalizování programu nebo maximalizování a pro ukončení programu.
Pro oba MenuItems si uděláme ActionListenery:
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 |
// PopUp menu pro tray ikonu PopupMenu popup = new PopupMenu(); // menuItem pro PopUpmenu final MenuItem minimize = new MenuItem("Minimize to tray"); // action listener pro MenuItem minimize.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // volame metodu pro zmenu visiblity setvisible(); // nastavime text na MenuItem dle visiblity if (isVisible() == false) { minimize.setLabel("Open"); } else { minimize.setLabel("Minimize to tray"); } } }); // MenuItem pro ukonceni programu MenuItem exit = new MenuItem("Exit"); // action listener pro konec programu exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.exit(0); } }); // pridame menuItems do PopUp menu popup.add(minimize); popup.add(exit); |
Všimněte si, že v Action Listeneru voláme metodu setvisible(), kterou si doděláme později.
Jelikož jsme kontrolovali podporu SystemTray, je jasné že ji musíme použít.
Navíc vytvoříme novou ikonu, která bude representovat ikonu v tray a nový objekt typu TrayIcon, do kterého přidáme jak ikonu tak popup menu:
1 2 3 4 5 6 7 8 9 10 11 12 |
//vytvorime novou systemTray SystemTray tray = SystemTray.getSystemTray(); // a obrazek pro tray ikony jako Image Image image = Toolkit.getDefaultToolkit().getImage("icon.gif"); // vytvorime novou tray ikonu TrayIcon trayIcon = new TrayIcon(image, "Window", popup); try { // a pridame ji do SystemTray tray.add(trayIcon); } catch (AWTException e) { ; } |
Zčásti je hotovo. Po spuštění programu a po dopssání metody setvisible(), by se zobrazila tray ikona včetně PopUp menu.
Navíc si program rozšíříme o to, aby se okno programu po kliknutí na ikonu skrylo v případě že je zobrazeno a zobrazilo v případě že je skryté.
To vyřešíme jednoduše přidáním Mouse Listeneru k prvku trayIcon:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Mouse Listener pro TrayIcon trayIcon.addMouseListener(new MouseListener() { // po kliknuti public void mouseClicked(MouseEvent arg0) { // pokud klidneme levym tlacitkem, zmeni se hodnota Visible if (arg0.getButton() == 1) setvisible(); } public void mouseEntered(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mousePressed(MouseEvent arg0) { } public void mouseReleased(MouseEvent arg0) { } }); |
Využijeme pouze metody mouseClicked, která mám odchytí kliknutí na ikonu. Navíc kontrolujeme hodnotu arg0.getButton, aby bylo povoleno pouze levé tlačítko myši.
Opět využíváme metodu setvisible(), kterou si nyní napíšeme:
1 2 3 4 5 6 7 8 |
private void setvisible() { // nastavi opacnou Visiblitu nez je aktualni if (this.isVisible() == true) { this.setVisible(false); } else { this.setVisible(true); } } |
Metoda kontroluje aktuální hodnotu nastavení visible aktuálního prvku a dle aktuálního stavu ji nahradí za hodnotu opačnou.
Nakonec ještě celý kód:
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 |
import java.awt.AWTException; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; /** * * @author zaachi * */ public class TrayMinimize extends JFrame { TrayMinimize() { setSize(100, 100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); trayicon(); } private void trayicon() { // pokud je tray ikon podporovana if (SystemTray.isSupported()) { // PopUp menu pro tray ikonu PopupMenu popup = new PopupMenu(); // menuItem pro PopUpmenu final MenuItem minimize = new MenuItem("Minimize to tray"); // action listener pro MenuItem minimize.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { // volame metodu pro zmenu visiblity setvisible(); // nastavime text na MenuItem dle visiblity if (isVisible() == false) { minimize.setLabel("Open"); } else { minimize.setLabel("Minimize to tray"); } } }); // MenuItem pro ukonceni programu MenuItem exit = new MenuItem("Exit"); // action listener pro konec programu exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.exit(0); } }); // pridame menuItems do PopUp menu popup.add(minimize); popup.add(exit); //vytvorime novou systemTray SystemTray tray = SystemTray.getSystemTray(); // a obrazek pro tray ikony jako Image Image image = Toolkit.getDefaultToolkit().getImage("icon.gif"); // vytvorime novou tray ikonu TrayIcon trayIcon = new TrayIcon(image, "Window", popup); try { // a pridame ji do SystemTray tray.add(trayIcon); } catch (AWTException e) { ; } // Mouse Listener pro TrayIcon trayIcon.addMouseListener(new MouseListener() { // po kliknuti public void mouseClicked(MouseEvent arg0) { // pokud klidneme levym tlacitkem, zmeni se hodnota Visible if (arg0.getButton() == 1) setvisible(); } public void mouseEntered(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mousePressed(MouseEvent arg0) { } public void mouseReleased(MouseEvent arg0) { } }); } else { ; } } private void setvisible() { // nastavi opacnou Visiblitu nez je aktualni if (this.isVisible() == true) { this.setVisible(false); } else { this.setVisible(true); } } public static void main(String[] args) { new TrayMinimize(); } } |
Ahoj,
bohužel mi to nejde… nezná to SystemTray a TrayIcon. Jsem naprostý začátečník takže se omlouvám, že nevím jak to řešit ))-: Jinak díky za pěkný článek.
W
Zkus pouzit jinou verzi javy.
Prave pro tento pripad je zde kontrola, zda je SystemTray podporovana:
if( SystemTray.isSupport ed()){
//true
}
e lse
{
//false
}
if (this.isVisible() == true) {
this.setVisible(false);
} else {
this.setVisible(true);
}
Teda to je krásná ukázka "škaredého" kódu (náš učitel Javy by použil silnější slova, případně by dotyčného na místě rovnou zardousil). Takže trochu lépe a přehledněji:
this.setVisible(!this.isVisible());
Lepší, že? (Nehledě na to, že this se dá vypustit).
A ještě poznámka, proměnné typu boolean zásadně netestujeme pomocí ==, protože už samy o sobě vracejí podmínku. Testování pomocí == je prasárna.
this. vetsina lidi pouziva z duvodu ze pokud clovek v prostredi napise this a . nabidne to hned mozne operace tzn. urychleni psani kodu 🙂