简体   繁体   English

在多个JPanel之间摇摆FocusTraversalPolicy

[英]Swing FocusTraversalPolicy across multiple JPanels

I have two JPanel objects which contain multiple components. 我有两个包含多个组件的JPanel对象。 Each panel has its own FocusTraversalPolicy . 每个面板都有自己的FocusTraversalPolicy

I want to start the focus cycle at the first component of the first panel. 我想在第一个面板的第一个组件上开始聚焦周期。 When the focus reached the last component of the first panel the focus should jump to the first component of the second panel when I press Tab . 当焦点到达第一个面板的最后一个组件时,按Tab时焦点应跳到第二个面板的第一个组件。

On both panels the FocusTraversalPolicyProvider is enabled. 在两个面板上都启用了FocusTraversalPolicyProvider

How does this work? 这是如何运作的?

public class Panel1 extends JPanel{

    private JTextField text1;
    private JTextField text2;

    public JPanel1(){
        init();
    }

    private void init(){
        text1 = new JTextField();
        text2 = new JTextField();

        this.setLayout(new FlowLayout());
        this.add(text1);
        this.add(text2);

        this.setFocusTraversalPolicyProvider(true);
        this.setFocusTraversalPolicy(new SimpleFocusTraversalPolicy(
            text1,
            text2
        ));
    }
}

public class Panel2 extends JPanel{

    private JTextField text1;
    private JTextField text2;

    public JPanel2(){
        init();
    }

    private void init(){
        text1 = new JTextField();
        text2 = new JTextField();

        this.setLayout(new FlowLayout());
        this.add(text1);
        this.add(text2);

        this.setFocusTraversalPolicyProvider(true);
        this.setFocusTraversalPolicy(new SimpleFocusTraversalPolicy(
            text1,
            text2
        ));
    }
}

public class ContainerPanel extends JPanel{

    private JPanel panel1, panel2;

    public ContainerPanel(){
        init();
    }

    private void init(){
        panel1 = new Panel1();
        panel2 = new Panel2();

        this.setLayout(new FlowLayout());
        this.add(panel1);
        this.add(panel2);

        /*
            what should I do here to jump from panel1 to panel2 after the last component of panel1?
        */
    }
}

You might be able to override a FocusTraversalPolicy#getComponentAfter(...) method: 您可能可以覆盖FocusTraversalPolicy#getComponentAfter(...)方法:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;

public class SimpleFocusTraversalPolicyTest {
  private JComponent makeUI() {
    JTextField t1 = new JTextField("3", 12);
    JTextField t2 = new JTextField("1", 12);
    JTextField t3 = new JTextField("4", 12);
    JTextField t4 = new JTextField("2", 12);
    JPanel p1 = new JPanel();
    p1.setBorder(BorderFactory.createTitledBorder("left"));
    p1.setFocusTraversalPolicy(new SimpleFocusTraversalPolicy(t2, t4, t1, t3));
    p1.add(t1); p1.add(t2); p1.add(t3); p1.add(t4);
    p1.setFocusTraversalPolicyProvider(true);
    p1.setFocusCycleRoot(false);

    JTextField t5 = new JTextField("4", 12);
    JTextField t6 = new JTextField("3", 12);
    JTextField t7 = new JTextField("2", 12);
    JTextField t8 = new JTextField("1", 12);
    JPanel p2 = new JPanel();
    p2.setBorder(BorderFactory.createTitledBorder("right"));
    p2.setFocusTraversalPolicy(new SimpleFocusTraversalPolicy(t8, t7, t6, t5));
    p2.add(t5); p2.add(t6); p2.add(t7); p2.add(t8);
    p2.setFocusTraversalPolicyProvider(true);
    p2.setFocusCycleRoot(false);

    JPanel p = new JPanel(new GridLayout(1, 2));
    p.add(p1);
    p.add(p2);
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new SimpleFocusTraversalPolicyTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

//There is no SimpleFocusTraversalPolicy in your code, so this is just an example:
class SimpleFocusTraversalPolicy extends FocusTraversalPolicy {
  private final List<? extends Component> order;
  public SimpleFocusTraversalPolicy(Component... arrays) {
    super();
    this.order = Arrays.asList(arrays);
  }
  @Override public Component getFirstComponent(Container focusCycleRoot) {
    return order.get(0);
  }
  @Override public Component getLastComponent(Container focusCycleRoot) {
    return order.get(order.size() - 1);
  }
  @Override public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
    int idx = order.indexOf(aComponent) + 1;
    if (idx >= order.size() && !focusCycleRoot.isFocusCycleRoot()) {
      return null;
    } else {
      return order.get(idx % order.size());
    }
  }
  @Override public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
    int idx = order.indexOf(aComponent) - 1;
    if (idx < 0 && !focusCycleRoot.isFocusCycleRoot()) {
      return null;
    } else {
      return order.get((idx + order.size()) % order.size());
    }
  }
  @Override public Component getDefaultComponent(Container focusCycleRoot) {
    return order.get(0);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM