com.jidesoft.swing.VisibilityFocusTraversalPolicy Maven / Gradle / Ivy
/*
* @(#)VisibilityFocusTraversalPolicy.java 2/28/2012
*
* Copyright 2002 - 2012 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import com.jidesoft.utils.ReflectionUtils;
import javax.swing.*;
import java.util.HashSet;
import java.awt.*;
import java.util.Set;
/**
* The focus traversal policy to screen out those components that are not actually painted in the target container.
*
* @since 3.3.6
*/
public class VisibilityFocusTraversalPolicy extends FocusTraversalPolicy {
private FocusTraversalPolicy _defaultPolicy;
private Set _containers;
/**
* The constructor.
*
* @param defaultPolicy the default FocusTraversalPolicy
* @since 3.4.0
*/
public VisibilityFocusTraversalPolicy(FocusTraversalPolicy defaultPolicy) {
this(defaultPolicy, null);
}
/**
* The constructor.
*
* @param defaultPolicy the default FocusTraversalPolicy
* @param container the container to check the visibility of its child components
*/
public VisibilityFocusTraversalPolicy(FocusTraversalPolicy defaultPolicy, Container container) {
super();
if (defaultPolicy != null && ReflectionUtils.isSubClassOf(defaultPolicy, "LegacyGlueFocusTraversalPolicy")) {
throw new IllegalArgumentException("VisibilityFocusTraversalPolicy can't work well with LegacyGlueFocusTraversalPolicy.");
}
_defaultPolicy = defaultPolicy;
if (container != null) {
_containers = new HashSet();
_containers.add(container);
}
}
/**
* Adds the container that needs to check the visibility of its child component.
*
* @param container the container
* @since 3.4.0
*/
public void addContainer(Container container) {
if (_containers == null) {
_containers = new HashSet();
}
_containers.add(container);
}
/**
* Removes the container that needs to check the visibility of its child component.
*
* @param container the container
* @since 3.4.0
*/
public void removeContainer(Container container) {
if (_containers != null) {
_containers.remove(container);
}
}
/**
* Gets all the containers that need to check the visibility of its child component.
*
* @return the container array.
* @since 3.4.0
*/
public Container[] getContainers() {
if (_containers == null) {
return new Container[0];
}
else {
return _containers.toArray(new Container[_containers.size()]);
}
}
/**
* Gets the default FocusTraversalPolicy
*
* @return the default FocusTraversalPolicy.
*/
public FocusTraversalPolicy getDefaultPolicy() {
return _defaultPolicy;
}
@Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
if (_defaultPolicy == null) {
return null;
}
Component component = _defaultPolicy.getComponentAfter(aContainer, aComponent);
boolean componentChanged = true;
while (component != null && aComponent != component && componentChanged) {
componentChanged = false;
for (Container container : _containers) {
if (container.isAncestorOf(component)) {
Rectangle collapsiblePaneBounds = container.getBounds();
Container parent = container.getParent();
Rectangle bounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), parent);
if (bounds.x < collapsiblePaneBounds.x + collapsiblePaneBounds.width && bounds.x + bounds.width > collapsiblePaneBounds.x && bounds.y < collapsiblePaneBounds.y + collapsiblePaneBounds.height && bounds.y + bounds.height > collapsiblePaneBounds.y) {
return component;
}
component = _defaultPolicy.getComponentAfter(aContainer, component);
componentChanged = true;
break;
}
}
}
return component;
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
if (_defaultPolicy == null) {
return null;
}
Component component = _defaultPolicy.getComponentBefore(aContainer, aComponent);
boolean componentChanged = true;
while (component != null && aComponent != component && componentChanged) {
componentChanged = false;
for (Container container : _containers) {
if (container.isAncestorOf(component)) {
Rectangle collapsiblePaneBounds = container.getBounds();
Container parent = container.getParent();
Rectangle bounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), parent);
if (bounds.x < collapsiblePaneBounds.x + collapsiblePaneBounds.width && bounds.x + bounds.width > collapsiblePaneBounds.x && bounds.y < collapsiblePaneBounds.y + collapsiblePaneBounds.height && bounds.y + bounds.height > collapsiblePaneBounds.y) {
return component;
}
component = _defaultPolicy.getComponentBefore(aContainer, component);
componentChanged = true;
break;
}
}
}
return component;
}
@Override
public Component getFirstComponent(Container aContainer) {
if (_defaultPolicy == null) {
return null;
}
Component component = _defaultPolicy.getFirstComponent(aContainer);
Component aComponent = component;
boolean componentChanged;
do {
componentChanged = false;
for (Container container : _containers) {
if (container.isAncestorOf(component)) {
Rectangle collapsiblePaneBounds = container.getBounds();
Container parent = container.getParent();
Rectangle bounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), parent);
if (bounds.x < collapsiblePaneBounds.x + collapsiblePaneBounds.width && bounds.x + bounds.width > collapsiblePaneBounds.x && bounds.y < collapsiblePaneBounds.y + collapsiblePaneBounds.height && bounds.y + bounds.height > collapsiblePaneBounds.y) {
return component;
}
component = _defaultPolicy.getComponentAfter(aContainer, component);
componentChanged = true;
break;
}
}
}
while (component != null && aComponent != component && componentChanged);
return component;
}
@Override
public Component getLastComponent(Container aContainer) {
if (_defaultPolicy == null) {
return null;
}
Component component = _defaultPolicy.getLastComponent(aContainer);
Component aComponent = component;
boolean componentChanged;
do {
componentChanged = false;
for (Container container : _containers) {
if (container.isAncestorOf(component)) {
Rectangle collapsiblePaneBounds = container.getBounds();
Container parent = container.getParent();
Rectangle bounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), parent);
if (bounds.x < collapsiblePaneBounds.x + collapsiblePaneBounds.width && bounds.x + bounds.width > collapsiblePaneBounds.x && bounds.y < collapsiblePaneBounds.y + collapsiblePaneBounds.height && bounds.y + bounds.height > collapsiblePaneBounds.y) {
return component;
}
component = _defaultPolicy.getComponentBefore(aContainer, component);
componentChanged = true;
break;
}
}
}
while (component != null && aComponent != component && componentChanged);
return component;
}
@Override
public Component getDefaultComponent(Container aContainer) {
if (_defaultPolicy == null) {
return null;
}
Component component = _defaultPolicy.getDefaultComponent(aContainer);
Component aComponent = component;
boolean old = _defaultPolicy instanceof SortingFocusTraversalPolicy && ((SortingFocusTraversalPolicy) _defaultPolicy).getImplicitDownCycleTraversal();
if (_defaultPolicy instanceof SortingFocusTraversalPolicy) {
((SortingFocusTraversalPolicy) _defaultPolicy).setImplicitDownCycleTraversal(false);
}
try {
boolean componentChanged;
do {
componentChanged = false;
for (Container container : _containers) {
if (container.isAncestorOf(component)) {
Rectangle collapsiblePaneBounds = container.getBounds();
Container parent = container.getParent();
Rectangle bounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), parent);
if (bounds.x < collapsiblePaneBounds.x + collapsiblePaneBounds.width && bounds.x + bounds.width > collapsiblePaneBounds.x && bounds.y < collapsiblePaneBounds.y + collapsiblePaneBounds.height && bounds.y + bounds.height > collapsiblePaneBounds.y) {
return component;
}
component = _defaultPolicy.getComponentAfter(aContainer, component);
componentChanged = true;
break;
}
}
}
while (component != null && aComponent != component && componentChanged);
return component;
}
finally {
if (_defaultPolicy instanceof SortingFocusTraversalPolicy) {
((SortingFocusTraversalPolicy) _defaultPolicy).setImplicitDownCycleTraversal(old);
}
}
}
@Override
public Component getInitialComponent(Window window) {
if (_defaultPolicy == null) {
return null;
}
return _defaultPolicy.getInitialComponent(window);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy