2

I am trying to create a popup on a button through the action listener with Java.

I have some code, but I can't get it to work, though I think I'm close! This code is from an example but for Pmenu.show, I had to remove the first arg, and I don't know what to replace it with, which seems to be the problem here.

btnOptions.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                final JPopupMenu Pmenu = new JPopupMenu();
                  JMenuItem menuItem = new JMenuItem("Cut");
                  Pmenu.add(menuItem);
                  menuItem = new JMenuItem("Copy");
                  Pmenu.add(menuItem);
                  menuItem = new JMenuItem("Paste");
                  Pmenu.add(menuItem);
                  menuItem = new JMenuItem("Delete");
                  Pmenu.add(menuItem);
                  menuItem = new JMenuItem("Undo");
                  Pmenu.add(menuItem);
                  Point location = MouseInfo.getPointerInfo().getLocation();
                  Pmenu.show(null, location.getX(), location.getY());
            }
        });
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Michael Scott
  • 429
  • 2
  • 8
  • 18

2 Answers2

3

try passing in the instance of your window. (this).

According to the documentation, the first parameter is the

invoker - the component in whose space the popup menu is to appear

So you want to show the popup menu in the window.

Madushan
  • 6,977
  • 31
  • 79
  • just as a little clarification, the coordinates past to the invoke method are relative to the supplied component. If you supply no component reference, then the coordinates are absolute to the screen – MadProgrammer Jul 23 '12 at 02:15
  • I literally typed in "this" (no quotes) but that didn't work. – Michael Scott Jul 23 '12 at 02:15
  • @Mad Programmer - I looked at that example and their code saus JDigit.this So I tried btnOptions.this but it tells me to create that class. So I tried another class, which is one of my more "main" class if you will. It was ComicDownloader.this and then .show wants me to remove the arguments. – Michael Scott Jul 23 '12 at 02:27
  • `JPopupMenu.show(Component invoker, int x, int y)`. You need to pass all three parameters. In your case I'd do something like `JPopupMneu.show((Component)e.getSource(), location.getX(), location.getY());` – MadProgrammer Jul 23 '12 at 04:23
2
Component source = (Component)evt.getSource();
Point location = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(location, source
Pmenu.show(source, location.getX(), location.getY());

The question that jumps out at me is "why?" Why do it this way? What is it your are trying to achieve?

UPDATE - Popup offset

This would display the popup centered horizontally against the source control (the button) and under it.

Component source = (Component)evt.getSource();
Point location = source.getLocation();
Dimension size = source.getSize();

int xPos = location.x + ((size.width - PMenu.getWidth()) / 2;
int yPos = location.y + size.height;
Pmenu.show(source, xPos, yPos);

This is, of course, just an example, you would be able to supply your layout information as you please

WORKING UPDATE

    Component source = (Component)evt.getSource(); 
    Dimension size = source.getSize(); 

    int xPos = ((size.width - Pmenu.getPreferredSize().width) / 2); 
    int yPos = size.height;

    Pmenu.show(source, xPos, yPos);

Because the popup location is relative to the source, we don't need the source's location information

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I have a settings button and when a user clicks it, I want a popup menu to appear. Is that what you're asking? – Michael Scott Jul 23 '12 at 17:23
  • Yeah, that's fine, just curious – MadProgrammer Jul 23 '12 at 19:25
  • @MichaelScott The main reason I wanted to know, is if you only want to show the popup because of the click, you probably don't need the mouse location. You can use the position of the button (either absolutely on the screen, or relative as we've already pointed out) and display the popup, for example, under the button – MadProgrammer Jul 24 '12 at 03:49
  • Ohhh, I am going to look at all this tonight. What would that code look like? – Michael Scott Jul 25 '12 at 00:41
  • evt is giving me an error so I had to create a variable just an fyi EventObject evt = null; Then I run the program and click the settings button but I get errors Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at ComicDownloader$6.actionPerformed(ComicDownloader.java:712) Line 712 is this Component source = (Component)evt.getSource(); – Michael Scott Jul 25 '12 at 03:46
  • @MichaelScott Sorry, I called it `evt` it's actually `e` in your code – MadProgrammer Jul 25 '12 at 03:55
  • This is my code. The popup, pops up but it's WAYY below the program. Component source = (Component)e.getSource(); Point location = source.getLocation(); Dimension size = source.getSize(); int xPos = location.x + ((size.width - Pmenu.getWidth()) / 2); int yPos = location.y + size.height; Pmenu.show(source, xPos, yPos); – Michael Scott Jul 26 '12 at 03:27
  • @MichaelScott Opps, thought that may happen, my bad, sorry, untested code. Check out the second update - I've test this one – MadProgrammer Jul 26 '12 at 04:11
  • Hey Mad, I was too busy over the summer, but I'm back and your new code is PERFECT! Thank you! – Michael Scott Aug 31 '12 at 21:31