Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JPopupMenu positioning

705 views
Skip to first unread message

Sabine Dinis Blochberger

unread,
Apr 27, 2011, 11:42:37 AM4/27/11
to
To: comp.lang.java.gui
JPopupMenu positioning

I have a button, which, when clicked, should show a popup menu alignd
with its lower right corner.

The issue is that the popup menu shows in a wrong place with the first
click on the button, and in the correct one on every subsequent click,
even when moving or resizing the window.

source to display the problem:
-snip-
public class NewJFrame extends javax.swing.JFrame {

/** Creates new form NewJFrame */
public NewJFrame() {
initComponents();
}

private void initComponents() {

jPopupMenu1 = new javax.swing.JPopupMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenuItem2 = new javax.swing.JMenuItem();
jButton1 = new javax.swing.JButton();

jMenuItem1.setText("Item 1");
jPopupMenu1.add(jMenuItem1);

jMenuItem2.setText("Item 2");
jPopupMenu1.add(jMenuItem2);

setDefaultCloseOperation(javax.swing.WindowConstants
.EXIT_ON_CLOSE);

jButton1.setText("jButton1");
jButton1.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent
evt) {
jButton1ActionPerformed(evt);
}
});

javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax
.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment
.TRAILING, layout.createSequentialGroup()
.addContainerGap(206, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
);
layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addContainerGap(219, Short.MAX_VALUE))
);

pack();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent
evt) {
// show the popupmenu
jPopupMenu1.show(jButton1, jButton1.getWidth() -
jPopupMenu1.getWidth(),
jButton1.getHeight());
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}

private javax.swing.JButton jButton1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JPopupMenu jPopupMenu1;
}
-snip-

Any way to make it behave the way I want to (show up in the correct
place on the first try)? I have tried

JFrame.invalidate()
JFrame.validate()
JFrame.pack()

JPopupMenu.invalidate()
JPopupMenu.validate()
JPopupMenu.pack()

I also tried to set the popup menus on screen location directly, but
never found out how to get the correct point. This might be a possible
solution, to call jPopupMenu1.setLocation().

Thanks again.
--
Sabine Dinis Blochberger

Op3racional
www.op3racional.eu

---
* Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24

Thomas Fritsch

unread,
Jan 23, 2008, 7:04:14 AM1/23/08
to
Sabine Dinis Blochberger schrieb:

> JPopupMenu positioning
>
> I have a button, which, when clicked, should show a popup menu alignd
> with its lower right corner.
>
> The issue is that the popup menu shows in a wrong place with the first
> click on the button, and in the correct one on every subsequent click,
> even when moving or resizing the window.
>
> source to display the problem:
[...]

> private void jButton1ActionPerformed(java.awt.event.ActionEvent
> evt) {
> // show the popupmenu
> jPopupMenu1.show(jButton1, jButton1.getWidth() -
> jPopupMenu1.getWidth(),
> jButton1.getHeight());
> }
[...]
I've reproduced your problem. In the debugger I saw:
When the method is called for the first time, jPopupMenu1.getWidth()
returns 0, because the popup (a package-private member variable in
JPopupMenu) is not yet realized.
When it is called the for second/third/... time, jPopupMenu1.getWidth()
returns 20, and all is fine.

>
> Any way to make it behave the way I want to (show up in the correct
> place on the first try)? I have tried
[...]
> JPopupMenu.pack()
I tried that, too, and didn't succeed.
Looking into JPopupMenu's source code, you see that JPopupMenu.pack() is
essentially a no-op, when JPopupMenu's popup member is not yet realized.

>
> I also tried to set the popup menus on screen location directly, but
> never found out how to get the correct point. This might be a possible
> solution, to call jPopupMenu1.setLocation().

I would take a pragmatic route, and decide to display the popup menu
*left*-aligned, instead of *right*-aligned to the button:


private void jButton1ActionPerformed(java.awt.event.ActionEvent
evt) {
// show the popupmenu

jPopupMenu1.show(jButton1, 0, jButton1.getHeight());
}
I know this is not quite what wanted, but at least it behaves consistently.

--
Thomas


Sabine Dinis Blochberger

unread,
Jan 23, 2008, 7:47:56 AM1/23/08
to
Thomas Fritsch wrote:

> Sabine Dinis Blochberger schrieb:

> [...]
> I've reproduced your problem. In the debugger I saw:
> When the method is called for the first time, jPopupMenu1.getWidth()
> returns 0, because the popup (a package-private member variable in
> JPopupMenu) is not yet realized.
> When it is called the for second/third/... time, jPopupMenu1.getWidth()
> returns 20, and all is fine.

That is a great insight!

I have tried figuring out the location for the menu after the call to
show (using setLocation()), but was having problem determining the Point
(on screen, or in relation to the frame). I suspect SwingUtilities might
help with the conversion of coordinate spaces.

> >
> > I also tried to set the popup menus on screen location directly, but
> > never found out how to get the correct point. This might be a possible
> > solution, to call jPopupMenu1.setLocation().
> I would take a pragmatic route, and decide to display the popup menu
> *left*-aligned, instead of *right*-aligned to the button:
> private void jButton1ActionPerformed(java.awt.event.ActionEvent
> evt) {
> // show the popupmenu
> jPopupMenu1.show(jButton1, 0, jButton1.getHeight());
> }
> I know this is not quite what wanted, but at least it behaves consistently.
>

Yes, that is what I will put inplace now, until I get more time to
fiddle, which is probably never <g>.

Thank you very much for your time, Thomas.

0 new messages