Solved

JToggle disabled after popup hide

Posted on 2004-10-25
318 Views
Last Modified: 2007-12-19
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?



0
Question by:rubentrancoso
    21 Comments
     
    LVL 16

    Expert Comment

    by:gnoon
    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
     
    LVL 92

    Expert Comment

    by:objects
    can u post your code (in particular your action listener)
    0
     

    Author Comment

    by:rubentrancoso
    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
     
    LVL 92

    Accepted Solution

    by:
    try using the following to unselect the button.

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

    Author Comment

    by:rubentrancoso
    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
     

    Author Comment

    by:rubentrancoso
    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
     
    LVL 92

    Expert Comment

    by:objects
    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
     

    Author Comment

    by:rubentrancoso
    yes, the same behavior
    0
     
    LVL 16

    Expert Comment

    by:gnoon
    Use tb.doClick(); in popupMenuWillBecomeInvisible() instead. It should works.
    0
     
    LVL 16

    Expert Comment

    by:gnoon
    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
     
    LVL 92

    Expert Comment

    by:objects
    >  the JToggleButton state isn't changed but only its color.

    no, the button state is changed.
    0
     
    LVL 16

    Expert Comment

    by:gnoon
    Sorry, my foolish ;-)
    0
     

    Author Comment

    by:rubentrancoso
    I thinking that I must add a glasspane to control de button behavior. Not sure.
    0
     
    LVL 92

    Expert Comment

    by:objects
    how would a glass pane help exactly?
    0
     
    LVL 16

    Expert Comment

    by:gnoon
    rubentrancoso, how about tb.doClick()? did you try?
    0
     

    Author Comment

    by:rubentrancoso
    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
     
    LVL 92

    Expert Comment

    by:objects
    > 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
     

    Author Comment

    by:rubentrancoso
    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
     
    LVL 92

    Expert Comment

    by:objects
    > 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
     

    Author Comment

    by:rubentrancoso
    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
     

    Author Comment

    by:rubentrancoso
    thanx all anyway
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    What Security Threats Are You Missing?

    Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

    Suggested Solutions

    For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
    Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
    Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
    This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now