我们正试图向用户展示 JGlassPane
表示由于当前显示的进度条或其他内容而当前不接受事件。虽然这通常会自动工作,因为我们显示了一个模态对话框,我们还希望 JGlassPane
不需要一个 JDialog
,意思是只是 JGlassPane
和一个等待的光标。
到目前为止,我们通过使用 JGlassPane
它忽略了事件并描绘出半透明的颜色。最初我们叫 requestFocus
上 JGlassPane
. 问题是,当玻璃板消失时,我们失去了先前聚焦的组件。解决这个问题的方法是简单地记住先前关注的组件。但是,如果 Action
,触发了 JGlassPane
,通过菜单调用,焦点组件是windows JRootPane
. 通常,swing在关闭菜单后会正确地恢复焦点,但是,在这种情况下,我们破坏了这个功能。有没有一种方法可以在不破坏焦点行为的情况下实现我们想要的?
在这个演示中,您可以看到,在使用两个按钮中的一个后按esc键时,焦点会正确返回,但使用表上的上下文菜单时则不会。
public class FocusDemo
{
//Temporary static veriable for demo purposes.
private static final AtomicReference<Component> previouslyFocused = new AtomicReference<>();
private static class ConsumingGlassPane extends JPanel
{
public ConsumingGlassPane()
{
setOpaque( false );
setFocusable( true );
addMouseListener( new MouseListener()
{
@Override
public void mouseClicked( @NonNull final MouseEvent e )
{
e.consume();
}
@Override
public void mousePressed( @NonNull final MouseEvent e )
{
e.consume();
}
@Override
public void mouseReleased( @NonNull final MouseEvent e )
{
e.consume();
}
@Override
public void mouseEntered( @NonNull final MouseEvent e )
{
e.consume();
}
@Override
public void mouseExited( @NonNull final MouseEvent e )
{
e.consume();
}
} );
addKeyListener( new KeyListener()
{
@Override
public void keyTyped( final KeyEvent e )
{
e.consume();
}
@Override
public void keyReleased( final KeyEvent e )
{
e.consume();
}
@Override
public void keyPressed( final KeyEvent e )
{
if ( e.getKeyCode() == KeyEvent.VK_ESCAPE )
{
setVisible( false );
final Component component = previouslyFocused.get();
if ( component != null )
{
component.requestFocusInWindow();
}
}
e.consume();
}
} );
// This component keeps the focus until is made hidden
setInputVerifier( new InputVerifier()
{
@Override
public boolean verify( final JComponent input )
{
return !isVisible();
}
} );
}
@Override
protected void paintComponent( final Graphics g )
{
final Graphics2D g2 = (Graphics2D) g.create();
g2.setColor( new Color( 240, 230, 230, 128 ) );
g2.fillRect( 0, 0, getWidth(), getHeight() );
g2.dispose();
}
}
public static void main( final String[] args )
{
final JFrame frame = new JFrame();
frame.setGlassPane( new ConsumingGlassPane() );
final ActionListener showglasspane = __ ->
{
previouslyFocused.set( frame.getFocusOwner() );
frame.getRootPane().getGlassPane().setVisible( true );
frame.getRootPane().getGlassPane().requestFocus();
};
final JButton button1 = new JButton( "Show GlassPane" );
final JButton button2 = new JButton( "Show GlassPane" );
button1.addActionListener( showglasspane );
button2.addActionListener( showglasspane );
final Object[][] objects = { { 1, 2, 3 }, { 1, 2, 3 } };
final String[] col = { "Lel", "Lol", "Lul" };
final JTable table = new JTable( objects, col );
final JMenuItem menuItem = new JMenuItem( "Show GlassPane" );
menuItem.addActionListener( showglasspane );
final JPopupMenu popup = new JPopupMenu();
popup.add( menuItem );
table.setComponentPopupMenu( popup );
frame.setLayout( new GridBagLayout() );
frame.add( button1 );
frame.add( button2 );
frame.add( table );
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
暂无答案!
目前还没有任何答案,快来回答吧!