JToggle disabled after popup hide

Hello experts,

I´m trying to do that a JToggleButton raises a popup and it must be hided in tree ways. First clicking in a menu option, deselecting the JToggleButton or clicking outside the popup and button.
What is happening is that I´m not reaching the right way to control it. I´m using a ActionListener to get ToggleButton events and a PopupMenuListener to change the JToggleButton state when it hides, but I´m having indesireable behaviors in the togglebutton when I click on it to hide the popup cause the hide event changes de button state to unselected than it generate the action event like I´m opening the menu again.

Some idea?



rubentrancosoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gnoonCommented:
Sounds like having more than 1 controller to control the JToggleButton state:

- mouse click on the button

  mouse click on the button --> button state change --> actionPerformed--> popup visible

- PopupMenuListener

  popup hiding --> popupMenuWillBecomeInvisible --> button state change (above) --> ...

Is this current behaviors?

If yes, you should code for checking which source generates event in actionPerformed, or using the JToogleButton state to decide popup visible.
0
objectsCommented:
can u post your code (in particular your action listener)
0
rubentrancosoAuthor Commented:
Sure,
here is the code!
I´ll make a new executable class to post here, for now the code is mixed and it will take more time.

===================================

            JToggleButton tb = new JToggleButton("ShowPopup");

            tb.addActionListener(
                  new ActionListener() {
                        public void actionPerformed( ActionEvent e ) {
                              JToggleButton b = ((JToggleButton)e.getSource());
                              boolean selected = b.isSelected();
                              if ( selected ) {
                                     showPopupUp();
                              }
                        }
                  }
            );


==========================================================

        popupMenu.addPopupMenuListener(
                    new PopupMenuListener( ) {
                          public void popupMenuCanceled( PopupMenuEvent e ) {
                          }
                          public void popupMenuWillBecomeVisible( PopupMenuEvent e ) {
                          }
                          public void popupMenuWillBecomeInvisible( PopupMenuEvent e ) {
                                tb.setSelected(false);
                          }
                    }
        );
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

objectsCommented:
try using the following to unselect the button.

EventQueue.invokeLater(new Runnable()
   {   public void run() {  tb.setSelected(false); }});
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rubentrancosoAuthor Commented:
a better sample...

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class ToggleControl extends JFrame {
   
    MyPopup cp;
    JToggleButton tb;    
   
    public ToggleControl() {
        this.addWindowListener(
            new WindowAdapter() {
                public void windowClosing( WindowEvent e ) {
                    System.exit(0);
                }
            }
        );
        this.setSize( 500, 500 );
        this.setVisible(true);
        this.setLayout( new FlowLayout() );
        cp = new MyPopup();
       
        cp.addPopupMenuListener(
                new PopupMenuListener( ) {
            public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
            }
            public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
                                      tb.setSelected(false);
            }
            public void popupMenuCanceled(PopupMenuEvent arg0) {
            }
                }
        );        
       
        tb = new JToggleButton("Start");
        this.getContentPane().add(tb);
        this.validate();
       
        tb.addActionListener(
                new ActionListener() {
                     public void actionPerformed( ActionEvent e ) {
                          JToggleButton b = ((JToggleButton)e.getSource());
                          boolean selected = b.isSelected();
                          if ( selected ) {
                                cp.show( tb, tb.getWidth(), tb.getHeight() );
                          }
                     }
                }
           );
    }
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ToggleControl tc = new ToggleControl();
    }
   
    class MyPopup extends JPopupMenu {
       
        static final int SIDEBARWIDTH = 20;
       
        public MyPopup() {
            JMenu m = new JMenu("SubMenu");
            JMenuItem mi = new JMenuItem("SubItem 1");
            m.add(mi);
            mi = new JMenuItem("SubItem 2");
            m.add(mi);
            this.add( m );
            mi = new JMenuItem("Item 1");
            this.add( mi );
            mi = new JMenuItem("Item 2");
            this.add( mi );
        }
       
        public void show( Component c, int x, int y ) {
            super.show( c, x, y );
        }
    }

}
0
rubentrancosoAuthor Commented:
the main problem is when the popup is allready open and I try to unselect the toggle clicking on it.
But the popup event change de button after hide and what happens is that the buttons goes pressed again and the popup appears.
0
objectsCommented:
yes I realise that. It is occurring because when the ActionEvent gets prcoessed the toggle button is unselected.
Did u try the code I posted?
0
rubentrancosoAuthor Commented:
yes, the same behavior
0
gnoonCommented:
Use tb.doClick(); in popupMenuWillBecomeInvisible() instead. It should works.
0
gnoonCommented:
As JavaDoc (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/AbstractButton.html#setSelected(boolean)),

 " public void setSelected(boolean b)
      Sets the state of the button. Note that this method does not trigger an actionEvent. Call doClick to perform
      a programatic action change. "

Because of  JToogleButton.setSelected() method does not trigger an actionEvent, the JToggleButton state isn't changed but only its color. So, the b.isSelected() in actionPerformed always returns true while clicking on the button.
0
objectsCommented:
>  the JToggleButton state isn't changed but only its color.

no, the button state is changed.
0
gnoonCommented:
Sorry, my foolish ;-)
0
rubentrancosoAuthor Commented:
I thinking that I must add a glasspane to control de button behavior. Not sure.
0
objectsCommented:
how would a glass pane help exactly?
0
gnoonCommented:
rubentrancoso, how about tb.doClick()? did you try?
0
rubentrancosoAuthor Commented:
I can intercept the click on it ( glasspane ) and make the action myself. ( i think )
The big trouble is that ever the togglebutton raises a action the button state is allready set to the new value ( selected oe deselected ). When I click over the button what first happen is the popupevent deselecting the button, and after that, the action event is processed normaly and independently.
With the doclick it just deselect the button before the click happens over the button. When the click occours out of the button it is tha same as seting the button deselected.
I´m not seeing how to mix this two paths.
0
objectsCommented:
> I can intercept the click on it ( glasspane ) and make the action myself. ( i think )

