2012-10-01 20 views
14

voglio aggiungere JPopupMenu alla barra delle applicazioni come TrayIcon (cioèsystemTray.add(trayIcon)), ma non ho trovato un modo per fare il so.From docs il costruttore di TrayIcon assomiglia:Aggiunta JPopupMenu al TrayIcon

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

C'è un modo per farlo?

+8

Benvenuti nel mio mondo. È frustrante come questo non sia stato implementato. In ogni caso, potresti trovare [Uso di JPopupMenu in TrayIcon] (http://weblogs.java.net/blog/ixmal/archive/2006/05/using_jpopupmen.html) di interesse – MadProgrammer

+0

Utilizzare un MouseListener e agire su mouseReleased è la strada da percorrere. Puoi anche dare un'occhiata a [questa risposta] (http://stackoverflow.com/questions/12638845/adding-a-vertical-separator-in-popupmenu-in-the-task-bar/12640454#12640454) che è per un altro scopo ma visualizza anche un JPopupMenu su un TrayIcon. –

risposta

-1

Si può guardare in tutorial di Oracle e l'esempio how to use the system tray

+1

Come afferma doc/tutorial, il supporto di TrayIcon è limitato e fino ad oggi, JPopupMenu non può essere aggiunto in TrayIcon direttamente tramite il costruttore, quindi il downvote. – FaithReaper

0

non riesco a vedere alcun problema con costruttore pubblico TrayIcon(Image image, String tooltip, PopupMenu popup), nor is Java7 su 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 non è un JPopupMenu e quindi non può fare cose come Actions. –

2

Per la corrente TrayIcon implementazione, non è possibile aggiungere direttamente uno JPopupMenu o JMenu a TrayIcon. Tuttavia, alcune persone sono riuscite a risolverlo implementando un custom MouseListener che ascolta solo il clic con il pulsante destro del mouse su Trayicon. Quando si fa clic con il pulsante destro del mouse, impostare la posizione del Popupmenu su event.getXOnScreen() e event.getYOnScreen() e impostarlo su di esso.

5

Questo è un problema noto. C'è un bug report, che contiene lo schema di una soluzione alternativa. L'ho adattato qui sotto:

// 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 (nuovo MouseAdapter() {' non viene compilato su Java 1.8.111. È necessario passare a 'MouseListener()'. – FaithReaper

+0

È strano, perché Java 8 rifiuta MouseAdapter? –

+0

In ogni caso, sembra esserci un problema con questa soluzione: il popup non viene chiuso quando si fa clic all'esterno. –