2013-02-15 103 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