怎样通过按下回车键在一个JTextField中切换到下一个JTextField?

huangapple go评论79阅读模式
英文:

How to across JTextField to next JTextField by hit Enter

问题

// Checkbox 1 action performed
private void chk1ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    if(chk1.isSelected()){
        p1.setEnabled(false);
    } else{
        p1.setEnabled(true);
    }
}

// Checkbox 2 action performed
private void chk2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    if(chk2.isSelected()){
        p2.setEnabled(false);
    } else{
        p2.setEnabled(true);
    }
}

// Checkbox 3 action performed
private void chk3ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    if(chk3.isSelected()){
        p3.setEnabled(false);
    } else{
        p3.setEnabled(true);
    }
} 

// Second text field key pressed
private void p1KeyPressed(java.awt.event.KeyEvent evt) {                                 
    if(evt.getKeyCode() == KeyEvent.VK_ENTER){
        p2.requestFocus();
    }
}

// Third text field key pressed
private void p2KeyPressed(java.awt.event.KeyEvent evt) {                                 
    if(evt.getKeyCode() == KeyEvent.VK_ENTER){
        p3.requestFocus();
    }
}

// Enter key pressed on third text field
private void p3KeyPressed(java.awt.event.KeyEvent evt) {                                 
    if(evt.getKeyCode() == KeyEvent.VK_ENTER){
        // Handle further action here
    }
}

请注意,以上是您提供的代码的翻译部分。如有需要,请随时告诉我需要添加哪些其他部分的翻译。

英文:

When select check box to set enable(false) on second text field and hit enter need to focus at third text field
if not select any check box then hit ENTER it can be focus on text field as flow.
I should add any code or how can I make it work

My GUI:

怎样通过按下回车键在一个JTextField中切换到下一个JTextField?

private void chk1ActionPerformed(java.awt.event.ActionEvent evt) {                                     
// Set action perform for check box:
if(chk1.isSelected()){
p1.setEnabled(false);
} else{
p1.setEnabled(true);
}
}
private void chk2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
// Set action perform for check box:
if(chk2.isSelected()){
p2.setEnabled(false);
} else{
p2.setEnabled(true);
}
}
private void chk3ActionPerformed(java.awt.event.ActionEvent evt) {                                     
// Set action perform for check box:
if(chk3.isSelected()){
p3.setEnabled(false);
} else{
p3.setEnabled(true);
}
} 
private void p_numKeyPressed(java.awt.event.KeyEvent evt) {                                 
// TODO add your handling code here:
if(evt.getKeyCode()==KeyEvent.VK_ENTER){
p1.requestFocus();
}
}
private void p1KeyPressed(java.awt.event.KeyEvent evt) {                                 
// TODO add your handling code here:
if(evt.getKeyCode()==KeyEvent.VK_ENTER){
p2.requestFocus();
}
}
private void p2KeyPressed(java.awt.event.KeyEvent evt) {                                 
// TODO add your handling code here:
if(evt.getKeyCode()==KeyEvent.VK_ENTER){
p3.requestFocus();
}
}

答案1

得分: 2

我认为你正在寻找的是焦点子系统。这个子系统负责在按下焦点遍历键时组件获取焦点的顺序。例如,你可以定义组件获取焦点的顺序,并添加检查以仅将焦点转移到已启用的组件。你似乎还想将<kbd> ENTER </kbd>键添加为焦点遍历键(即在按下它时,焦点将根据当前焦点遍历策略转移到另一个组件)。所有这些都可以通过焦点子系统来实现。

以下代码似乎可以实现你的要求,利用了焦点子系统:

import java.awt.Component;
import java.awt.Container;
import java.awt.DefaultFocusTraversalPolicy;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class FocusHopSystem {
    
    public static class AbsoluteFocusTraversalPolicy extends DefaultFocusTraversalPolicy {
        private final Component[] comps;
        
        public AbsoluteFocusTraversalPolicy(final Component... comps) {
            this.comps = comps.clone();
        }
        
        private int indexOf(final Component comp) {
            for (int i = 0; i &lt; comps.length; ++i)
                if (comps[i] == comp)
                    return i;
            return -1;
        }

        @Override
        public Component getComponentAfter(final Container aContainer, final Component aComponent) {
            final int aIndex = indexOf(aComponent);
            if (aIndex &lt; 0)
                return null;
            for (int i = 1; i &lt; comps.length; ++i) {
                final Component after = comps[(aIndex + i) % comps.length];
                if (after != null &amp;&amp; after.isDisplayable() &amp;&amp; after.isVisible() &amp;&amp; after.isEnabled())
                    return after;
            }
            return null;
        }

        @Override
        public Component getComponentBefore(final Container aContainer, final Component aComponent) {
            final int aIndex = indexOf(aComponent);
            if (aIndex &lt; 0)
                return null;
            for (int i = 1; i &lt; comps.length; ++i) {
                final Component before = comps[(aIndex - i + comps.length) % comps.length];
                if (before != null &amp;&amp; before.isDisplayable() &amp;&amp; before.isVisible() &amp;&amp; before.isEnabled())
                    return before;
            }
            return null;
        }

        @Override
        public Component getFirstComponent(final Container aContainer) {
            for (int i = 0; i &lt; comps.length; ++i) {
                final Component first = comps[i];
                if (first != null &amp;&amp; first.isDisplayable() &amp;&amp; first.isVisible() &amp;&amp; first.isEnabled())
                    return first;
            }
            return null;
        }

        @Override
        public Component getLastComponent(final Container aContainer) {
            for (int i = comps.length - 1; i &gt;= 0; --i) {
                final Component last = comps[i];
                if (last != null &amp;&amp; last.isDisplayable() &amp;&amp; last.isVisible() &amp;&amp; last.isEnabled())
                    return last;
            }
            return null;
        }

        @Override
        public Component getDefaultComponent(final Container aContainer) {
            return getFirstComponent(aContainer);
        }
    }
    
    private static void createAndShowGUI() {
        final String text = &quot;0&quot;;
        final int width = 12;
        
        final JTextField tf1 = new JTextField(text, width),
                         tf2 = new JTextField(text, width),
                         tf3 = new JTextField(text, width),
                         tf4 = new JTextField(text, width);
        
        final JCheckBox ck2 = new JCheckBox(&quot;jTextField2&quot;, true),
                        ck3 = new JCheckBox(&quot;jTextField3&quot;, true),
                        ck4 = new JCheckBox(&quot;jTextField4&quot;, true);
        
        final JButton save = new JButton(&quot;Save&quot;);
        
        ck2.addActionListener(e -&gt; tf2.setEnabled(ck2.isSelected()));
        ck3.addActionListener(e -&gt; tf3.setEnabled(ck3.isSelected()));
        ck4.addActionListener(e -&gt; tf4.setEnabled(ck4.isSelected()));
        
        final JPanel frameContents = new JPanel(new GridLayout(0, 5, 5, 5));
        
        //First row:
        frameContents.add(new JPanel());
        frameContents.add(ck2);
        frameContents.add(ck3);
        frameContents.add(ck4);
        frameContents.add(new JPanel());
        
        //Second row:
        frameContents.add(tf1);
        frameContents.add(tf2);
        frameContents.add(tf3);
        frameContents.add(tf4);
        frameContents.add(save);
        
        //Make the other components unfocusable:
        for (final Component comp: new Component[]{ck2, ck3, ck4, save})
            comp.setFocusable(false);
        
        //Make frameContents the focus cycle root:
        frameContents.setFocusCycleRoot(true);
        
        //Install our FocusTraversalPolicy to the cycle root:
        frameContents.setFocusTraversalPolicy(new AbsoluteFocusTraversalPolicy(tf1, tf2, tf3, tf4));
        
        //Add KeyEvent.VK_ENTER key to the focus traversal keys of the frameContents:
        final Set forwardKeys = frameContents.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
        final Set newForwardKeys = new HashSet(forwardKeys);
        newForwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
        frameContents.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, newForwardKeys);
        
        final JFrame frame = new JFrame(&quot;Focus traversal test.&quot;);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(frameContents);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        
        //Start focus on the first text field:
        tf1.requestFocusInWindow();
    }
    
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(FocusHopSystem::createAndShowGUI);
    }
}

在上面的示例中,我将<kbd> ENTER </kbd>键添加为焦点遍历键的一个备选项,除了<kbd> TAB </kbd>。

编辑1:更简单的方法...

我发现,这比第一个示例代码更简单,这是因为默认的焦点遍历策略已经可以满足你的要求,即只允

英文:

I think what you are looking for is the Focus Subsystem. This is responsible for the order in which components are getting focus when you press a focus traversal key. For example you can define what is the order of the components to get focus, and also add the check to transfer focus only to enabled components. What you also seem to want to do is to add the <kbd>ENTER</kbd> key as a focus traversal key (ie when pressing it, the focus will be transfered to another component - according to the current focus traversal policy). All this can be done via the focus subsystem.

The following code seems to do what you are asking, by utilizing the focus subsystem:

import java.awt.Component;
import java.awt.Container;
import java.awt.DefaultFocusTraversalPolicy;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class FocusHopSystem {
public static class AbsoluteFocusTraversalPolicy extends DefaultFocusTraversalPolicy {
private final Component[] comps;
public AbsoluteFocusTraversalPolicy(final Component... comps) {
this.comps = comps.clone();
}
private int indexOf(final Component comp) {
for (int i = 0; i &lt; comps.length; ++i)
if (comps[i] == comp)
return i;
return -1;
}
@Override
public Component getComponentAfter(final Container aContainer, final Component aComponent) {
final int aIndex = indexOf(aComponent);
if (aIndex &lt; 0)
return null;
for (int i = 1; i &lt; comps.length; ++i) {
final Component after = comps[(aIndex + i) % comps.length];
if (after != null &amp;&amp; after.isDisplayable() &amp;&amp; after.isVisible() &amp;&amp; after.isEnabled())
return after;
}
return null;
}
@Override
public Component getComponentBefore(final Container aContainer, final Component aComponent) {
final int aIndex = indexOf(aComponent);
if (aIndex &lt; 0)
return null;
for (int i = 1; i &lt; comps.length; ++i) {
final Component before = comps[(aIndex - i + comps.length) % comps.length];
if (before != null &amp;&amp; before.isDisplayable() &amp;&amp; before.isVisible() &amp;&amp; before.isEnabled())
return before;
}
return null;
}
@Override
public Component getFirstComponent(final Container aContainer) {
for (int i = 0; i &lt; comps.length; ++i) {
final Component first = comps[i];
if (first != null &amp;&amp; first.isDisplayable() &amp;&amp; first.isVisible() &amp;&amp; first.isEnabled())
return first;
}
return null;
}
@Override
public Component getLastComponent(final Container aContainer) {
for (int i = comps.length - 1; i &gt;= 0; --i) {
final Component last = comps[i];
if (last != null &amp;&amp; last.isDisplayable() &amp;&amp; last.isVisible() &amp;&amp; last.isEnabled())
return last;
}
return null;
}
@Override
public Component getDefaultComponent(final Container aContainer) {
return getFirstComponent(aContainer);
}
}
private static void createAndShowGUI() {
final String text = &quot;0&quot;;
final int width = 12;
final JTextField tf1 = new JTextField(text, width),
tf2 = new JTextField(text, width),
tf3 = new JTextField(text, width),
tf4 = new JTextField(text, width);
final JCheckBox ck2 = new JCheckBox(&quot;jTextField2&quot;, true),
ck3 = new JCheckBox(&quot;jTextField3&quot;, true),
ck4 = new JCheckBox(&quot;jTextField4&quot;, true);
final JButton save = new JButton(&quot;Save&quot;);
ck2.addActionListener(e -&gt; tf2.setEnabled(ck2.isSelected()));
ck3.addActionListener(e -&gt; tf3.setEnabled(ck3.isSelected()));
ck4.addActionListener(e -&gt; tf4.setEnabled(ck4.isSelected()));
final JPanel frameContents = new JPanel(new GridLayout(0, 5, 5, 5));
//First row:
frameContents.add(new JPanel());
frameContents.add(ck2);
frameContents.add(ck3);
frameContents.add(ck4);
frameContents.add(new JPanel());
//Second row:
frameContents.add(tf1);
frameContents.add(tf2);
frameContents.add(tf3);
frameContents.add(tf4);
frameContents.add(save);
//Make the other components unfocusable:
for (final Component comp: new Component[]{ck2, ck3, ck4, save})
comp.setFocusable(false);
//Make frameContents the focus cycle root:
frameContents.setFocusCycleRoot(true);
//Install our FocusTraversalPolicy to the cycle root:
frameContents.setFocusTraversalPolicy(new AbsoluteFocusTraversalPolicy(tf1, tf2, tf3, tf4));
//Add KeyEvent.VK_ENTER key to the focus traversal keys of the frameContents:
final Set forwardKeys = frameContents.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
final Set newForwardKeys = new HashSet(forwardKeys);
newForwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
frameContents.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, newForwardKeys);
final JFrame frame = new JFrame(&quot;Focus traversal test.&quot;);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(frameContents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//Start focus on the first text field:
tf1.requestFocusInWindow();
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(FocusHopSystem::createAndShowGUI);
}
}

In the above example, I am adding the key <kbd>ENTER</kbd> as an alternative focus traversal key, aside from <kbd>TAB</kbd>.

Edit 1: It's even simpler...

As I found out, it's even simpler than the first sample code, and that's because the default focus traversal policy does what you are asking, ie allows only focusable-and-enabled components to gain focus and in the desired order. So we only need to make the unneeded components to non-focusable (ie the check-boxes and the button) and leave enabled the text-fields. Just add/set the <kbd>ENTER</kbd> key as a focus traversal key and you are good to go:

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class FocusHopSystem2 {
private static void createAndShowGUI() {
final String text = &quot;0&quot;;
final int width = 12;
final JTextField tf1 = new JTextField(text, width),
tf2 = new JTextField(text, width),
tf3 = new JTextField(text, width),
tf4 = new JTextField(text, width);
final JCheckBox ck2 = new JCheckBox(&quot;jTextField2&quot;, true),
ck3 = new JCheckBox(&quot;jTextField3&quot;, true),
ck4 = new JCheckBox(&quot;jTextField4&quot;, true);
final JButton save = new JButton(&quot;Save&quot;);
ck2.addActionListener(e -&gt; tf2.setEnabled(ck2.isSelected()));
ck3.addActionListener(e -&gt; tf3.setEnabled(ck3.isSelected()));
ck4.addActionListener(e -&gt; tf4.setEnabled(ck4.isSelected()));
final JPanel frameContents = new JPanel(new GridLayout(0, 5, 5, 5));
//First row:
frameContents.add(new JPanel());
frameContents.add(ck2);
frameContents.add(ck3);
frameContents.add(ck4);
frameContents.add(new JPanel());
//Second row:
frameContents.add(tf1);
frameContents.add(tf2);
frameContents.add(tf3);
frameContents.add(tf4);
frameContents.add(save);
//Make the other components unfocusable:
for (final Component comp: new Component[]{ck2, ck3, ck4, save})
comp.setFocusable(false);
//Make frameContents the focus cycle root:
frameContents.setFocusCycleRoot(true);
////Install the DefaultFocusTraversalPolicy to the cycle root:
//frameContents.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy()); //This is not necessary in this case.
//Add KeyEvent.VK_ENTER key to the focus traversal keys of the frameContents:
final Set forwardKeys = frameContents.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
final Set newForwardKeys = new HashSet(forwardKeys);
newForwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
frameContents.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, newForwardKeys);
final JFrame frame = new JFrame(&quot;Focus traversal test.&quot;);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(frameContents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//Start focus on the first text field:
tf1.requestFocusInWindow();
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(FocusHopSystem2::createAndShowGUI);
}
}

You may also read The AWT Focus Subsystem.

答案2

得分: 1

以下是翻译好的部分:

这是“Tab”键的默认工作方式。当您按下“Tab”键时,焦点将移动到下一个启用的组件。

如果您想要为“Enter”键复制此功能,首先可以创建一个自定义的“Action”

Action transfer = new AbstractAction()
{
    @Override
    public void actionPerformed(ActionEvent e)
    {
        Component c = (Component)e.getSource();
        c.transferFocus();
    }
};

默认情况下,“Enter”键将调用添加到文本字段的“ActionListener”。现在,您可以将此“Action”添加到特定的文本字段:

...
textField1.addActionListener(transfer);
textField2.addActionListener(transfer);

或者,您可以通过将自定义的“Action”添加到“ActionMap”来替换所有文本字段的默认Enter“Action”:

...
ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");
am.put("notify-field-accept", transfer);
英文:

This is the way the Tab key works by default. When you press Tab focus will move to the next enabled component.

If you want to duplicate this functionality for the Enter key then first you can create a custom Action

Action transfer = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
Component c = (Component)e.getSource();
c.transferFocus();
}
};

By default the "Enter" key will invoke the ActionListener added to the text field. So, now you can add this Action to specific text fields:

...
textField1.addActionListener( transfer );
textField2.addActionListener( transfer );

Or you can replace the default Enter Action of all the text fields by adding your custom Action to the ActionMap:

...
ActionMap am = (ActionMap)UIManager.get(&quot;TextField.actionMap&quot;);
am.put(&quot;notify-field-accept&quot;, transfer);

huangapple
  • 本文由 发表于 2020年8月3日 18:16:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63227570.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定