2012-10-01 21 views
14

Quiero añadir JPopupMenu a la barra de tareas como TrayIcon (es decir systemTray.add(trayIcon)) pero no he encontrado una manera de hacer so.From la docs el constructor de TrayIcon es así:Adición JPopupMenu a la TrayIcon

public TrayIcon(Image image, 
      String tooltip, 
      PopupMenu popup) 

¿Hay alguna manera de que pueda hacer esto?

+8

Bienvenido a mi mundo. Es frustrante cómo esto no se ha implementado. No obstante, puede encontrar [Uso de JPopupMenu en TrayIcon] (http://weblogs.java.net/blog/ixmal/archive/2006/05/using_jpopupmen.html) de interés – MadProgrammer

+0

Usar un MouseListener y actuar sobre mouseReleased es el camino a seguir. También puede consultar [esta respuesta] (http://stackoverflow.com/questions/12638845/adding-a-vertical-separator-in-popupmenu-in-the-task-bar/12640454#12640454) que es para otro propósito pero también muestra un JPopupMenu en un TrayIcon. –

Respuesta

-1

Usted puede mirar en el tutorial y el ejemplo de Oracle how to use the system tray

+1

Como estados de doc/tutorial, el soporte de TrayIcon es limitado y hasta el día de hoy, JPopupMenu no se puede agregar a TrayIcon directamente a través del constructor, por lo que el voto a favor. – FaithReaper

0

no puedo ver ningún problema con el público constructor TrayIcon(Image image, String tooltip, PopupMenu popup), nor is Java7 en WinXP/Win7 (Win2003/2008)

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Image; 
import java.awt.MenuItem; 
import java.awt.PopupMenu; 
import java.awt.SystemTray; 
import java.awt.TrayIcon; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.UIManager; 

public class ActiveTray { 

    public static void main(String args[]) throws Exception { 
     if (SystemTray.isSupported() == false) { 
      System.err.println("No system tray available"); 
      return; 
     } 
     final SystemTray tray = SystemTray.getSystemTray(); 
     PropertyChangeListener propListener = new PropertyChangeListener() { 

      public void propertyChange(PropertyChangeEvent evt) { 
       TrayIcon oldTray[] = (TrayIcon[]) evt.getOldValue(); 
       TrayIcon newTray[] = (TrayIcon[]) evt.getNewValue(); 
       System.out.println(oldTray.length + "/" + newTray.length); 
      } 
     }; 
     tray.addPropertyChangeListener("trayIcons", propListener); 
     Icon icon = new BevelArrowIcon(BevelArrowIcon.UP, false, false); 
     Image image = iconToImage(icon); 
     PopupMenu popup = new PopupMenu(); 
     MenuItem item = new MenuItem("Hello, World"); 
     final TrayIcon trayIcon = new TrayIcon(image, "Tip Text", popup); 
     ActionListener menuActionListener = new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       trayIcon.displayMessage("Good-bye", "Cruel World", 
         TrayIcon.MessageType.WARNING); 
      } 
     }; 
     item.addActionListener(menuActionListener); 
     popup.add(item); 
     ActionListener actionListener = new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       tray.remove(trayIcon); 
      } 
     }; 
     trayIcon.addActionListener(actionListener); 
     tray.add(trayIcon); 
    } 

    static Image iconToImage(Icon icon) { 
     if (icon instanceof ImageIcon) { 
      return ((ImageIcon) icon).getImage(); 
     } else { 
      int w = icon.getIconWidth(); 
      int h = icon.getIconHeight(); 
      GraphicsEnvironment ge = 
        GraphicsEnvironment.getLocalGraphicsEnvironment(); 
      GraphicsDevice gd = ge.getDefaultScreenDevice(); 
      GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
      BufferedImage image = gc.createCompatibleImage(w, h); 
      Graphics2D g = image.createGraphics(); 
      icon.paintIcon(null, g, 0, 0); 
      g.dispose(); 
      return image; 
     } 
    } 

    static class BevelArrowIcon implements Icon { 

     public static final int UP = 0;   // direction 
     public static final int DOWN = 1; 
     private static final int DEFAULT_SIZE = 16; 
     private Color edge1; 
     private Color edge2; 
     private Color fill; 
     private int size; 
     private int direction; 

     public BevelArrowIcon(int direction, boolean isRaisedView, 
       boolean isPressedView) { 
      if (isRaisedView) { 
       if (isPressedView) { 
        init(UIManager.getColor("controlLtHighlight"), 
          UIManager.getColor("controlDkShadow"), 
          UIManager.getColor("controlShadow"), 
          DEFAULT_SIZE, direction); 
       } else { 
        init(UIManager.getColor("controlHighlight"), 
          UIManager.getColor("controlShadow"), 
          UIManager.getColor("control"), 
          DEFAULT_SIZE, direction); 
       } 
      } else { 
       if (isPressedView) { 
        init(UIManager.getColor("controlDkShadow"), 
          UIManager.getColor("controlLtHighlight"), 
          UIManager.getColor("controlShadow"), 
          DEFAULT_SIZE, direction); 
       } else { 
        init(UIManager.getColor("controlShadow"), 
          UIManager.getColor("controlHighlight"), 
          UIManager.getColor("control"), 
          DEFAULT_SIZE, direction); 
       } 
      } 
     } 

     public BevelArrowIcon(Color edge1, Color edge2, Color fill, 
       int size, int direction) { 
      init(edge1, edge2, fill, size, direction); 
     } 

     @Override 
     public void paintIcon(Component c, Graphics g, int x, int y) { 
      switch (direction) { 
       case DOWN: 
        drawDownArrow(g, x, y); 
        break; 
       case UP: 
        drawUpArrow(g, x, y); 
        break; 
      } 
     } 

     @Override 
     public int getIconWidth() { 
      return size; 
     } 

     @Override 
     public int getIconHeight() { 
      return size; 
     } 

     private void init(Color edge1, Color edge2, Color fill, 
       int size, int direction) { 
      edge1 = Color.red; 
      edge2 = Color.blue; 
      this.edge1 = edge1; 
      this.edge2 = edge2; 
      this.fill = fill; 
      this.size = size; 
      this.direction = direction; 
     } 

     private void drawDownArrow(Graphics g, int xo, int yo) { 
      g.setColor(edge1); 
      g.drawLine(xo, yo, xo + size - 1, yo); 
      g.drawLine(xo, yo + 1, xo + size - 3, yo + 1); 
      g.setColor(edge2); 
      g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1); 
      int x = xo + 1; 
      int y = yo + 2; 
      int dx = size - 6; 
      while (y + 1 < yo + size) { 
       g.setColor(edge1); 
       g.drawLine(x, y, x + 1, y); 
       g.drawLine(x, y + 1, x + 1, y + 1); 
       if (0 < dx) { 
        g.setColor(fill); 
        g.drawLine(x + 2, y, x + 1 + dx, y); 
        g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); 
       } 
       g.setColor(edge2); 
       g.drawLine(x + dx + 2, y, x + dx + 3, y); 
       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); 
       x += 1; 
       y += 2; 
       dx -= 2; 
      } 
      g.setColor(edge1); 
      g.drawLine(xo + (size/2), yo + size - 1, xo 
        + (size/2), yo + size - 1); 
     } 

     private void drawUpArrow(Graphics g, int xo, int yo) { 
      g.setColor(edge1); 
      int x = xo + (size/2); 
      g.drawLine(x, yo, x, yo); 
      x--; 
      int y = yo + 1; 
      int dx = 0; 
      while (y + 3 < yo + size) { 
       g.setColor(edge1); 
       g.drawLine(x, y, x + 1, y); 
       g.drawLine(x, y + 1, x + 1, y + 1); 
       if (0 < dx) { 
        g.setColor(fill); 
        g.drawLine(x + 2, y, x + 1 + dx, y); 
        g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); 
       } 
       g.setColor(edge2); 
       g.drawLine(x + dx + 2, y, x + dx + 3, y); 
       g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); 
       x -= 1; 
       y += 2; 
       dx += 2; 
      } 
      g.setColor(edge1); 
      g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3); 
      g.setColor(edge2); 
      g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2); 
      g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1); 
     } 
    } 
} 
+3

