How do I determine which monitor a Swing mouse event occurs in?
Asked Answered
F

5

11

I have a Java MouseListener on a component to detect mouse presses. How can I tell which monitor the mouse press occurred in?

@Override
public void mousePressed(MouseEvent e) {
  // I want to make something happen on the monitor the user clicked in
}

The effect I'm trying to achieve is: when the user presses the mouse button in my app, a popup window shows some info, until the mouse is released. I want to ensure this window is positioned where the user clicks, but I need to adjust the window position on the current screen so that the entire window is visible.

Ferula answered 8/8, 2009 at 8:55 Comment(2)
I'm not sure it's that easy. I think you have to capture the mouse to see any clicks outside your window, and I have no idea how to do that in java (Hence the comment--I have no "Answer").Witted
Bill, you are right, it is not easy. That's why I asking the collective brain that is Stack Overflow!Ferula
D
15

You can get display information from java.awt.GraphicsEnvironment. You can use this to get a information about your local system. Including the bounds of each monitor.

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
...
Decastro answered 8/8, 2009 at 9:57 Comment(1)
This is half the solution, and it helped me work out the whole solution. Thanks!Ferula
F
2

Rich's answer helped me find a whole solution:

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();
}
Ferula answered 8/8, 2009 at 13:21 Comment(1)
If you want to get the default monitor, see my updated answer, on multi-screen systems where Windows should be centered across all displays, getMaximumWindowBounds() returns the bounds of the entire display area.Decastro
C
1

Since Java 1.6 you can use getLocationOnScreen, in previous versions you must get the location of the component that generated the event:

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

You will have to use the GraphicsEnvironment class to get the bound of the screen.

Corena answered 8/8, 2009 at 10:16 Comment(0)
S
0

Maybe e.getLocationOnScreen(); will work? It's only for java 1.6.

Sarcasm answered 8/8, 2009 at 10:3 Comment(0)
P
0

Leaving this here to help anyone else who may be searching for this:

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;
}
Pertinacious answered 27/9, 2022 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.