[英]Java Swing FocusTraversalPolicy Issue
I'm currently having an issue with implementing a FocusTraversalPolicy
. 我目前在实现
FocusTraversalPolicy
遇到问题。
I would like for the Tab
/ Shift+Tab
keyboard shortcuts to allow for navigating top-bottom/left-right. 我想使用
Tab
/ Shift+Tab
键盘快捷键来浏览上下/左右。 This will allow for simpler navigation when filling in a form. 填写表格时,这将使导航更简单。
The policy should only impact all elements in the mainPanel
of my JFrame
. 该策略应仅影响
JFrame
的mainPanel
的所有元素。
I have implemented the policy using the following class: 我已经使用以下课程实施了该政策:
public class DefaultViewFocusTraversalPolicy
extends FocusTraversalPolicy
{
ArrayList<Component> order;
public DefaultViewFocusTraversalPolicy(ArrayList<Component> order)
{
this.order = order;
}
@Override
public Component getComponentAfter(Container aContainer, Component aComponent)
{
int index = (order.indexOf(aComponent) + 1) % order.size();
Component after = order.get(index);
while (index < order.size() && !(after.isEnabled() && after.isVisible()))
{
index++;
after = order.get(index);
}
return after;
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent)
{
int index = order.indexOf(aComponent) - 1;
if (index < 0)
{
index = order.size() - 1;
}
Component before = order.get(index);
while (index >= 0 && !(before.isEnabled() && before.isVisible()))
{
index--;
before = order.get(index);
}
return before;
}
@Override
public Component getFirstComponent(Container aContainer)
{
int index = 0;
Component first = order.get(index);
while (index < order.size() && !(first.isEnabled() && first.isVisible()))
{
index++;
first = order.get(index);
}
return first;
}
@Override
public Component getLastComponent(Container aContainer)
{
int index = order.size() - 1;
Component last = order.get(index);
while (index >= 0 && !(last.isEnabled() && last.isVisible()))
{
index--;
last = order.get(index);
}
return last;
}
@Override
public Component getDefaultComponent(Container aContainer)
{
return getFirstComponent(aContainer);
}
}
I then instantiate the class with the following inside the constructor of my view (eg main JFrame
): 然后,在我的视图的构造函数(例如main
JFrame
)中使用以下实例化该类:
ArrayList<Component> order = new ArrayList<>();
order.add(this.ecmID);
order.add(this.modeID);
// ...
DefaultViewFocusTraversalPolicy policy =
new DefaultViewFocusTraversalPolicy(order);
this.mainPanel.setFocusTraversalPolicy(policy);
However, when I try to Tab through the elements, nothing has changed and the previous policy is still in place. 但是,当我尝试使用Tab键浏览元素时,没有任何变化,并且以前的策略仍然存在。 I've already tried going through the Java tutorial: link
我已经尝试过Java教程: 链接
Any help would be much appreciated. 任何帮助将非常感激。
I am not sure why you are even extending the FocusTraversalPolicy
for your case while default FocusTraversalPolicy
should do the job for you. 我不确定您为什么
FocusTraversalPolicy
为您的案例扩展FocusTraversalPolicy
,而默认FocusTraversalPolicy
应该为您完成这项工作。
However, you need to set this.mainPanel.setFocusCycleRoot(true)
: which sets whether this Container is the root of a focus traversal cycle. 但是,您需要设置
this.mainPanel.setFocusCycleRoot(true)
:它设置此Container是否为焦点遍历循环的根。 Once focus enters a traversal cycle, typically it cannot leave it via focus traversal unless one of the up- or down-cycle keys is pressed. 焦点进入遍历周期后,通常除非按下向上或向下周期键之一,否则无法通过焦点遍历离开焦点。 Normal traversal is limited to this Container, and all of this Container's descendants that are not descendants of inferior focus cycle roots.
正常遍历仅限于此Container,并且该Container的所有后代都不是下聚焦周期根的后代。
You can look into the ContainerOrderFocusTraversalPolicy
: 您可以查看
ContainerOrderFocusTraversalPolicy
:
Container.getComponents()
Container.getComponents()
返回 It has a nice function: boolean accept(Component aComponent)
: Determines whether a Component is an acceptable choice as the new focus owner. 它具有一个很好的功能:
boolean accept(Component aComponent)
:确定是否可以接受Component作为新的焦点所有者。 just override this function by extending this class, with your corresponding component list you don't want to be focused of the Container
. 只需通过扩展此类来覆盖此函数,并使用您不希望关注
Container
相应组件列表即可。 No need to override all of the function and implement them. 无需覆盖所有功能并实现它们。
ArrayList<Component> order = new ArrayList<>();
I think that you looking for 我想你在找
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.GridLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Testing {
private static final long serialVersionUID = 1L;
private Component[] focusList;
private int focusNumber = 0;
private JFrame frame;
public Testing() {
JTextField tf1 = new JTextField(5);
tf1.setName("tf1");
JTextField tf2 = new JTextField(5);
tf2.setName("tf2");
JTextField tf3 = new JTextField(5);
tf3.setName("tf3");
JButton b1 = new JButton("B1");
b1.setName("b1");
JButton b2 = new JButton("B2");
b2.setName("b2");
tf2.setEnabled(false);
focusList = new Component[]{tf1, b1, tf2, b2, tf3};
JPanel panel = new JPanel(new GridLayout(5, 1));
panel.add(tf1);
panel.add(b1);
panel.add(tf2);
panel.add(b2);
panel.add(tf3);
frame = new JFrame();
frame.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
frame.add(panel);
frame.pack();
frame.setLocation(150, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent ke) {
if (ke.getID() == KeyEvent.KEY_PRESSED) {
if (ke.getKeyCode() == KeyEvent.VK_TAB) {
Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
System.out.println(comp.getName());
if (comp.isEnabled() == false) {
if (ke.isShiftDown()) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
} else {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
}
}
}
}
return false;
}
});
}
private class MyFocusTraversalPolicy extends FocusTraversalPolicy {
@Override
public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
focusNumber = (focusNumber + 1) % focusList.length;
return focusList[focusNumber];
}
@Override
public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
focusNumber = (focusList.length + focusNumber - 1) % focusList.length;
return focusList[focusNumber];
}
@Override
public Component getDefaultComponent(Container focusCycleRoot) {
return focusList[0];
}
@Override
public Component getLastComponent(Container focusCycleRoot) {
return focusList[focusList.length - 1];
}
@Override
public Component getFirstComponent(Container focusCycleRoot) {
return focusList[0];
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Testing testing = new Testing();
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.