相对于其他主要 JFrame 上的元素显示 JFrame

Display JFrame relative to elements on other main JFrame

例如,您可以想象您被要求重新发明下拉菜单。正确的做法似乎是制作 JFrame 并在单击某个元素时显示它。这样的 JFrame 将是未修饰的。我正在做这个。我的程序希望允许用户单击图像(代表某物)并从其他可用图像中单击 select。

所以我做了这样的JFrame:

public class FrameSummonerSpells extends JFrame {
  public FrameSummonerSpells() {
    settings = set;
    // Remove title bar, close buttons...
    setUndecorated(true); 
    setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    //Will populate the selection of objects in grid layout
    createButtons();
    //Will make the frame as large as the content
    pack();
    //Do not appear by default
    setVisible(false); 
  }
}

我从 JButton:

显示它
  private void showPopup() {
    //Create the popup if needed
    if(popup==null)
      createPopup();
    //Get location of this button
    Point location = getLocation();
    //Move the popup at the location of this button
    //Also move vertically so it appears UNDER the button
    popup.setLocation(location.x, location.y+this.getSize().height);
    //Show the popup
    popup.setVisible(true);
  }

如您所见,我设置的位置不是相对于按钮或框架设置的:

然而,应该注意的是,我发送给 setLocation 的参数被接受,但只是被错误地解释了。

因此我的问题是:如何生成一个可以包含 JComponent 的新对象(JFrame 或其他对象)出现在 window 或 甚至扩展 之上window 并保持与 window(或某些元素)的相对位置?

这是我要显示的:

How to spawn a new object (JFrame or something else

不要使用 JFrame。 child window 应该(可能)是一个 JDialog 并以 JFrame 作为所有者。

that the arguments I send to setLocation are accepted, but just wrongly interpreted.

尝试使用 getLocationOnScreen() 方法获取源组件的位置。您可能会使用该组件的高度来确定弹出窗口的位置,以便它显示在组件下方。

几乎不需要调整。

  1. JDialogJFrame 更好,因为它可以成为主框架的子 window。
  2. getLocation 没有给出正确的坐标。 getLocationOnScreen 做到了。

代码现在看起来像这样 - 我已经覆盖了 setVisible 以便框架在显示时始终对齐:

  @Override
  public void setVisible(boolean visible) {
    if(visible) {
      //Get location of the button
      Point location = parent_button.getLocationOnScreen();
      //Move the popup at the location of the
      //Also move vertically so it appears UNDER the button
      setLocation(location.x, location.y+parent_button.getSize().height);
    }
    //Call the original setVisible
    super.setVisible(visible); 
  }