如何确定鼠标事件发生在哪个监视器上?

10

我在组件上有一个Java的MouseListener用于检测鼠标按下事件。如何判断鼠标按下事件发生在哪个显示器上?

@Override
public void mousePressed(MouseEvent e) {
  // I want to make something happen on the monitor the user clicked in
}
我想要实现的效果是:当用户在我的应用程序中按下鼠标按钮时,会弹出一个窗口显示一些信息,直到松开鼠标。我想确保此窗口位于用户单击的位置,但我需要调整窗口在当前屏幕上的位置,以便整个窗口可见。

我不确定这是否那么容易。我认为你必须捕获鼠标才能看到窗口外的任何点击,而我不知道如何在Java中实现这一点(因此有评论 - 我没有“答案”)。 - Bill K
1
Bill,你说得对,这确实不容易。这就是为什么我向 Stack Overflow 这个集体智慧提问的原因! - Steve McLeod
5个回答

14
您可以从 java.awt.GraphicsEnvironment 获取显示信息。您可以使用它来获取有关本地系统的信息,包括每个显示器的边界。
Point point = event.getPoint();

GraphicsEnvironment e 
     = GraphicsEnvironment.getLocalGraphicsEnvironment();

GraphicsDevice[] devices = e.getScreenDevices();

Rectangle displayBounds = null;

//now get the configurations for each device
for (GraphicsDevice device: devices) { 

    GraphicsConfiguration[] configurations =
        device.getConfigurations();
    for (GraphicsConfiguration config: configurations) {
        Rectangle gcBounds = config.getBounds();

        if(gcBounds.contains(point)) {
            displayBounds = gcBounds;
        }
    }
}

if(displayBounds == null) {
    //not found, get the bounds for the default display
    GraphicsDevice device = e.getDefaultScreenDevice();

    displayBounds =device.getDefaultConfiguration().getBounds();
}
//do something with the bounds
...

这是解决问题的一半,它帮助我解决了整个问题。谢谢! - Steve McLeod

2

Rich的回答帮助我找到了一个完整的解决方案:

public void mousePressed(MouseEvent e) {
    final Point p = e.getPoint();
    SwingUtilities.convertPointToScreen(p, e.getComponent());
    Rectangle bounds = getBoundsForPoint(p);
    // now bounds contains the bounds for the monitor in which mouse pressed occurred
    // ... do more stuff here
}


private static Rectangle getBoundsForPoint(Point point) {
    for (GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
        for (GraphicsConfiguration config : device.getConfigurations()) {
            final Rectangle gcBounds = config.getBounds();
            if (gcBounds.contains(point)) {
                return gcBounds;
            }
        }
    }
    // if point is outside all monitors, default to default monitor
    return GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
}

如果您想获取默认监视器,请查看我的更新答案,在多屏幕系统中,Windows 应该在所有显示器上居中,getMaximumWindowBounds() 返回整个显示区域的边界。 - Rich Seller

1

自Java 1.6以来,您可以使用getLocationOnScreen,在之前的版本中,您必须获取生成事件的组件的位置:

Point loc;
// in Java 1.6
loc = e.getLocationOnScreen();
// in Java 1.5 or previous
loc = e.getComponent().getLocationOnScreen();

你需要使用GraphicsEnvironment类来获取屏幕的边界。

0
留下这段话是为了帮助那些可能正在寻找解决办法的人:

private int screenIndexOfMouse() {
    GraphicsDevice myScreen = MouseInfo.getPointerInfo().getDevice();
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] allScreens = env.getScreenDevices();
    int myScreenIndex = -1;
    for (int i = 0; i < allScreens.length; i++) {
        if (allScreens[i].equals(myScreen))
        {
            myScreenIndex = i;
            break;
        }
    }
    
    return myScreenIndex;
}

0

或许 e.getLocationOnScreen(); 可以工作?这仅适用于Java 1.6。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接