Package net.xoetrope.swing.focus

Source Code of net.xoetrope.swing.focus.XPanelFocusExtension$ActionHandler

package net.xoetrope.swing.focus;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.DefaultButtonModel;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.SwingUtilities;
import net.xoetrope.swing.XPanel;
import net.xoetrope.xui.helper.ReflectionHelper;

/**
* The class is an extract of the SwingLabs JXButtonPanel. It handles the
* change of focus using the arrow keys.
* <p>Copyright (c) Xoetrope Ltd., 1998-2004<br>
* License:      see license.txt
* @version 1.0
*/
public class XPanelFocusExtension
{
  private boolean isCyclic;
  private boolean isGroupSelectionFollowFocus;
  private XPanel xp;
 
  /** Creates a new instance of XPanelFocusExtension */
  public XPanelFocusExtension( XPanel xp )
  {
    this.xp = xp;
   
    Object[] values = new Object[ 1 ];
    values[ 0 ] = Boolean.TRUE;
    ReflectionHelper.setViaReflection( "setFocusTraversalPolicyProvider", xp, values );
    //xp.setFocusTraversalPolicyProvider( true );
   
    xp.setFocusTraversalPolicy( new JXButtonPanelFocusTraversalPolicy());
   
    ActionListener actionHandler = new ActionHandler();
    xp.registerKeyboardAction( actionHandler, ActionHandler.FORWARD,
            KeyStroke.getKeyStroke( KeyEvent.VK_RIGHT, 0 ),
            JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
    xp.registerKeyboardAction( actionHandler, ActionHandler.FORWARD,
            KeyStroke.getKeyStroke( KeyEvent.VK_DOWN, 0 ),
            JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
    xp.registerKeyboardAction( actionHandler, ActionHandler.BACKWARD,
            KeyStroke.getKeyStroke( KeyEvent.VK_LEFT, 0 ),
            JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
    xp.registerKeyboardAction( actionHandler, ActionHandler.BACKWARD,
            KeyStroke.getKeyStroke( KeyEvent.VK_UP, 0 ),
            JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
   
    setGroupSelectionFollowFocus( true );
  }
 
  /**
  * Returns whether arrow keys should support
  * cyclic focus traversal ordering for for this JXButtonPanel.  
  */
  public boolean isCyclic()
  {
    return isCyclic;
  }

  /**
  * Sets whether arrow keys should support
  * cyclic focus traversal ordering for this JXButtonPanel.
  */
  public void setCyclic(boolean isCyclic)
  {
    this.isCyclic = isCyclic;
  }

  /**
  * Returns whether arrow keys should transfer button's
  * selection as well as focus for this JXButtonPanel.<p>
  *
  * Note: this property affects buttons which are added to a ButtonGroup
  */
  public boolean isGroupSelectionFollowFocus()
  {
    return isGroupSelectionFollowFocus;
  }

  /**
  * Sets whether arrow keys should transfer button's
  * selection as well as focus for this JXButtonPanel.<p>
  *
  * Note: this property affects buttons which are added to a ButtonGroup
  */
  public void setGroupSelectionFollowFocus( boolean groupSelectionFollowFocus )
  {
    isGroupSelectionFollowFocus = groupSelectionFollowFocus;
  }

  private static ButtonGroup getButtonGroup( AbstractButton button )
  {
    ButtonModel model = button.getModel();
    if (model instanceof DefaultButtonModel) {
      return ((DefaultButtonModel) model).getGroup();
    }
    return null;
  }

  private class ActionHandler implements ActionListener
  {
    private static final String FORWARD = "moveSelectionForward";
    private static final String BACKWARD = "moveSelectionBackward";

    public void actionPerformed( ActionEvent e )
    {
      FocusTraversalPolicy ftp = xp.getFocusTraversalPolicy();

      if (ftp instanceof JXButtonPanelFocusTraversalPolicy) {
        JXButtonPanelFocusTraversalPolicy xftp = (JXButtonPanelFocusTraversalPolicy)ftp;

        String actionCommand = e.getActionCommand();
        Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        Component next;

        xftp.setAlternativeFocusMode( true );

        if ( FORWARD.equals( actionCommand )) {
          next = xftp.getComponentAfter( xp, fo );
        }
        else if (
            BACKWARD.equals( actionCommand )) {
            next = xftp.getComponentBefore( xp, fo );
        }
        else {
          throw new AssertionError( "Unexpected action command: " + actionCommand );
        }

        xftp.setAlternativeFocusMode(false);

        if ( fo instanceof AbstractButton ) {
          AbstractButton b = (AbstractButton)fo;
          b.getModel().setPressed( false );
        }

        if ( next != null ) {
          if ( fo instanceof AbstractButton && next instanceof AbstractButton ) {
            ButtonGroup group = getButtonGroup( (AbstractButton)fo );
            AbstractButton nextButton = (AbstractButton)next;
            if ( group != getButtonGroup( nextButton )) {
              return;
            }

            if ( isGroupSelectionFollowFocus() && group != null &&
                    group.getSelection() != null && !nextButton.isSelected()) {
                nextButton.setSelected( true );
            }
            next.requestFocusInWindow();
          }
        }
      }
    }
  }

  private class JXButtonPanelFocusTraversalPolicy extends LayoutFocusTraversalPolicy
  {
    private boolean isAlternativeFocusMode;

    public boolean isAlternativeFocusMode()
    {
      return isAlternativeFocusMode;
    }

    public void setAlternativeFocusMode( boolean alternativeFocusMode )
    {
      isAlternativeFocusMode = alternativeFocusMode;
    }

    protected boolean accept(Component c)  
    {
      if (!isAlternativeFocusMode() && c instanceof AbstractButton) {
        AbstractButton button = (AbstractButton) c;
        ButtonGroup group = XPanelFocusExtension.this.getButtonGroup( button );
        if (group != null && group.getSelection() != null && !button.isSelected()) {
          return false;
        }
      }
      return super.accept(c);
    }

    public Component getComponentAfter(Container aContainer, Component aComponent)
    {
      Component componentAfter = super.getComponentAfter(aContainer, aComponent);
      if (!isAlternativeFocusMode()) {
        return componentAfter;
      }
 
      if ( XPanelFocusExtension.this.isCyclic()) {
        return componentAfter == null ? getFirstComponent(aContainer) : componentAfter;
      }

      if (aComponent == getLastComponent(aContainer)) {
        return aComponent;
      }

      return componentAfter;
    }

    public Component getComponentBefore(Container aContainer, Component aComponent)
    {
      Component componentBefore = super.getComponentBefore(aContainer, aComponent);
      if (!isAlternativeFocusMode()) {
        return componentBefore;
      }
     
      if ( XPanelFocusExtension.this.isCyclic()) {
        return componentBefore == null ? getLastComponent(aContainer) : componentBefore;
      }
     
      if (aComponent == getFirstComponent(aContainer)) {
        return aComponent;
      }
      return componentBefore;
    }
  }
}
TOP

Related Classes of net.xoetrope.swing.focus.XPanelFocusExtension$ActionHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.