🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.jbuilder.java.swing
Article #8929

Re: JPopupMenue focus as a heavy elementn

#8929
From: Andreas Andersson
Date: Thu, 29 Jun 2000 00:00
181 lines
5271 bytes
Hi,
This is simply a bug in the implementation for JPopupMenu. Key events for
JPopupMenu goes to container instead. This is a very irritated issue, but
there is workarounds for this problem. I present one solution down here, I'm
aware of that this problably isn't the best way to handle this, but it will
work for most cases. If you would like to know more about this problem you
can search SUN:s bug database because this is a very often reported bug.

Workaround example:

public class JPopUpButton extends JButton implements ActionListener
 {
 private JPopupMenu myMenu;
 private MenuElement[] sub;

 public JPopUpButton()
  {
  this( "" );
  }

 public JPopUpButton( String label )
  {
  super( label, new ImageIcon("images/tdown.gif") );

  this.setHorizontalTextPosition( this.LEADING );

  myMenu = new JPopupMenu( label ) // hack to disable parent focus
   {
   FocusManager old;

   public void setVisible( boolean b )
    {
    if( b )
     {
     old = FocusManager.getCurrentManager();
     FocusManager.disableSwingFocusManager();
     }
    else
     {
     FocusManager.setCurrentManager( old );
     }
    super.setVisible(b);
    }
   };

  myMenu.setInvoker(this);

  KeyHandler kh = new KeyHandler();

  super.addActionListener( this );
  }

 public void actionPerformed( ActionEvent deed )
  {
  myMenu.show( this, 0,0 );
  }
 public void addItem( JMenuItem jmi )
  {
  myMenu.add( jmi );
  sub = myMenu.getSubElements();
  }

 public class KeyHandler extends AbstractAction
  {
  public static final String SPACE = "SPACE";
  public static final String TAB = "TAB";
  public static final String SHIFT_TAB = "SHIFT_TAB";
  public static final String UP = "UP";
  public static final String DOWN = "DOWN";
  public static final String ENTER = "RETURN";
  public static final String ESCAPE = "ESCAPE";

  public KeyHandler( /*JPopupMenu myMenu*/ )
   {
   super();
   myMenu.registerKeyboardAction( KeyHandler.this, UP,
    KeyStroke.getKeyStroke( KeyEvent.VK_UP, 0 ),
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, DOWN,
    KeyStroke.getKeyStroke( KeyEvent.VK_DOWN, 0 ),
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, SPACE,
    KeyStroke.getKeyStroke( ' ' ), // VK_SPACE does NOT work
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, TAB,
    KeyStroke.getKeyStroke( KeyEvent.VK_TAB, 0 ),
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, SHIFT_TAB,
    KeyStroke.getKeyStroke( KeyEvent.VK_TAB, Event.SHIFT_MASK ),
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, ENTER,
    KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ),
    WHEN_IN_FOCUSED_WINDOW );
   myMenu.registerKeyboardAction( KeyHandler.this, ESCAPE,
    KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ),
    WHEN_IN_FOCUSED_WINDOW );
   }

  public int getSelectedIndex()
   {
   for( int i = 0; i < sub.length; i++ )
    {
    JMenuItem jmi = (JMenuItem)sub[i];
    if( jmi.isArmed() )
     {
     return i;
     }
    }
   return -1;
   }

  public void setSelectedIndex( int idx )
   {
   for( int i = 0; i < sub.length; i++ )
    {
    JMenuItem jmi = (JMenuItem)sub[i];
    jmi.setArmed( i == idx );
    }
   }
  public JMenuItem getSelectedItem()
   {
   for( int i = 0; i < sub.length; i++ )
    {
    JMenuItem jmi = (JMenuItem)sub[i];
    if( jmi.isArmed() )
     {
     return jmi;
     }
    }
   return null;
   }

  public void actionPerformed( ActionEvent ae )
   {
   String cmd = ae.getActionCommand();
   if( cmd == UP || cmd == SHIFT_TAB )
    {
    int i = getSelectedIndex();
    if( i > 0 )
     setSelectedIndex( i-1 );
    }
   else if( cmd == DOWN || cmd == TAB )
    {
    int i = getSelectedIndex();
    if( i < (sub.length-1) )
     setSelectedIndex( i+1 );
    }
   else if( cmd == SPACE )
    {
    JMenuItem jmi = getSelectedItem();
    if( jmi instanceof JCheckBoxMenuItem )
     {
     JCheckBoxMenuItem jcb = (JCheckBoxMenuItem)jmi;
     jcb.setSelected( !jcb.isSelected() );
     }
    }
   else if( cmd == ENTER || cmd == ESCAPE )
    {
    myMenu.setVisible( false );
    }
   else
    {
    }
   }
  }
 }

Regards
Andreas Andersson
Udi Nakar <udini@iphighway.com> wrote in message news:395a1441@dnews...
> Hi
>
> When the JPopupMenu is not contained in the top-level window it is
displayed
> as an instance of JWindow. In this case the requestFocus() method doesn't
> get the focus to the popup. How can I get the focus to the popup.
>
> TIA
> Udi
>
>
Technical Details
Message-ID: <395b5265@dnews>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <395a1441@dnews>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 111d45,5f7c1b7a9f62decb
X-Google-Attributes: gid111d45,public
From: "Andreas Andersson" <andreas.andersson@medicinsklogik.se>
Subject: Re: JPopupMenue focus as a heavy elementn
Date: 2000/06/29
Message-ID: <395b5265@dnews>
X-Deja-AN: 640400813
References: <395a1441@dnews>
X-Priority: 3
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300
X-Trace: 29 Jun 2000 06:43:01 -0800, 127.0.0.1
Organization: MLAB
X-MSMail-Priority: Normal
Newsgroups: borland.public.jbuilder.java.swing