有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何解除JTextField的焦点

当我的应用程序加载(使用netbeans创建)时,第一个JTextField会自动聚焦,在这个JTextField中,我写了“输入你的用户名”,当用户点击这个字段时,它会消失,但当应用程序加载时,这个字段聚焦,意味着我看不到“输入你的用户名”,如何在启动时解除关注


共 (3) 个答案

  1. # 1 楼答案

    登录最好在模式对话框中完成,但这会带来问题,因为在组件可见后必须调用方法requestFocusInWindow(),但由于对话框是模式的,所以这会被阻止

    本例使用Rob Camick的RequestFocusListener(如Dialog Focus中所示)在对话框可见后管理焦点

    Login with focused password field

    注意:这就是它在用户做任何事情之前的显示方式。默认情况下,密码字段是聚焦的

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class LoginRequired {
    
        LoginRequired() {
            JFrame f = new JFrame("Login Required");
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            f.setResizable(false);
            f.setSize(400, 300); // not recommended, but used here for convenience
            f.setLocationByPlatform(true);
            f.setVisible(true);
    
            showLogin(f);
        }
    
        private void showLogin(JFrame frame) {
            JPanel p = new JPanel(new BorderLayout(5,5));
    
            JPanel labels = new JPanel(new GridLayout(0,1,2,2));
            labels.add(new JLabel("User Name", SwingConstants.TRAILING));
            labels.add(new JLabel("Password", SwingConstants.TRAILING));
            p.add(labels, BorderLayout.LINE_START);
    
            JPanel controls = new JPanel(new GridLayout(0,1,2,2));
            JTextField username = new JTextField("Joe Blogs");
            controls.add(username);
            JPasswordField password = new JPasswordField();
            password.addAncestorListener(new RequestFocusListener(false));
            controls.add(password);
            p.add(controls, BorderLayout.CENTER);
    
            JOptionPane.showMessageDialog(
                frame, p, "Log In", JOptionPane.QUESTION_MESSAGE);
            System.out.println("User Name: " + username.getText());
            System.out.println("Password: " + new String(password.getPassword()));
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                new LoginRequired();
            });
        }
    }
    
    /**
     *  Convenience class to request focus on a component.
     *
     *  When the component is added to a realized Window then component will
     *  request focus immediately, since the ancestorAdded event is fired
     *  immediately.
     *
     *  When the component is added to a non realized Window, then the focus
     *  request will be made once the window is realized, since the
     *  ancestorAdded event will not be fired until then.
     *
     *  Using the default constructor will cause the listener to be removed
     *  from the component once the AncestorEvent is generated. A second constructor
     *  allows you to specify a boolean value of false to prevent the
     *  AncestorListener from being removed when the event is generated. This will
     *  allow you to reuse the listener each time the event is generated.
     */
    class RequestFocusListener implements AncestorListener
    {
        private boolean removeListener;
    
        /*
         *  Convenience constructor. The listener is only used once and then it is
         *  removed from the component.
         */
        public RequestFocusListener()
        {
            this(true);
        }
    
        /*
         *  Constructor that controls whether this listen can be used once or
         *  multiple times.
         *
         *  @param removeListener when true this listener is only invoked once
         *                        otherwise it can be invoked multiple times.
         */
        public RequestFocusListener(boolean removeListener)
        {
            this.removeListener = removeListener;
        }
    
        @Override
        public void ancestorAdded(AncestorEvent e)
        {
            JComponent component = e.getComponent();
            component.requestFocusInWindow();
    
            if (removeListener)
                component.removeAncestorListener( this );
        }
    
        @Override
        public void ancestorMoved(AncestorEvent e) {}
    
        @Override
        public void ancestorRemoved(AncestorEvent e) {}
    }
    
  2. # 2 楼答案

    textField.setFocusable(false);
    textField.setFocusable(true);
    

    如果且仅当textField具有焦点,则TAB顺序中的下一个组件将自动获得焦点。其效果与按TAB键相同

    (未在只有一个可聚焦组件的GUI中测试:))

  3. # 3 楼答案

    使用^{}将焦点设置在其他组件上,而不是首先设置JTextfield

    但是我建议不要改变本机焦点系统,而是在constructor中的JTextFieldinitComponents()调用上setText(String s)(假设在netbeans中)

    进一步可选阅读:How to Use the Focus Subsystem