如何在JTextField上设置焦点?

31
我让我的游戏不需要鼠标就能运行,所以使用指针不是一个选择。当玩家失败时,将显示最高分菜单。
这是我的代码。
    highScore=new MyTextField("Your Name");
    highScore.addKeyListener(this);
    highScore.setFont(font);
    highScore.requestFocusInWindow();

我已经尝试过

highScore.setFocusable(true);
highScore.requestFocusInWindow();
highScore.requestFocus(true);
highScore.requestFocus();

但是我的JTextField仍未获得焦点。

如何让它获得焦点?


你在GUI中哪里添加highScore字段?我个人会将高分对话框显示为JOptionPane或JDialog,或者通过CardLayout交换GUI视图。 - Hovercraft Full Of Eels
嗯...我正在设计我的高分面板。所以看起来好像没有使用swing。JOptionPane,JDialog。它们可以更改吗?CardLayout?我不知道那个。我会尝试一下。 - Kenjiro
1
目前为止,根据您提供的有限信息,我们不确定您正在做什么。我们只知道您的GUI可能已经插入了一个名为“highScore”的组件,并且上面的代码是尝试获取对它的引用。请提供更多详细信息和更多代码,以便我们能够更好地帮助您。否则,我们只能猜测。最好创建并发布一个SSCCE,以说明您的问题。 - Hovercraft Full Of Eels
是的。我有主菜单、舞台,如果输了或游戏结束则绘制图片并要求输入名称以提交分数。我已经用我的GameAction(一个管理键盘按下或未按下的类)解决了这个问题。我可以使用tap()方法虚拟按下键盘。因此,我创建了我的GameAction,用户很少按下像F1或€这样的按键。当该按钮被按下时(我虚拟按下),调用requestFocus。谢谢你的帮助。 - Kenjiro
10个回答

61

如果您希望在GUI显示时将焦点放在JTextField上,可以使用以下代码:

in = new JTextField(40);
f.addWindowListener( new WindowAdapter() {
    public void windowOpened( WindowEvent e ){
        in.requestFocus();
    }
}); 

其中f代表您的JFrame,而in则是您的JTextField


那时它也应该能工作,但您需要使用另一种方法。所有可用的方法都在WindowAdapter文档中显示。 - Lukas Knuth
所以你的框架已经显示,然后你在onClick事件或其他事件中显示了你的JTextField?当它显示出来时,它应该获得输入焦点吗? - Lukas Knuth
是的。我有主菜单、舞台,如果输了或游戏结束则绘制图片并要求输入名称以提交分数。我已经用我的GameAction(一个管理键盘按下或未按下的类)解决了这个问题。我可以使用tap()方法虚拟按下键盘。因此,我创建了我的GameAction,用户很少按下,例如F1或€之类的按钮。当按下该按钮时(我虚拟按下),调用requestFocus。谢谢你的帮助。 - Kenjiro
即使 f 不是包含组件,这对我也起作用。我不明白。我创建了一个 JDialog 并在之后使用了 in.requestFocus();,但它没有起作用。我添加了一个 windowListener 并从那里请求焦点,然后它就起作用了。但为什么呢?你能解释一下吗? - WVrock
你把windowListener添加到对话框里了?那很奇怪。我猜requestFocus()实际上并没有立即执行任何操作,而只是将该操作添加到事件队列中。 - Lukas Knuth
显示剩余2条评论

8
如果只有一个顶级容器,那么GUI构造函数的最后几行将是这样的。
.
.
.
myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {

   @Override
     public void run() {
         myComponent.grabFocus();
         myComponent.requestFocus();//or inWindow
     }
});

6
public void actionPerformed(ActionEvent arg0)
{
    if (arg0.getSource()==clearButton)
    {
        enterText.setText(null);
        enterText.grabFocus();  //Places flashing cursor on text box        
    }       
}

2

试试这个,

myFrame.setVisible(true);
EventQueue.invokeLater(new Runnable() {

   @Override
     public void run() {
         myComponent.grabFocus();
         myComponent.requestFocus();//or inWindow
     }
});

