Get component location on current monitor

I want to set the location JPopupMenudepending on the location of the button that opens the menu. My code works fine on my first monitor, but it doesn't work on my second monitor, which has different heights. The problem is that it getLocationOnScreen()provides a location relative to the main screen, and not the actual screen on which the component is displayed.

My code is:

// screenSize represents the size of the screen where the button is
// currently showing
final Rectangle screenSize = dateButton.getGraphicsConfiguration().getBounds();

final int yScreen = screenSize.height;
int preferredY;

// getLocationOnScreen does always give the relative position to the main screen
if (getLocationOnScreen().y + dateButton.getHeight() + datePopup.getPreferredSize().height > yScreen) {
  preferredY = -datePopup.getPreferredSize().height;
} else {
  preferredY = getPreferredSize().height;
}

datePopup.show(DateSpinner.this, 0, preferredY);

How to get the location of a component on its real monitor?

+3
source share
3 answers

I got a solution for this, using the borders of the second screen, it's pretty simple:

public static Point getLocationOnCurrentScreen(final Component c) {
  final Point relativeLocation = c.getLocationOnScreen();

  final Rectangle currentScreenBounds = c.getGraphicsConfiguration().getBounds();

  relativeLocation.x -= currentScreenBounds.x;
  relativeLocation.y -= currentScreenBounds.y;

  return relativeLocation;
}

Thank you for your responses!

+5
source

, "getLocationOnScreen()", "this" ( , "this").

, , "button.getLocationOnScreen()".

+1

, , . , JDialog - . , .

getSize(), getWidth() getHeight() getPreferredSize(). getSize(), getWidth getHeight , getPreferredSize() LayoutManager , .

JPopupMenu.show(), invoker.

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

public class Test2 {

    public static void main(String[] args) {

        final JFrame frame = new JFrame();
        final JButton button = new JButton("Hello");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JPopupMenu popupMenu = new JPopupMenu();
                popupMenu.add(new JMenuItem("Some test"));
                System.err.println(button.getLocationOnScreen());
                popupMenu.show(button, 0, button.getHeight());
                JDialog dialog = new JDialog(frame);
                dialog.setSize(100, 30);
                Point locationOnScreen = button.getLocationOnScreen();
                locationOnScreen.x += button.getWidth();
                dialog.setLocation(locationOnScreen);
                dialog.setVisible(true);
            }
        });
        frame.addComponentListener(new ComponentListener() {

            @Override
            public void componentShown(ComponentEvent e) {

            }

            @Override
            public void componentResized(ComponentEvent e) {
                info(button);
            }

            private void info(final JButton button) {
                if (button.isShowing()) {
                    System.err.println(button.getLocationOnScreen());
                    System.err.println(button.getGraphicsConfiguration().getBounds());
                }
            }

            @Override
            public void componentMoved(ComponentEvent e) {
                info(button);
            }

            @Override
            public void componentHidden(ComponentEvent e) {

            }
        });
        button.setPreferredSize(new Dimension(200, 60));
        frame.add(button);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }
}
+1

All Articles