3

我想JPopupMenu根据打开菜单的按钮的 y 位置设置 a 的位置。我的代码在我的第一台显示器上运行良好,但在我的第二台显示器上却失败了,它的高度不同。问题是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);

如何在其实际监视器上获取组件的位置?

4

3 回答 3

6

我使用第二个屏幕的边界得到了一个解决方案,这很简单:

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

感谢您的回答!

于 2012-05-03T10:03:34.940 回答
1

通常,当您调用“getLocationOnScreen()”时,它会获取组件“this”的位置(从代码中我不太明白“this”是谁)。

也许您可以尝试使用“button.getLocationOnScreen()”来获取按钮的位置。

于 2012-05-03T09:47:28.247 回答
1

这是一个小片段,展示了如何相对于另一个元素定位元素。它在按钮下方显示一个弹出菜单,在其左侧显示一个 JDialog。我在一个多屏幕环境中测试了它,其中辅助屏幕位于主屏幕的右侧。

此外,使用 getSize()、getWidth() 和 getHeight() 代替 getPreferredSize()。getSize()、getWidth 和 getHeight 返回组件的实际尺寸,而 getPreferredSize() 只是 LayoutManager 指示组件希望拥有的尺寸。

如果您使用该方法,请JPopupMenu.show()确保使用相对于调用程序组件的坐标和大小。

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);
    }
}
于 2012-05-03T10:02:44.117 回答