0

当我尝试使用时,它对我不起作用:

JOptionPane.showConfirmDialog(...)

但是 - 我找到了一个解决方案! 非常原始,但有效。
只需使用键“Tab”通过java.awt.Robot跳转到字段。 例如:
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(100);
robot.keyRelease(KeyEvent.VK_TAB);

如果您需要按多次“Tab”才能获取到您的组件,您可以使用以下方法:
GUIUtils.pressTab(3);

定义:

public static void pressTab(int amountOfClickes)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            try
            {
                Robot robot = new Robot();
                int i = amountOfClickes;
                while (i-- > 0)
                {
                    robot.keyPress(KeyEvent.VK_TAB);
                    robot.delay(100);
                    robot.keyRelease(KeyEvent.VK_TAB);
                }
            }
            catch (AWTException e)
            {
                System.out.println("Failed to use Robot, got exception: " + e.getMessage());
            }
        }
    });
}

如果您的组件位置是动态的,您可以无限制地运行while循环,但需要在组件上添加一些焦点监听器,在到达组件时停止循环。

0
在我的情况下,除非在构造函数返回之后调用requestFocus(),否则以上所有方法都不起作用。
MyPanel panel = new MyPanel(...);
frame.add(panel);
panel.initFocus();

MyPanel.initFocus() 将会有:

myTextField.requestFocus();

它有效。


0

虽然yourTextField.requestFocus()是一种解决方案,但它并不是最好的,因为在官方Java文档中,这种方法被认为是依赖于平台的。

文档说:

请注意,不建议使用此方法,因为其行为依赖于平台。相反,我们建议使用requestFocusInWindow()。

请改用yourJTextField.requestFocusInWindow()


0

将jTextField.requestFocusInWindow();放入jTextField FocusLost事件中如何?对我有用。 在JPanel上有5个控件。 一旦单击MessageBox,焦点就会失去在jTextField上。 尝试了所有建议的代码但没有成功,在我的情况下只有上述方法可行。


0

如果页面包含多个项目并且想要设置选项卡顺序和焦点,我建议使用FocusTraversalPolicy。

如果您正在使用FocusTraversalPolicy,则grabFocus()将不起作用。

示例代码

int focusNumber = 0;
Component[] focusList;
focusList = new Component[] { game, move, amount, saveButton,
            printButton, editButton, deleteButton, newButton,
            settingsButton };

frame.setFocusTraversalPolicy(new FocusTraversalPolicy() {

        @Override
        public Component getLastComponent(Container aContainer) {
            return focusList[focusList.length - 1];
        }

        @Override
        public Component getFirstComponent(Container aContainer) {
            return focusList[0];
        }

        @Override
        public Component getDefaultComponent(Container aContainer) {
            return focusList[1];
        }

        @Override
        public Component getComponentAfter(Container focusCycleRoot,
                Component aComponent) {
            focusNumber = (focusNumber + 1) % focusList.length;
            if (focusList[focusNumber].isEnabled() == false) {
                getComponentAfter(focusCycleRoot, focusList[focusNumber]);
            }
            return focusList[focusNumber];
        }

        @Override
        public Component getComponentBefore(Container focusCycleRoot,
                Component aComponent) {
            focusNumber = (focusList.length + focusNumber - 1)
                    % focusList.length;
            if (focusList[focusNumber].isEnabled() == false) {
                getComponentBefore(focusCycleRoot, focusList[focusNumber]);
            }
            return focusList[focusNumber];
        }
    });

0

这段代码用于将鼠标光标定位到“jtextfield”和“Jcombobox”位置

 try {
     Robot  robot = new Robot();
        int x = Jtextfield.getLocationOnScreen().x;
        int y=  Jtextfield.getLocationOnScreen().y;
       JOptionPane.showMessageDialog(null, x+"x< - y>"+y);// for I location see
        robot.mouseMove(x, y);
    } catch (AWTException ex) { 
        ex.printStackTrace();
    } 

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