0

You can for example imagine you were asked to re-invent dropdown menu. The right way to do that seems to make JFrame and display it when certain element is clicked. Such JFrame would be undecorated. I'm doing just this. My program wants to allow user to click on image (which represents something) and select from other images available.

So I made such 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); 
  }
}

And I display it from 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);
  }

As you can see, the position I set isn't set relative to the button or the frame:

image description

It should be noted, however, that the arguments I send to setLocation are accepted, but just wrongly interpreted.

My question therefore is: How to spawn a new object (JFrame or something else) that can contain JComponent, appear over the window or even extend over the window and keep relative position to the window (or some element)?

This is what I want to display:

image description

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Have you considered trying [`JFrame#setLocationRelativeTo`](http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setLocationRelativeTo(java.awt.Component))? Component coordinates are contextual to the container that they reside in, they are not screen coordinates – MadProgrammer Mar 13 '15 at 01:02
  • 1
    See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Mar 13 '15 at 02:37

2 Answers2

2

How to spawn a new object (JFrame or something else

Don't use a JFrame. A child window should (probably) be a JDialog with the JFrame as the owner.

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

Try using the getLocationOnScreen() method to get the location of your source component. You would probably use the height of that component to determine the location of your popup so it shows below the component.

camickr
  • 321,443
  • 19
  • 166
  • 288
0

Few tweaks were needed.

  1. JDialog is better for this than JFrame as it can be made child window of the main frame.
  2. The getLocation didn't give the correct coordinates. getLocationOnScreen did.

And the code now looks like this - I've overriden setVisible so that the frame always aligns itself when shown:

  @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); 
  }
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • `setLocationRelativeToParent(...)` is not needed. This will set the location so that the popup is centered on the parent. Then the next line of code overrides the location. Use one or the other, not both. – camickr Mar 13 '15 at 14:40
  • Thank you very much for help :) I removed that. – Tomáš Zato Mar 13 '15 at 15:19