Получить расположение компонентов на текущем мониторе


Я хочу установить местоположение a JPopupMenu в зависимости от местоположения y кнопки, которая открывает меню. Мой код отлично работает на моем первом мониторе, но терпит неудачу на моем втором мониторе, который имеет другую высоту. Проблема заключается в том, что getLocationOnScreen() предоставляет расположение относительно главного экрана, а не фактический экран, на котором показан компонент.

Мой код:

// 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);

Как я могу получить местоположение компонента на его фактическом мониторе?

3 3

3 ответа:

Я получил решение для этого, используя границы второго экрана, это довольно просто:

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;
}

Спасибо за ваши ответы!

Обычно, когда вы вызываете " getLocationOnScreen ()", он получает расположение компонента " this "(из кода я не совсем понимаю, кто" this").

Возможно, вы можете попытаться получить местоположение кнопки, используя "button.getLocationOnScreen ()".

Вот небольшой фрагмент, который показывает, как расположить элементы относительно друг друга. Он отображает всплывающее меню под кнопкой и 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);
    }
}