How to Set Focus on JTextField? - java

I make my game run without mouse so using pointer is not a choice. High Score menu will show when player lose.
this is my code
highScore=new MyTextField("Your Name");
highScore.addKeyListener(this);
highScore.setFont(font);
highScore.requestFocusInWindow();
I have tried
highScore.setFocusable(true);
highScore.requestFocusInWindow();
highScore.requestFocus(true);
highScore.requestFocus();
but still not gained focus on my JTextField.
How to focus it?

If you want your JTextField to be focused when your GUI shows up, you can use this:
in = new JTextField(40);
f.addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
in.requestFocus();
}
});
Where f would be your JFrame and in is your JTextField.

if is there only one Top-Level Container then last lines in GUI constructor would be for example
.
.
.
myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myComponent.grabFocus();
myComponent.requestFocus();//or inWindow
}
});

public void actionPerformed(ActionEvent arg0)
{
if (arg0.getSource()==clearButton)
{
enterText.setText(null);
enterText.grabFocus(); //Places flashing cursor on text box
}
}

Try this one,
myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myComponent.grabFocus();
myComponent.requestFocus();//or inWindow
}
});

If the page contains multiple item and like to set the tab sequence and focus I will suggest to use FocusTraversalPolicy.
grabFocus() will not work if you are using FocusTraversalPolicy.
Sample code
int focusNumber = 0;
Component[] focusList;
focusList = new Component[] { game, move, amount, saveButton,
printButton, editButton, deleteButton, newButton,
settingsButton };
frame.setFocusTraversalPolicy(new FocusTraversalPolicy() {
#Override
public Component getLastComponent(Container aContainer) {
return focusList[focusList.length - 1];
}
#Override
public Component getFirstComponent(Container aContainer) {
return focusList[0];
}
#Override
public Component getDefaultComponent(Container aContainer) {
return focusList[1];
}
#Override
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
focusNumber = (focusNumber + 1) % focusList.length;
if (focusList[focusNumber].isEnabled() == false) {
getComponentAfter(focusCycleRoot, focusList[focusNumber]);
}
return focusList[focusNumber];
}
#Override
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
focusNumber = (focusList.length + focusNumber - 1)
% focusList.length;
if (focusList[focusNumber].isEnabled() == false) {
getComponentBefore(focusCycleRoot, focusList[focusNumber]);
}
return focusList[focusNumber];
}
});

In my case nothing above worked untill I called requestFocus() AFTER my constructor has returned.
MyPanel panel = new MyPanel(...);
frame.add(panel);
panel.initFocus();
MyPanel.initFocus() would have:
myTextField.requestFocus();
And it works.

This code mouse cursor “jtextfield” “Jcombobox” location focused
try {
Robot robot = new Robot();
int x = Jtextfield.getLocationOnScreen().x;
int y= Jtextfield.getLocationOnScreen().y;
JOptionPane.showMessageDialog(null, x+"x< - y>"+y);// for I location see
robot.mouseMove(x, y);
} catch (AWTException ex) {
ex.printStackTrace();
}

It was not working for me when tried to use:
JOptionPane.showConfirmDialog(...)
But -
I found a solution !
Very primitive, but works.
Just jump to the field by java.awt.Robot using key "Tab".
For example:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
If you should press multiple times on "Tab" to get your Component you can use below method:
GUIUtils.pressTab(3);
Definition:
public static void pressTab(int amountOfClickes)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
Robot robot = new Robot();
int i = amountOfClickes;
while (i-- > 0)
{
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);
}
}
catch (AWTException e)
{
System.out.println("Failed to use Robot, got exception: " + e.getMessage());
}
}
});
}
If your Component location is dynamic, you can run over the while loop without limitation, but add some focus listener on the component, to stop the loop once arrived to it.

