2013-02-15 64 views
3

我已经创建了号码,我不知道如何可以通过按下回车键切换字段之间的焦点。切换JTextFields将输入文本字段的关键字

另外,我可以控制的目标领域?例如,我可以定义通过按Enterfield A的焦点将更改为field C

enter image description here

+0

你只需要实现一个动作监听'JTextField',等你以后按enter键操作完成后。 – Maroun 2013-02-15 20:02:29

+0

我知道'ActionListener'是关键,但我怎样才能控制焦点开关? – 2013-02-15 20:03:35

+0

jTextField.requestFocus() – 2013-02-15 20:09:45

回答

5

简单的例子:

假设你有两个JTextField S:textFieldtextField1

textField.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     textField1.requestFocusInWindow();  
    } 
}); 

textField1.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     textField.requestFocusInWindow(); 
    } 
}); 

现在,当你打Enter当聚焦在第一JTextField,其他人会有所侧重,反之亦然。

+1

应该被包装成invokeLater – mKorbel 2013-02-15 22:01:25

+0

@mKorbel我仍然不知道在哪种情况下我应该使用'invokeLater'。我应该在这种情况下使用它吗? – Maroun 2013-02-16 09:44:17

+2

聚焦,FocusSubsystem是异步的,则延迟的invokeLater这个事件EDT结束时,通知的invokeLater EDT和延迟事件队列EDT应 – mKorbel 2013-02-16 09:52:29

5

看看How to Use the Focus Subsystem

将介绍如何设置传输密钥的焦点子系统

简单的例子

public class TestFocusTransfersal { 

    public static void main(String[] args) { 
     new TestFocusTransfersal(); 
    } 

    public TestFocusTransfersal() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JTextField field1 = new JTextField("1", 10); 
     private JTextField field2 = new JTextField("2", 10); 
     private JTextField field3 = new JTextField("3", 10); 
     private JTextField field4 = new JTextField("4", 10); 
     private JTextField field5 = new JTextField("5", 10); 
     private JTextField field6 = new JTextField("6", 10); 
     private JTextField field7 = new JTextField("7", 10); 
     private JTextField field8 = new JTextField("8", 10); 
     private JTextField field9 = new JTextField("9", 10); 
     private final MyOwnFocusTraversalPolicy policy; 

     public TestPane() { 
      // Set up enter for focus transfer... 
      Set forwardKeys = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); 
      Set newForwardKeys = new HashSet(forwardKeys); 
      newForwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 
      setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 
          newForwardKeys); 

      setLayout(new GridBagLayout()); 

      add("Field #1: ", field1, 0, 0); 
      add("Field #2: ", field2, 2, 0); 
      add("Field #3: ", field3, 4, 0); 
      add("Field #4: ", field4, 6, 0); 
      add("Field #5: ", field5, 8, 0); 
      add("Field #6: ", field6, 2, 1); 
      add("Field #7: ", field7, 4, 1); 
      add("Field #8: ", field8, 6, 1); 
      add("Field #9: ", field9, 8, 1); 

      policy = new MyOwnFocusTraversalPolicy(
          field1, 
          field6, 
          field7, 
          field8, 
          field9, 
          field2, 
          field3, 
          field4, 
          field5 
          ); 

//   You can do this to make life easier, but it may have unexpected 
//   consequences... 
//   setFocusCycleRoot(true); 
//   setFocusTraversalPolicy(policy); 

     } 

     @Override 
     public void addNotify() { 
      super.addNotify(); 
//  Comment this out if you use focusCycleRoot 
      SwingUtilities.getWindowAncestor(this).setFocusTraversalPolicy(policy); 
     } 

     protected void add(String label, JTextField field, int x, int y) { 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridy = y; 
      gbc.gridx = x; 
      gbc.insets = new Insets(2, 2, 2, 2); 
      gbc.anchor = GridBagConstraints.EAST; 
      add(new JLabel(label), gbc); 
      gbc.gridx++; 
      add(field, gbc); 
     } 
    } 

    public static class MyOwnFocusTraversalPolicy 
        extends FocusTraversalPolicy { 

     private List<Component> order; 

     public MyOwnFocusTraversalPolicy(Component... order) { 
      this.order = new ArrayList<>(Arrays.asList(order)); 
     } 

     @Override 
     public Component getComponentAfter(Container focusCycleRoot, 
         Component aComponent) { 
      int idx = (order.indexOf(aComponent) + 1) % order.size(); 
      return order.get(idx); 
     } 

     @Override 
     public Component getComponentBefore(Container focusCycleRoot, 
         Component aComponent) { 
      int idx = order.indexOf(aComponent) - 1; 
      if (idx < 0) { 
       idx = order.size() - 1; 
      } 
      return order.get(idx); 
     } 

     @Override 
     public Component getDefaultComponent(Container focusCycleRoot) { 
      return order.get(0); 
     } 

     @Override 
     public Component getLastComponent(Container focusCycleRoot) { 
      return order.size() > 0 ? order.get(order.size()) : null; 
     } 

     @Override 
     public Component getFirstComponent(Container focusCycleRoot) { 
      return order.get(0); 
     } 
    } 
} 
+0

+1很好的例子尤其是大量使用的Swing的对焦系统 – 2013-02-16 18:52:21

+0

不能重复往往不够:这么幼稚的实施FocusTraversalPolicy将_break_,但在所有(有复合部件或实容器中,作为孩子当网络连接),因为它是最微不足道的上下文必须处理下面的组件树(直到下一个嵌套策略)。 – kleopatra 2013-03-10 14:43:19

+0

你救了我的命。真的很好的例子。 – uzzi 2016-09-08 09:21:51