如何在单击输入数字按钮时保持对JTextField的焦点?

3
我对GUI的相关知识比较陌生,以下是我遇到的问题。我有3个JTextFields,分别是信用卡号、过期日期和安全码。我可以在这些字段中输入信息。我还为每个按钮实现了焦点监听器。如果我单击它,它会显示获得焦点,如果我单击其他任何地方,它就会失去焦点。在这些文本字段下面,我有一个数字键盘(触摸屏/鼠标单击),用于输入数字。如何保持焦点在特定的文本字段上,直到仅且明确地单击另外两个文本字段之一?当前具有焦点的文本字段将在尝试单击以输入数字时失去焦点。我不希望发生这种情况。我在网上搜索并没有找到适用于我的情况的特定解决方案。如果您能提供任何帮助或提示,我将不胜感激。

为什么会发生这种情况?我已经提供了可工作的代码。你的代码有什么不同?请发布一个 SSCCE 来演示问题。 - camickr
2个回答

7
myJButton.setFocusable(false);

如果一组按钮被放在一个名为allMyButtons的集合中:

for (JButton button: allMyButtons) {
    button.setFocusable(false);
}

这就是全部。


啊,现在我可以在网上找到很多东西了。我会试一下然后晚点回复你。谢谢。 - Kumar
用以下方法解决了。谢谢!我把所有数字按钮设置为false,根据焦点的不同,在文本字段之间交替设置为true和false。 - Kumar

3
除了@Hovercrafts的建议(+1)之外,您可能还想扩展 TextAction 以实现将数字插入文本字段的逻辑。 TextAction 使您可以访问最近获得焦点的文本字段,因此插入代码变得非常通用:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;

public class NumpadPanel extends JPanel
{
    public NumpadPanel()
    {
        setLayout( new BorderLayout() );

        JTextField textField1 = new JTextField(4);
        JTextField textField2 = new JTextField(2);
        JTextField textField3 = new JTextField(2);

        JPanel panel = new JPanel();
        panel.add( textField1 );
        panel.add( textField2 );
        panel.add( textField3 );
        add(panel, BorderLayout.PAGE_START);

        Action numberAction = new TextAction("")
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                JTextComponent textComponent = getFocusedComponent();

                if (textComponent != null)
                    textComponent.replaceSelection(e.getActionCommand());
            }
        };

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout( new GridLayout(0, 5) );
        add(buttonPanel, BorderLayout.CENTER);

        for (int i = 0; i < 10; i++)
        {
            String text = String.valueOf(i);
            JButton button = new JButton( text );
            button.addActionListener( numberAction );
            button.setMargin( new Insets(20, 20, 20, 20) );
            button.setFocusable( false );
            buttonPanel.add( button );
        }

        // Optionally auto tab when text field is full

        //SizeDocumentFilter sf = new SizeDocumentFilter();
        //sf.installFilter(textField1, textField2, textField3);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("Numpad Panel");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new NumpadPanel() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

您可能还想考虑使用文本字段自动制表,以便在文本字段变满时焦点会从一个文本字段移动到另一个文本字段。


谢谢您的回复,但是我无法扩展TextAction类,因为我已经扩展了另一个类。对于我来说,要处理的代码太多了。但最终我使用了Hovercrafts的答案使其正常工作。 - Kumar
@Harold,是的,Hovercrafts的回答解决了你的问题。TextAction提供了更好的设计。我已经扩展了一个不同的类,什么不同的类?你完全可以像我演示的那样创建一个简单的类。这个类独立于你可能已经创建的任何类。 - camickr
我想时间是原因。我们正在设计一个POS系统,我负责SQL/数据库方面的工作。GUI团队有太多的工作要处理,所以我决定尝试帮忙。我迷失了方向,不知道从哪里开始。这是一次很好的学习经验。我们的项目已经完成,但我会尝试修改代码来扩展TextAction。 - Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接