While yourTextField.requestFocus() is A solution, it is not the best since in the official Java documentation this is discourage as the method requestFocus() is platform dependent.
The documentation says:
Note that the use of this method is discouraged because its behavior is platform dependent. Instead we recommend the use of requestFocusInWindow().
Use yourJTextField.requestFocusInWindow() instead.

How about put jTextField.requestFocusInWindow(); into jTextField FocusLost event?
Works for me
have 5 controls on JPanel
Soon as click on MessageBox, focus lost on jTextField.
Used all the suggested codes but no luck
Only above method works my case.

Related

Using Jinput to pop up a JFrame WIndow alarm

Using Jinput and Java in Netbeans, I'm working on a very small project that simply Pops up a JFrame alarm window when lets say a user presses down on the 'K' on the keyboard and terminates the JFrame alarm window when the user lets go of 'k'. In my code, I seemed to get stuck in the while loop as the JFrame opened on the first press down and couldn't seem to close. I researched and I found that using javax.swing.Timer was the better way to do it. However, since I'm a newbie at this, all the different ways to use timer just made me even more confused. Could someone please see my code and point me in the right direction?
Here is my code;
public void startPolling() {
while(true) {
ControllerEnvironment.getDefaultEnvironment().getControllers();
ca[index].poll();
EventQueue queue = ca[index].getEventQueue();
Event event = new Event();
while(queue.getNextEvent(event)) {
StringBuffer buffer = new StringBuffer(ca[index].getName());
buffer.append(" at ");
buffer.append(event.getNanos()).append(", ");
Component comp = event.getComponent();
buffer.append(comp.getName()).append(" changed to ");
float value = event.getValue();
if(comp.isAnalog()) {
buffer.append(value);
} else {
if(value==1.0f) {
buffer.append("On");
if ("K".equals(comp.getName())){
alarmBox();
}
} else {
buffer.append("Off");
if ("K".equals(comp.getName())){
alarmBox.setVisible(false);
}
}
}
System.out.println(buffer.toString());
}
}
}
alarmBox() is my JFrame.
I was working on it and here is my updated code:
public void startPolling() {
Timer timer = new Timer(50, new ActionListener() {
public void actionPerformed(ActionEvent e) {
ca[index].poll();
EventQueue queue = ca[index].getEventQueue();
Event event = new Event();
while(queue.getNextEvent(event)) {
StringBuffer buffer = new StringBuffer(ca[index].getName());
buffer.append(" at ");
buffer.append(event.getNanos()).append(", ");
Component comp = event.getComponent();
buffer.append(comp.getName()).append(" changed to ");
float value = event.getValue();
if(comp.isAnalog()) {
buffer.append(value);
} else {
if(value==1.0f) {
buffer.append("On");
if ("K".equals(comp.getName())){
alarmBox();
}
} else {
buffer.append("Off");
if ("K".equals(comp.getName())){
alarmBox.dispose();
}
}
}
System.out.println(buffer.toString());
}
try {
Thread.sleep(20);
} catch (InterruptedException f) {
f.printStackTrace();
}
}
}); timer.start();
if you just want to open and close window,y to use timer?
you have a very complicated code,for a simple task.
you can add a ComponentListener to your JFrame to hide,somthing like this:
frame.addComponentListener(new ComponentAdapter(){
public void componentMoved(ComponentEvent e) {
if (popup.isVisible()){
popup.setVisible(false);
}
}
});

JButton breaks my Keylistener

JAVA USING NETBEANS
Hello stackoverflow, i have a problem i would like help with. In a nutshell, I have a mouselistener and a keylistener on a jpanel, everything works fine except when i press one of my jbuttons, then the keylistener goes AWOL. Can any1 explain the problem, is the panels focus now on the buttons instead of the keyboard, im at a lost.
Here is the code, if somethings are not reference, assume its are there the entire panel code was 500+ long so i cut quite a bit.
Thanks in advance for any help.
package tankgame;
public class TankPanel extends JPanel implements KeyListener,
MouseListener,MouseMotionListener
{
JButton back,shop, menu, health, speed, rapidfire, shootradius;
TankPanel()
{
setLayout( null );
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setFocusable(true);
shop= new JButton("SHOP");
shop.addMouseListener(this);
shop.setBounds(400,0, 80,15);
add(shop);
}
public void keyPressed(KeyEvent k)
{
char c = k.getKeyChar();
if(c=='u')
{
u++;
System.out.println(u+" = u");
}
if(c=='i')
{
i++;
System.out.println(i+" = i");
}
if( c == 'd' )
{
if(Ptank.pic==PlayerTankE)
{
if(Ptank.move==true)
{
Pbarrel.x+=Ptank.speed;
Ptank.x+=Ptank.speed;
}
}
else
{
if(Ptank.pic==PlayerTankN || Ptank.pic==PlayerTankS)
{
Ptank.x = Ptank.x - 5;
Ptank.y=Ptank.y+5;
}
Ptank.setPic(PlayerTankE);
Ptank.width=35;
Ptank.height = 23;
}
}
setFocusable(true);
repaint();
}
public void keyReleased(KeyEvent k)
{
}
public void keyTyped(KeyEvent k)
{
}
public void mouseClicked(MouseEvent e)
{
//Invoked when the mouse button has been clicked (pressed and released)
}
public void mouseEntered(MouseEvent e)
{//Invoked when the mouse enters a component.
}
public void mouseExited(MouseEvent e)
{ //Invoked when the mouse exits a component.
}
public void mousePressed(MouseEvent e)
{//Invoked when a mouse button has been pressed on a component.
if(e.getSource()==back)
{
System.out.println(456);
System.out.println(back.getLocation().x + " "+back.getLocation().y);
}
else if(e.getSource() == menu)
{
changebuttons("menu");
System.out.println(456);
System.out.println(menu.getLocation().x + " "+menu.getLocation().y);
}
else if(e.getSource() == shop)
{
changebuttons("shop");
System.out.println(456);
System.out.println(shop.getLocation().x + " "+shop.getLocation().y);
}
else if(e.getButton() == MouseEvent.BUTTON1)
{
destpoint= new Point();
destpoint.setLocation(mousex, mousey);
origin = new Point();
}
for(int i = 0; i< Ptank.rapidfire; i++)
{
if (origin.distance(destpoint) <= 100 && origin.distance(destpoint) >= 50)
{
Bullet add = new Bullet(this,destpoint);
add.getOrigin(origin);
add.setPic(PlayerBullet);
add.width=4;
add.height=4;
bulletList.add(add);
}
}
}
}
public void mouseReleased(MouseEvent e)
{//Invoked when a mouse button has been released on a component.
}
public void mouseDragged(MouseEvent e)
{//Invoked when a mouse button is pressed on a component and then dragged.
}
public void mouseMoved(MouseEvent e)
{
//Invoked when the mouse cursor has been moved onto a component but no buttons
Cursor cursor = Cursor.getDefaultCursor();
//you have a List<Polygon>, so you can use this enhanced for loop
cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
setCursor(cursor);
mousex=e.getX();
mousey=e.getY();
}
public void changebuttons(String x)
{
if(x.equals("shop"))
{
menu.setBounds(720, 0, 80, 15);
health.setBounds(0, 0, 125, 15);
speed.setBounds(150, 0, 125, 15);
shootradius.setBounds(300, 0, 200, 15);
rapidfire.setBounds(500, 0, 150, 15);
shop.setBounds(1000, 0, 150, 15);
}
}
KeyEvents are only generated on a component that has focus. When you click on the button is now has focus to key events won't be generated on the panel. You need to add:
panel.requestFocusInWindow()
in your ActionListener to give focus back to the panel.
However the better solution is to use Key Bindings as you can add bindings to a KeyStroke even when the component doesn't have focus.
Don't use a KeyListener which requires the component be focused to work. Instead consider using Key Bindings. You can find out how to use these guys at the Swing tutorial: How To Use Key Bindings. If you need more specific help, you will want to post a much smaller bit of code than you show above, code that is self-contained and will actually compile and run for us, an SSCCE.

Right click on JButton

I am trying to write a Minesweeper clone in Java for fun. I have a grid of JButtons whose labels I will change to represent the danger count, flags, etc.
My problem is, I don't know how to get a right click on a JButton to depress the button. I've done the following:
button.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
boolean mine = field.isMine(x, y);
if (e.isPopupTrigger()) {
button.setText("F");
}
else {
if (mine) {
button.setText("X");
}
}
}
});
This doesn't seem to be working at all; the "F" is never shown, only the "X" part. But more importantly, this does nothing for depressing the button.
EDIT: Macs have popup trigger happen on mousePress, not mouseClick.
EDIT: Here's the solution I worked out based off of accepted answer:
button.addMouseListener(new MouseAdapter(){
boolean pressed;
#Override
public void mousePressed(MouseEvent e) {
button.getModel().setArmed(true);
button.getModel().setPressed(true);
pressed = true;
}
#Override
public void mouseReleased(MouseEvent e) {
//if(isRightButtonPressed) {underlyingButton.getModel().setPressed(true));
button.getModel().setArmed(false);
button.getModel().setPressed(false);
if (pressed) {
if (SwingUtilities.isRightMouseButton(e)) {
button.setText("F");
}
else {
button.setText("X");
}
}
pressed = false;
}
#Override
public void mouseExited(MouseEvent e) {
pressed = false;
}
#Override
public void mouseEntered(MouseEvent e) {
pressed = true;
}
});
add(button);
Minesweeper clone http://grab.by/1y9z
Button can't be pressed by right click. Add such a lines to you mouse listener
mousePressed:
if(isRightButtonPressed) {underlyingButton.getModel().setPressed(true));
mouseReleased:
if(needReset) {underlyingButton.getModel().setPressed(false));
or do there whatever want.
I wouldn't use isPopupTrigger but directly check for the right button:
button.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
boolean mine = field.isMine(x, y);
if (e.getButton() == MouseEvent.BUTTON2) {
button.setText("F");
}
...
Just a small addition: the simplest way to check for the right button is SwingUtilities.isRightMouseButton
As you have mentioned that checking for "mousePressed" solved your issue. And the Javadoc of isPopupTrigger would explain the need for this:
public boolean isPopupTrigger()
...
Note: Popup menus are triggered differently on different systems. Therefore, isPopupTrigger should be checked in both mousePressed and mouseReleased for proper cross-platform functionality.
Also see the section on The Mouse Listener API in the Java Swing tutorial.
MouseEvent has some properties
static int BUTTON1
static int BUTTON2
static int BUTTON3
among others. Check those when your event fires.
EDIT
public int getButton()
Returns which, if any, of the mouse buttons has changed state.
The button being visibly depressed on right click isn't part of the "normal" behavior of buttons. You may be able to fake it using JToggleButtons, or simply changing the button's background color and maybe border while the right mouse button is being held down.
If you are certain that the event is properly being triggered (debug FTW!) and that the button.setText("F") is happening, then perhaps you simply need to repaint.
Repaint the button.
http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html#repaint(java.awt.Rectangle)
This works for me fine on Mac:
import java.awt.event.*;
import javax.swing.*;
public class ButtonTest extends JFrame {
JButton button;
public ButtonTest() {
button = new JButton("W");
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == 3) { // if right click
button.setText("F");
button.getModel().setPressed(false);
// button.setEnabled(true);
} else {
button.setText("X");
button.getModel().setPressed(true);
// button.setEnabled(false);
}
}
});
this.add(button);
this.setVisible(true);
}
public static void main(String[] args) {
new ButtonTest();
}
}
You might as well check for e.getButton() == 2 but I don't know when this one is triggered on Macs.