PopupMenu no es un JPopupMenu, por lo que no puede hacer cosas como Acciones. –

2

Para el actual TrayIcon implementación, no es posible agregar directamente un JPopupMenu o JMenu a TrayIcon. Sin embargo, algunas personas se las arreglaron para solucionarlo implementando un MouseListener personalizado que escucha el clic derecho solo en el Trayicon. Cuando haga clic con el botón derecho del mouse, establezca la ubicación del menú emergente en event.getXOnScreen() y event.getYOnScreen() y configúrelo.

5

Se trata de un problema conocido. Hay un bug report, que contiene el esquema de una solución. Lo he adaptado a continuación:

// Build your popup menu 
final JPopupMenu trayPopup = new JPopupMenu(); 
// I'm using actions, there are other ways of doing this. 
trayPopup.add(someFantaticAction); 

// Get your tray icon 
trayIcon = new TrayIcon(icon, "My awesome application"); 

trayIcon.addMouseListener(new MouseAdapter() { 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     maybeShowPopup(e); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     maybeShowPopup(e); 
    } 

    private void maybeShowPopup(MouseEvent e) { 
     if (e.isPopupTrigger()) { 
      trayPopup.setLocation(e.getX(), e.getY()); 
      trayPopup.setInvoker(trayPopup); 
      trayPopup.setVisible(true); 
     } 
    } 
}); 
+0

'trayIcon.addMouseListener (nuevo MouseAdapter() {' no se compila en Java 1.8.111. Es necesario cambiar a 'MouseListener()'. – FaithReaper

+0

Eso es raro, ¿por qué Java 8 rechazaría MouseAdapter? –

+0

De todos modos, parece haber un problema con esta solución: la ventana emergente no se cierra cuando hace clic fuera de ella. –