自定义FocusTraversalPolicy类Java Swing
我正在为应用程序中的多个面板设置新的Tab键顺序。 我想创建一个新的类,这将允许我像处理过的setNextFocusableComponent方法一样处理大量的排序。 我创建了一个扩展DefaultTreversalPolicyClass并且重载getComponentBefore和getComponentAfter方法的类。 在面板本身上,我希望实现与创建新的自定义类(我将其称为CustomizedTabOrderPolicy)一样简单,然后添加要为其指定Tab键顺序的组件。 我通过CustomizedTabOrderPolicy类中的便捷方法来完成此操作,该类允许我将要为其指定Tab键顺序“链接”的组件添加到散列表中,然后创建一个hastable的副本,其中键和值将被切换。 然后我使用这些哈希表来建立这两个组件之间的向前和向后制表符“链接”。
以下是我的习惯课:
import java.awt.Component;
import java.awt.Container;
import java.awt.DefaultFocusTraversalPolicy;
import java.util.Hashtable;
public class CustomizedTabOrderPolicy extends DefaultFocusTraversalPolicy {
private Hashtable<Component, Component> exceptionsMap = new Hashtable<Component, Component>();
private Hashtable<Component, Component> excpetionsMapReflection = new Hashtable<Component, Component>();
private Component defaultComponent;
private Component firstComponent;
private Component lastComponent;
public CustomizedTabOrderPolicy() {
}
@Override
public Component getComponentAfter(Container container, Component component) {
java.awt.Toolkit.getDefaultToolkit().beep();
if (exceptionsMap.containsKey(component)) {
return exceptionsMap.get(component);
} else {
return super.getComponentAfter(container, component);
}
}
@Override
public Component getComponentBefore(Container container, Component component) {
if (exceptionsMap.containsValue(component)) {
return excpetionsMapReflection.get(component);
} else {
return super.getComponentBefore(container, component);
}
}
@Override
public Component getDefaultComponent(Container container) {
if (this.defaultComponent != null) {
return this.defaultComponent;
}
return super.getDefaultComponent(container);
}
@Override
public Component getFirstComponent(Container container) {
if (this.firstComponent != null) {
return this.firstComponent;
}
return super.getFirstComponent(container);
}
@Override
public Component getLastComponent(Container container) {
if (this.lastComponent != null) {
return this.lastComponent;
}
return super.getLastComponent(container);
}
public void addNewException(Component origin, Component destination) {
exceptionsMap.put(origin, destination);
excpetionsMapReflection.put(destination, origin);
}
public void setDefaultComponent(Component defaultComponent) {
this.defaultComponent = defaultComponent;
}
public void setLastComponent(Component lastComponent) {
this.lastComponent = lastComponent;
}
public void setFirstComponent(Component firstComponent) {
this.firstComponent = firstComponent;
}
}
为了实现这一点,我在我的JPanel上使用了以下内容:
CustomizedTabOrderPolicy customPolicy = new CustomizedTabOrderPolicy();
customPolicy.addNewException(<component1>, <component2>);
customPolicy.addNewException(<component3>, <component4>);
customPolicy.addNewException(<component5>, <component6>);
this.setFocusTraversalPolicy(customPolicy);
我没有收到任何编译器或运行时错误,但似乎我的CustomTabOrderPolicy根本没有被JPanel使用。 当我将断点插入getComponentBefore和getComponentAfter方法时,它们从不被触发。 我对Focus Traversal Policies的工作非常陌生,所以我想知道我在这里错过了什么......
好的,我应该做的是继承FocusTraversalPolicy而不是DefaultFocusTraversalPolicy,并在原始策略的副本中传递,以在没有“例外”时恢复。 我还需要在面板上将FocusCycleRoot设置为true,以便它使用我的FocusTraversalPolicy。 我现在已经设置好了,以便在我的AbstractJPanel基类中有一个CustomizedTabOrderPolicy实例,以便我需要在面板初始化中调用所有这些内容:
this.setTabOrderEnabled(true);
this.getCustomTabOrder().addNewException(component1, component2);
this.getCustomTabOrder().addNewException(component2, component3);
this.getCustomTabOrder().addNewException(component3, component4);
我也有点改变了课程,以使它更有效。
public class CustomizedTabOrderPolicy extends FocusTraversalPolicy {
private FocusTraversalPolicy oldPolicy;
private Hashtable<Component, Component> exceptionsMap = new Hashtable<Component, Component>();
private Hashtable<Component, Component> exceptionsMapReflection = new Hashtable<Component, Component>();
private Component defaultComponent;
private Component firstComponent;
private Component lastComponent;
public CustomizedTabOrderPolicy(FocusTraversalPolicy oldPolicy) {
this.oldPolicy = oldPolicy;
}
public Component getComponentAfter(Container container, Component component) {
if (component == this.getLastComponent(container)) {
if (isValid(this.getFirstComponent(container))) {
return this.getFirstComponent(container);
} else {
return this.getComponentAfter(container, this.getFirstComponent(container));
}
}
if (exceptionsMap.containsKey(component) && isValid(exceptionsMap.get(component))) {
return exceptionsMap.get(component);
} else {
return oldPolicy.getComponentAfter(container, component);
}
}
public Component getComponentBefore(Container container, Component component) {
if (component == this.getFirstComponent(container)) {
if (isValid(this.getLastComponent(container))) {
return this.getLastComponent(container);
} else {
return this.getComponentBefore(container, this.getLastComponent(container));
}
}
if (exceptionsMapReflection.containsKey(component) && isValid(exceptionsMapReflection.get(component))) {
return exceptionsMapReflection.get(component);
} else {
return oldPolicy.getComponentBefore(container, component);
}
}
public boolean isValid(Component component) {
if (component.isEnabled() && component.isVisible() && component.isFocusable()) {
return true;
} else {
return false;
}
}
public Component getDefaultComponent(Container container) {
if (this.defaultComponent != null) {
return this.defaultComponent;
}
return oldPolicy.getDefaultComponent(container);
}
public Component getFirstComponent(Container container) {
if (this.firstComponent != null) {
return this.firstComponent;
}
return oldPolicy.getFirstComponent(container);
}
public Component getLastComponent(Container container) {
if (this.lastComponent != null) {
return this.lastComponent;
} else {
return oldPolicy.getLastComponent(container);
}
}
public void addNewException(Component origin, Component destination) {
exceptionsMap.put(origin, destination);
exceptionsMapReflection.put(destination, origin);
}
public void setDefaultComponent(Component defaultComponent) {
this.defaultComponent = defaultComponent;
}
public void setLastComponent(Component lastComponent) {
this.lastComponent = lastComponent;
}
public void setFirstComponent(Component firstComponent) {
this.firstComponent = firstComponent;
}
}
高效! 我使用这个稍作修改,让它在不是isValid()时继续遍历(当然它应该在面板中至少有一个isValid()组件):
public Component getComponentAfter(Container container, Component component) {
if (component == this.getLastComponent(container)) {
if (isValid(this.getFirstComponent(container))) return this.getFirstComponent(container);
else return this.getComponentAfter(container, this.getFirstComponent(container));
}
if( exceptionsMap.containsKey(component) ) {
component = exceptionsMap.get(component);
if( isValid(component) ) return component;
return this.getComponentAfter(container, component);
}
return oldPolicy.getComponentAfter(container, component);
}
public Component getComponentBefore(Container container, Component component) {
if (component == this.getFirstComponent(container)) {
if (isValid(this.getLastComponent(container))) return this.getLastComponent(container);
else return this.getComponentBefore(container, this.getLastComponent(container));
}
if( exceptionsMapReflection.containsKey(component) ) {
component = exceptionsMapReflection.get(component);
if( isValid(component) ) return component;
return this.getComponentBefore(container, component);
}
return oldPolicy.getComponentBefore(container, component);
}
链接地址: http://www.djcxy.com/p/23987.html