How do you set a focus on JTextField in Swing?

I created a form using Swing in Java. In the form I have used a JTextField on which I have to set the focus whenever I press a key. How do I set focus on a particular component in Swing?
Would Component.requestFocus() give you what you need?
This would work..
SwingUtilities.invokeLater( new Runnable() {
public void run() {
Component.requestFocus();
}
} );
Now that we've searched the API all we need to do is read the API.
According to the API documentation:
"Because the focus behavior of this
method is platform-dependent,
developers are strongly encouraged to
use requestFocusInWindow when
possible. "
Note that all of the above fails for some reason in a JOptionPane. After much trial and error (more than the above stated 5 minutes, anyway), here is what finally worked:
final JTextField usernameField = new JTextField();
// ...
usernameField.addAncestorListener(new RequestFocusListener());
JOptionPane.showOptionDialog(this, panel, "Credentials", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
public class RequestFocusListener implements AncestorListener {
#Override
public void ancestorAdded(final AncestorEvent e) {
final AncestorListener al = this;
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JComponent component = e.getComponent();
component.requestFocusInWindow();
component.removeAncestorListener(al);
}
});
}
#Override
public void ancestorMoved(final AncestorEvent e) {
}
#Override
public void ancestorRemoved(final AncestorEvent e) {
}
}
You can use also JComponent.grabFocus(); it is the same

