如何确定系统托盘在屏幕上的位置?

如何确定系统托盘在屏幕上的位置?

问题描述:

每当用户点击系统托盘中的图标时,我想显示 JPopupMenu 。但是,任务栏可以位于屏幕上的任何位置 - 底部,顶部,右侧,左侧。

So I want to display a JPopupMenu whenever the user clicks the icon in the system tray. However, the task bar could be anywhere on the screen - bottom , top , right, left.

如何确定系统托盘的位置以便显示弹出框?

getX() getY()可以获得点击的坐标。可以做一些数学运算来正确显示弹出窗口吗?

How do I determine where the sys tray is so that I can display the popup?
getX() and getY() can get the coordinates of the click. Can some math be done to display the popup properly ?

我们将非常感谢一个简单的解释和示例代码。

A simple explanation and sample code will be appreciated.

另外,如果任务栏被隐藏,当我将 TrayIcon 添加到 SystemTray ?

Also, if the task bar is hidden, will an exception be generated when I add TrayIcon to the SystemTray?

在Swing本机中没有真正的方法可以做到这一点,不过,您可以使用以下内容导出可能的位置...

There's no real way to do this within Swing natively, however, you can derive the possible location with the following...

GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
Rectangle bounds = gd.getDefaultConfiguration().getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());

Rectangle safeBounds = new Rectangle(bounds);
safeBounds.x += insets.left;
safeBounds.y += insets.top;
safeBounds.width -= (insets.left + insets.right);
safeBounds.height -= (insets.top + insets.bottom);

System.out.println("Bounds = " + bounds);
System.out.println("SafeBounds = " + safeBounds);

Area area = new Area(bounds);
area.subtract(new Area(safeBounds));
System.out.println("Area = " + area.getBounds());

哪些输出

Bounds = java.awt.Rectangle[x=0,y=0,width=2560,height=1600]
SafeBounds = java.awt.Rectangle[x=0,y=40,width=2560,height=1560]
Area = java.awt.Rectangle[x=0,y=0,width=2560,height=40]

对于我的系统(注意,我的任务栏位于屏幕顶部)

For my system (note, my task bar is at the top of the screen)

已更新

正如我之前对您的托盘图标问题的回答所示...

As demonstrated in my previous answer to your question about tray icons...

public class TestTaskIcon {

  public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {

        Image img = null;
        try {
          img = ImageIO.read(new File("floppy_disk_red.png"));
        } catch (IOException e) {
          e.printStackTrace();
        }
        TrayIcon ti = new TrayIcon(img, "Tooltip");
        ti.addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            Rectangle bounds = getSafeScreenBounds(e.getPoint());
            JPopupMenu popup = new JPopupMenu();
            popup.add(new JLabel("hello"));

            Point point = e.getPoint();

            int x = point.x;
            int y = point.y;
            if (y < bounds.y) {
              y = bounds.y;
            } else if (y > bounds.y + bounds.height) {
              y = bounds.y + bounds.height;
            }
            if (x < bounds.x) {
              x = bounds.x;
            } else if (x > bounds.x + bounds.width) {
              x = bounds.x + bounds.width;
            }

            if (x + popup.getPreferredSize().width > bounds.x + bounds.width) {
              x = (bounds.x + bounds.width) - popup.getPreferredSize().width;
            }
            if (y + popup.getPreferredSize().height > bounds.y + bounds.height) {
              y = (bounds.y + bounds.height) - popup.getPreferredSize().height;
            }
            popup.setLocation(x, y);
            popup.setVisible(true);
          }
        });
        try {
          SystemTray.getSystemTray().add(ti);
        } catch (AWTException ex) {
          Logger.getLogger(TestTaskIcon.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
  }

  public static Rectangle getSafeScreenBounds(Point pos) {

    Rectangle bounds = getScreenBoundsAt(pos);
    Insets insets = getScreenInsetsAt(pos);

    bounds.x += insets.left;
    bounds.y += insets.top;
    bounds.width -= (insets.left + insets.right);
    bounds.height -= (insets.top + insets.bottom);

    return bounds;

  }

  public static Insets getScreenInsetsAt(Point pos) {
    GraphicsDevice gd = getGraphicsDeviceAt(pos);
    Insets insets = null;
    if (gd != null) {
      insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
    }
    return insets;
  }

  public static Rectangle getScreenBoundsAt(Point pos) {
    GraphicsDevice gd = getGraphicsDeviceAt(pos);
    Rectangle bounds = null;
    if (gd != null) {
      bounds = gd.getDefaultConfiguration().getBounds();
    }
    return bounds;
  }

  public static GraphicsDevice getGraphicsDeviceAt(Point pos) {

    GraphicsDevice device = null;

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice lstGDs[] = ge.getScreenDevices();

    ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);

    for (GraphicsDevice gd : lstGDs) {

      GraphicsConfiguration gc = gd.getDefaultConfiguration();
      Rectangle screenBounds = gc.getBounds();

      if (screenBounds.contains(pos)) {

        lstDevices.add(gd);

      }

    }

    if (lstDevices.size() > 0) {
      device = lstDevices.get(0);
    } else {
      device = ge.getDefaultScreenDevice();
    }

    return device;

  }
}