then why use a button at all?

> When I click over the button what first happen is the popupevent deselecting the button, and after that, the action event is processed normaly and independently.

yes, I mentioned that earlier

> I´m not seeing how to mix this two paths.

Not sure you easily can.
0
rubentrancosoAuthor Commented:
maybe, but I tried to get the mouse position eg but when the popup gos hide there´s no way to now the mouse position.
The button must act like a windows start menu, it´s why I need it.
0
objectsCommented:
> The button must act like a windows start menu, it´s why I need it.

i meant if you are using a glass pane to capture the mouse clicks then the button seems to no longer being used.

0
rubentrancosoAuthor Commented:
ok objects, you chanleged me :)

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class ToggleControl extends JFrame {
   
    MyPopup cp;
    JToggleButton tb;  
    boolean inButton = false;
   
    public ToggleControl() {
        this.addWindowListener(
            new WindowAdapter() {
                public void windowClosing( WindowEvent e ) {
                    System.exit(0);
                }
            }
        );
        this.setSize( 200, 200 );
        this.setVisible(true);
        this.setLayout( new FlowLayout() );
        cp = new MyPopup();
       
        cp.addPopupMenuListener(
                new PopupMenuListener( ) {
                              public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                                    tb.setSelected(true);
                              }
                              public void popupMenuWillBecomeInvisible(PopupMenuEvent e ) {
                                    long time = System.currentTimeMillis() + 3000;
                                    System.out.println("popup hided " + inButton );
                                    if ( !inButton )
                                          tb.setSelected(false);
                              }
                              public void popupMenuCanceled(PopupMenuEvent arg0) {
                              }
                }
        );        
       
        tb = new JToggleButton("Start");
        this.getContentPane().add(tb);
        this.validate();
       
        tb.addMouseListener(
                    new MouseListener() {
                              public void mouseClicked(MouseEvent e) {
                                    System.out.println("mouseClicked");
                              }
                              public void mousePressed(MouseEvent e) {
                                    System.out.println("mousePressed");
                                    if( !tb.isSelected() ) {
                                          EventQueue.invokeLater(
                                                new Runnable() {  
                                                      public void run() {  
                                                    cp.show( tb, tb.getWidth(), tb.getHeight() );
                                                      }
                                                }
                                          );
                                    }
                              }
                              public void mouseReleased(MouseEvent e) {
                                    System.out.println("mouseReleased");
                              }
                              public void mouseEntered(MouseEvent e) {
                                    System.out.println("mouseEntered");
                                    inButton = true;
                              }
                              public void mouseExited(MouseEvent e) {
                                    System.out.println("mouseExited");
                                    inButton = false;
                              }
                    }
               );
    }
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ToggleControl tc = new ToggleControl();
    }
   
    class MyPopup extends JPopupMenu {
       
        static final int SIDEBARWIDTH = 20;
       
        public MyPopup() {
            JMenu m = new JMenu("SubMenu");
            JMenuItem mi = new JMenuItem("SubItem 1");
            m.add(mi);
            mi = new JMenuItem("SubItem 2");
            m.add(mi);
            this.add( m );
            mi = new JMenuItem("Item 1");
            this.add( mi );
            mi = new JMenuItem("Item 2");
            this.add( mi );
        }
       
        public void show( Component c, int x, int y ) {
            super.show( c, x, y );
        }
    }

}
0
rubentrancosoAuthor Commented:
thanx all anyway
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.