Showing/hiding a JPopupMenu from a JButton; FocusListener not working?

I needed a JButton with an attached dropdown style menu. So I took a JPopupMenu and attached it to the JButton in the way you can see in the code below. What it needs to do is this:
show the popup when clicked
hide it if clicked a second time
hide it if an item is selected in the popup
hide it if the user clicks somewhere else in the screen
These 4 things work, but because of the boolean flag I'm using, if the user clicks somewhere else or selects an item, I have to click twice on the button before it shows up again. That's why I tried to add a FocusListener (which is absolutely not responding) to fix that and set the flag false in these cases.
EDIT: Last attempt in an answer post...
Here are the listeners: (It's in a class extending JButton, so the second listener is on the JButton.)
// Show popup on left click.
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
}
});
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (isShowingPopup) {
isShowingPopup = false;
} else {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
isShowingPopup = true;
}
}
});
I've been fighting with this for way too long now. If someone can give me a clue about what's wrong with this, it would be great!
Thanks!
Code:
public class Button extends JButton {
// Icon.
private static final ImageIcon ARROW_SOUTH = new ImageIcon("ArrowSouth.png");
// Unit popup menu.
private final JPopupMenu menu;
// Is the popup showing or not?
private boolean isShowingPopup = false;
public Button(int height) {
super(ARROW_SOUTH);
menu = new JPopupMenu(); // menu is populated somewhere else
// FocusListener on the JPopupMenu
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
}
});
// ComponentListener on the JPopupMenu
menu.addComponentListener(new ComponentListener() {
#Override
public void componentShown(ComponentEvent e) {
System.out.println("SHOWN");
}
#Override
public void componentResized(ComponentEvent e) {
System.out.println("RESIZED");
}
#Override
public void componentMoved(ComponentEvent e) {
System.out.println("MOVED");
}
#Override
public void componentHidden(ComponentEvent e) {
System.out.println("HIDDEN");
}
});
// ActionListener on the JButton
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (isShowingPopup) {
menu.requestFocus();
isShowingPopup = false;
} else {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
isShowingPopup = true;
}
}
});
// Skip when navigating with TAB.
setFocusable(true); // Was false first and should be false in the end.
menu.setFocusable(true);
}
}
Here's a variant of Amber Shah's "big hack" suggestion I just made. Without the isShowingPopup flag...
It's not bulletproof, but it works quite well until someone comes in with an incredibly slow click to close the popup (or a very fast second click to reopen it...).
public class Button extends JButton {
// Icon.
private static final ImageIcon ARROW_SOUTH = new ImageIcon("ArrowSouth.png");
// Popup menu.
private final JPopupMenu menu;
// Last time the popup closed.
private long timeLastShown = 0;
public Button(int height) {
super(ARROW_SOUTH);
menu = new JPopupMenu(); // Populated somewhere else.
// Show and hide popup on left click.
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
timeLastShown = System.currentTimeMillis();
}
#Override public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {}
#Override public void popupMenuCanceled(PopupMenuEvent arg0) {}
});
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ((System.currentTimeMillis() - timeLastShown) > 300) {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
}
}
});
// Skip when navigating with TAB.
setFocusable(false);
}
}
As I said in comments, that's not the most elegant solution, but it's horribly simple and it works in 98% of the cases.
Open to suggestions!
Here is another approach which is not too bad of a hack, if not elegant, and which, as far as I could tell, works. First, at the very top, I added a second boolean called showPopup.
The FocusListener has to be as follows:
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
isShowingPopup = true;
}
});
The isShowingPopup boolean does not get changed anywhere else--if it gains focus, it assumes it's shown and if it loses focus, it assumes it isn't.
Next, the ActionListener on the button is different:
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (showPopup) {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
menu.requestFocus();
} else {
showPopup = true;
}
}
});
Now comes the really new bit. It's a MouseListener on the button:
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
System.out.println("ispopup?: " + isShowingPopup);
if (isShowingPopup) {
showPopup = false;
}
}
#Override
public void mouseReleased(MouseEvent e) {
showPopup = true;
}
});
Basically, mousePressed gets called before the menu loses focus, so isShowingPopup reflects whether the popup was shown before the button is pressed. Then, if the menu was there, we just set showPopup to false, so that the actionPerformed method does not show the menu once it gets called (after the mouse is let go).
This behaved as expected in every case but one: if the menu was showing and the user pressed the mouse on the button but released it outside of it, actionPerformed was never called. This meant that showPopup remained false and the menu was not shown the next time the button was pressed. To fix this, the mouseReleased method resets showPopup. The mouseReleased method gets called after actionPerformed, as far as I can tell.
I played around with the resulting button for a bit, doing all the things I could think of to the button, and it worked as expected. However, I am not 100% sure that the events will always happen in the same order.
Ultimately, I think this is, at least, worth trying.
You could use the JPopupMenu.isVisible() instead of your Boolean variable to check the current state of the popup menu.
Have you tried adding a ComponentListener to the JPopupMenu, so that you know when it's been shown and hidden (and update your isShowingPopup flag accordingly)? I'm not sure listening for focus changes is necessarily the right approach.
What you need is a PopupMenuListener:
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
System.out.println("MENU INVIS");
isShowingPopup = false;
}
#Override
public void popupMenuCanceled(PopupMenuEvent arg0) {
System.out.println("MENU CANCELLED");
isShowingPopup = false;
}
});
I inserted this into your code and verified that it works.
Well, I can't be sure without seeing all of your code, but is it possible that the popup never actually gets focus at all? I've had problems with things' not getting focus properly in Swing before, so it could be the culprit. Try calling setFocusable(true) on the menu and then calling requestFocus() when you make the menu appear.
I tried the Answer of Tikhon Jelvis (introducing a smart combination of focusListener and mouseListener). It does not work for me on Linux (Java7/gtk). :-(
Reading http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#requestFocus%28%29 there is written "Note that the use of this method is discouraged because its behavior is platform dependent."
It may be that the order of listener calls changed with Java7 or it changes with GTK vs Windows. I would not recommend this solution if you want to be platform independent.
BTW: I created a new account on stackoverflow to give this hint. It seems I am not allowed to comment to his answer (because of reputation). But it seems I have a button to edit it. This stackoverflow is a very funny thing. :-)

Categories

Resources