Article View: borland.public.jbuilder.java.swing
Article #8898Re: JPopupMenu from JTree
From: Andreas Andersson
Date: Thu, 22 Jun 2000 00:00
Date: Thu, 22 Jun 2000 00:00
196 lines
5505 bytes
5505 bytes
Hi Ilia !
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:
import javax.swing.*;
import javax.swing.table.*;
import visi.mav.util.*;
import visi.mav.polaris.*;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
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
Ilia Gilderman <ilia@iphighway.com> wrote in message news:3951a9d5@dnews...
> Hi.
>
> I'm trying to register the keyboard actions to the PopupMenu that invoked
> from JTree
> I have no response in the JPopupMenu but the selection is moving behind
the
> JPopupMenu on the JTree itself.
> Any ideas?
>
> Ilia Gilderman
> ilia@iphighway.com
>
>
Technical Details
Message-ID:
<3951ba28@dnews>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<3951a9d5@dnews>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,468fedccf61a48fe X-Google-Attributes: gid111d45,public From: "Andreas Andersson" <andreas.andersson@medicinsklogik.se> Subject: Re: JPopupMenu from JTree Date: 2000/06/22 Message-ID: <3951ba28@dnews> X-Deja-AN: 637526718 References: <3951a9d5@dnews> X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 X-Trace: 22 Jun 2000 00:03:04 -0800, 127.0.0.1 Organization: MLAB X-MSMail-Priority: Normal Newsgroups: borland.public.jbuilder.java.swing