Gestire la System Tray in Java
di Antonio Coschignano, mercoledì 09 giugno 2010
La System Tray conosciuta anche come Taskbar Status Area su Microsoft Windows oppure Notification Area su ambienti GNOME è
quella barra che si trova solitamente in basso a destra nel desktop:
Adesso ottenuta un'istanza della classe bisogna aggiungere un'icona e gestirne gli eventi, associandone magari un popupmenu oppure un JFrame etc. La classe che si occupa di gestire queste funzioni è java.awt.TrayIcon a cui è associata un'immagine che rappresenta l'icona che viene visualizzata nella system tray. Quindi per prima cosa dobbiamo caricare un'immagine attraverso il Toolkit di sistema:
Java System Tray
La classe che si occupa di gestire questa funzionalità grafica è java.awt.SystemTray. Questa classe implementa innanzitutto due metodi statici, di cui uno si occupa di verificare che la funzionalità sia disponibile per la piattaforma su cui stiamo lavorando isSupported() mentre l'altro metodo getSystemTray() ritorna un riferimento alla system tray della piattaforma:import java.awt.SystemTray; .... SystemTray systemTray = null; if(SystemTray.isSupported()) { systemTray = SystemTray.getSystemTray(); }Il metodo getSystemTray() può generare un'eccezione (UnsupportedOperationException) in caso la funzionalità non è disponibile per un particolare sistema operativo. Quindi prima di invocare il metodo è consigliabile effettuare un controllo tramite isSupported().
Adesso ottenuta un'istanza della classe bisogna aggiungere un'icona e gestirne gli eventi, associandone magari un popupmenu oppure un JFrame etc. La classe che si occupa di gestire queste funzioni è java.awt.TrayIcon a cui è associata un'immagine che rappresenta l'icona che viene visualizzata nella system tray. Quindi per prima cosa dobbiamo caricare un'immagine attraverso il Toolkit di sistema:
String path="...."; Image img = Toolkit.getDefaultToolkit().getImage(path);Ora bisogna creare un'istanza della TrayIcon passando l'oggetto Image nel costruttore:
TrayIcon trayIcon = new TrayIcon(img);Aggiungiamo la TrayIcon alla SystemTray tramite il metodo add():
systemTray.add(trayIcon);Questo che abbiamo fatto semplicemente visualizza nella system tray l'icona che abbiamo caricato attraverso il Toolkit. Per associare altri componenti all'icona adesso bisogna implementare dei listener che in base agli eventi generati visualizza o nasconde gli oggetti grafici da noi definiti oppure effettua altre operazioni come l'uscita dall'applicazione e la rimozione della TrayIcon dalla system tray. Gli eventi vengono generati dal mouse quindi è opportuno implementare un MouseListener o ridefinire un MouseAdapter e registrarlo nella TrayIcon. Ad esempio, immaginiamo di avere un JFrame e ad ogni click del mouse viene visualizzato o nascosto in base allo stato precedente:
JFrame frame = new JFrame("Demo"); private class MyMouseListener exetnds MouseAdapter { @Override public void mouseClicked(MouseEvent e) { if(frame.isVisible()) frame.setVisible(false); else frame.setVisible(true); } } String path="...."; Image img = Toolkit.getDefaultToolkit().getImage(path); TrayIcon trayIcon = new TrayIcon(img); trayIcon.addMouseListener(new MyMouseListener()); if(SystemTray.isSupported()) { SystemTray.getSystemTray().add(trayIcon); }Un MouseEvent può comunque indicarci quale tasto del mouse è stato premuto (getButton()), destro o sinistro, quindi è possibile associare una funzione per la visualizzazione dell'oggetto grafico oppure la visualizzazione di un JPopupMenu con diverse voci (JMenuItem) dove ciascuno gestisce altri listener dove è possibile associare altri oggetti grafici o altre funzionalità.
Esempio con un JFrame e JPopupMenu
In questo esempio vediamo una semplice applicazione dove ad una TrayIcon è associato un JFrame e un JPopupMenu. In poche parole vengono gestiti gli eventi del mouse. Quando clicchiamo con il tasto destro viene visualizzato un JPopupMenu con le voci visualizza/nascondi/esci. Mentre se usiamo il tasto sinistro viene visualizzato o nascosto il JFrame:import java.awt.AWTException; import java.awt.HeadlessException; import java.awt.Image; 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.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; public class SystemTrayDemo extends JFrame { private TrayIcon trayIcon; private JPopupMenu popupMenu; public SystemTryDemo() throws HeadlessException { super("SystemTrayDemo"); setSize(300, 300); create(); } private void create() { try { if (SystemTray.isSupported()) { popupMenu = createPopupMenu(); SystemTray systemTray = SystemTray.getSystemTray(); Image img = Toolkit.getDefaultToolkit().getImage("c://icon.gif"); trayIcon = new TrayIcon(img); systemTray.add(trayIcon); trayIcon.addMouseListener(new SystemTrayMouseListener()); } } catch (AWTException ex) {} } private JPopupMenu createPopupMenu() { JPopupMenu p = new JPopupMenu(); JMenuItem apri = new JMenuItem("Apri"); JMenuItem nascondi = new JMenuItem("Nascondi"); JMenuItem esci = new JMenuItem("Esci"); apri.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(true); } }); nascondi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); } }); esci.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); SystemTray.getSystemTray().remove(trayIcon); System.exit(0); } }); p.add(apri); p.add(nascondi); p.addSeparator(); p.add(esci); return p; } private class SystemTrayMouseListener extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == 1) { //Pulsante sinistro del mouse if (isVisible()) { setVisible(false); } else { setVisible(true); } } else if (e.getButton() == 3) {//Pulsante destro del mouse popupMenu.show(e.getComponent(), e.getX(), e.getY()); } } } public static void main(String... argv) throws AWTException { SystemTrayDemo demo = new SystemTrayDemo(); } }Questo è uno screenshots dell'applicazione in esecuzione su Windows XP: