Как перейти через JTextField к следующему JTextField, нажав Enter - PullRequest
0 голосов
/ 03 августа 2020

При установке флажка для включения (false) во втором текстовом поле и нажатии Enter необходимо сфокусироваться на третьем текстовом поле. если не установите какой-либо флажок, нажмите ENTER, это может быть сосредоточено на текстовом поле как потоке. Я должен добавить любой код или как я могу заставить его работать

My GUI:

https://i.stack.imgur.com/sE997.png

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();
    }
}

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Думаю, вы ищете Подсистему Фокуса . Он отвечает за порядок, в котором компоненты получают фокус при нажатии клавиши обхода фокуса. Например, вы можете определить порядок компонентов для получения фокуса, а также добавить проверку для передачи фокуса только включенным компонентам. Что вы также, кажется, хотите сделать, так это добавить клавишу ENTER в качестве клавиши обхода фокуса (ie при ее нажатии фокус будет перенесен на другой компонент - в соответствии с текущей политикой обхода фокуса) . Все это можно сделать через подсистему фокуса.

Кажется, что следующий код делает то, что вы просите, используя подсистему фокуса:

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 < 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 < 0)
                return null;
            for (int i = 1; i < comps.length; ++i) {
                final Component after = comps[(aIndex + i) % comps.length];
                if (after != null && after.isDisplayable() && after.isVisible() && after.isEnabled())
                    return after;
            }
            return null;
        }

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

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

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

        @Override
        public Component getDefaultComponent(final Container aContainer) {
            return getFirstComponent(aContainer);
        }
    }
    
    private static void createAndShowGUI() {
        final String text = "0";
        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("jTextField2", true),
                        ck3 = new JCheckBox("jTextField3", true),
                        ck4 = new JCheckBox("jTextField4", true);
        
        final JButton save = new JButton("Save");
        
        ck2.addActionListener(e -> tf2.setEnabled(ck2.isSelected()));
        ck3.addActionListener(e -> tf3.setEnabled(ck3.isSelected()));
        ck4.addActionListener(e -> 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("Focus traversal test.");
        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);
    }
}

В приведенном выше примере я добавляю клавиша ENTER в качестве альтернативной клавиши обхода фокуса, помимо TAB .

Edit 1: Это еще проще ...

Как я обнаружил вне, это даже проще, чем в первом примере кода, и это потому, что политика обхода фокуса по умолчанию делает то, что вы просите, ie позволяет только фокусируемым и включенным компонентам получать фокус и в желаемом порядке. Поэтому нам нужно только сделать ненужные компоненты нефокусируемыми (ie флажки и кнопки) и оставить активными текстовые поля. Просто добавьте / установите клавишу ENTER в качестве клавиши обхода фокуса, и вы можете 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 = "0";
        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("jTextField2", true),
                        ck3 = new JCheckBox("jTextField3", true),
                        ck4 = new JCheckBox("jTextField4", true);
        
        final JButton save = new JButton("Save");
        
        ck2.addActionListener(e -> tf2.setEnabled(ck2.isSelected()));
        ck3.addActionListener(e -> tf3.setEnabled(ck3.isSelected()));
        ck4.addActionListener(e -> 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("Focus traversal test.");
        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);
    }
}

Вы также можете прочитать Подсистема AWT Focus .

1 голос
/ 03 августа 2020

Так работает клавиша Tab по умолчанию. Когда вы нажимаете Tab, фокус переместится на следующий включенный компонент.

Если вы хотите продублировать эту функцию для клавиши Enter, то сначала вы можете создать собственный Action

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

По умолчанию клавиша «Enter» вызывает ActionListener, добавленный в текстовое поле. Итак, теперь вы можете добавить это Action в указанные c текстовые поля:

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

Или вы можете заменить вводимый по умолчанию Action для всех текстовых полей, добавив свой собственный Action в ActionMap:

...
ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");
am.put("notify-field-accept", transfer);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...