rubentrancoso
asked on
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?
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?
can u post your code (in particular your action listener)
ASKER
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.getSourc e());
boolean selected = b.isSelected();
if ( selected ) {
showPopupUp();
}
}
}
);
========================== ========== ========== ========== ==
popupMenu.addPopupMenuList ener(
new PopupMenuListener( ) {
public void popupMenuCanceled( PopupMenuEvent e ) {
}
public void popupMenuWillBecomeVisible ( PopupMenuEvent e ) {
}
public void popupMenuWillBecomeInvisib le( PopupMenuEvent e ) {
tb.setSelected(false);
}
}
);
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.getSourc
boolean selected = b.isSelected();
if ( selected ) {
showPopupUp();
}
}
}
);
==========================
popupMenu.addPopupMenuList
new PopupMenuListener( ) {
public void popupMenuCanceled( PopupMenuEvent e ) {
}
public void popupMenuWillBecomeVisible
}
public void popupMenuWillBecomeInvisib
tb.setSelected(false);
}
}
);
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
a better sample...
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListe ner;
import java.awt.event.WindowAdapt er;
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.PopupMen uEvent;
import javax.swing.event.PopupMen uListener;
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 (PopupMenu Event arg0) {
}
public void popupMenuWillBecomeInvisib le(PopupMe nuEvent arg0) {
tb.setSelected(false);
}
public void popupMenuCanceled(PopupMen uEvent arg0) {
}
}
);
tb = new JToggleButton("Start");
this.getContentPane().add( tb);
this.validate();
tb.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent e ) {
JToggleButton b = ((JToggleButton)e.getSourc e());
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 );
}
}
}
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent
import java.awt.event.ActionListe
import java.awt.event.WindowAdapt
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.PopupMen
import javax.swing.event.PopupMen
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
}
public void popupMenuWillBecomeInvisib
tb.setSelected(false);
}
public void popupMenuCanceled(PopupMen
}
}
);
tb = new JToggleButton("Start");
this.getContentPane().add(
this.validate();
tb.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent e ) {
JToggleButton b = ((JToggleButton)e.getSourc
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 );
}
}
}
ASKER
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.
But the popup event change de button after hide and what happens is that the buttons goes pressed again and the popup appears.
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?
Did u try the code I posted?
ASKER
yes, the same behavior
Use tb.doClick(); in popupMenuWillBecomeInvisib le() instead. It should works.
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.
" 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(
> the JToggleButton state isn't changed but only its color.
no, the button state is changed.
no, the button state is changed.
Sorry, my foolish ;-)
ASKER
I thinking that I must add a glasspane to control de button behavior. Not sure.
how would a glass pane help exactly?
rubentrancoso, how about tb.doClick()? did you try?
ASKER
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.
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.
> 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.
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.
ASKER
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.
The button must act like a windows start menu, it´s why I need it.
> 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.
i meant if you are using a glass pane to capture the mouse clicks then the button seems to no longer being used.
ASKER
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.MouseListen er;
import java.awt.event.WindowAdapt er;
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.PopupMen uEvent;
import javax.swing.event.PopupMen uListener;
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 (PopupMenu Event e) {
tb.setSelected(true);
}
public void popupMenuWillBecomeInvisib le(PopupMe nuEvent e ) {
long time = System.currentTimeMillis() + 3000;
System.out.println("popup hided " + inButton );
if ( !inButton )
tb.setSelected(false);
}
public void popupMenuCanceled(PopupMen uEvent arg0) {
}
}
);
tb = new JToggleButton("Start");
this.getContentPane().add( tb);
this.validate();
tb.addMouseListener(
new MouseListener() {
public void mouseClicked(MouseEvent e) {
System.out.println("mouseC licked");
}
public void mousePressed(MouseEvent e) {
System.out.println("mouseP ressed");
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("mouseR eleased");
}
public void mouseEntered(MouseEvent e) {
System.out.println("mouseE ntered");
inButton = true;
}
public void mouseExited(MouseEvent e) {
System.out.println("mouseE xited");
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 );
}
}
}
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListen
import java.awt.event.WindowAdapt
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.PopupMen
import javax.swing.event.PopupMen
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
tb.setSelected(true);
}
public void popupMenuWillBecomeInvisib
long time = System.currentTimeMillis()
System.out.println("popup hided " + inButton );
if ( !inButton )
tb.setSelected(false);
}
public void popupMenuCanceled(PopupMen
}
}
);
tb = new JToggleButton("Start");
this.getContentPane().add(
this.validate();
tb.addMouseListener(
new MouseListener() {
public void mouseClicked(MouseEvent e) {
System.out.println("mouseC
}
public void mousePressed(MouseEvent e) {
System.out.println("mouseP
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("mouseR
}
public void mouseEntered(MouseEvent e) {
System.out.println("mouseE
inButton = true;
}
public void mouseExited(MouseEvent e) {
System.out.println("mouseE
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 );
}
}
}
ASKER
thanx all anyway
- mouse click on the button
mouse click on the button --> button state change --> actionPerformed--> popup visible
- PopupMenuListener
popup hiding --> popupMenuWillBecomeInvisib
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.