Java 焦点侦听器行为

Java 焦点侦听器行为,java,swing,jframe,focuslistener,Java,Swing,Jframe,Focuslistener,我有一个JFrame,当用户点击它时,我想关闭它。我有两个JTextFields和一个JButton(用户名、密码、提交)。当我给他们所有的FocusListener时,只要用户从一个字段转到另一个字段,窗口就会关闭。我如何允许用户从一个字段转到另一个字段,并且仅在用户单击弹出窗口外的任何位置时才将其关闭 public class LoginForm { static JTextField userName; static JTextField password; st

我有一个
JFrame
,当用户点击它时,我想关闭它。我有两个
JTextFields
和一个
JButton
(用户名、密码、提交)。当我给他们所有的
FocusListener
时,只要用户从一个字段转到另一个字段,窗口就会关闭。我如何允许用户从一个字段转到另一个字段,并且仅在用户单击弹出窗口外的任何位置时才将其关闭

public class LoginForm {

    static JTextField userName;
    static JTextField password;
    static JButton submit;
    JFrame main;
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

    UserSession session;

    public LoginForm(){

        Handler handle = new Handler();  //inner class
        LoginFormFocusListener fl = new LoginFormFocusListener();   //inner class

        main = new JFrame("Please Login");

        main.setUndecorated(true);
        main.setBounds((dim.width/2) - (500/2),(dim.height/2) - (150/2),500,150);
        main.setVisible(true);
        main.setAlwaysOnTop(true);
        main.setResizable(false);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        userName = new JTextField(10);
        password = new JTextField(10);
        main.setLayout(new GridLayout(0,1));

        JPanel panel = new JPanel();
        main.add(panel);
        panel.add(new JLabel("Username: "));
        panel.add(userName);
        panel.add(new JLabel("Password: "));
        panel.add(password);

        submit = new JButton("Submit");
        panel.add(submit);

        userName.addFocusListener(fl);
        password.addFocusListener(fl);
        submit.addFocusListener(fl);

        submit.addActionListener(handle);
    }
}
。。。(省略了不重要的方法和“Handler”类)


不要为此使用FocusListener,因为它们用于获得和失去焦点的组件,而不是顶级窗口。可能使用WindowListener监听窗口是否已停用或图标化

例如:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class WindowListenerFun {
   public static void main(String[] args) {
      JPanel panel = new JPanel();
      panel.add(new JTextField(10));
      panel.add(new JButton("button"));
      JFrame frame = new JFrame("Bad Frame");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(panel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);

      frame.addWindowListener(new WindowAdapter() {

         @Override
         public void windowIconified(WindowEvent wEvt) {
            ((JFrame)wEvt.getSource()).dispose();
         }

         @Override
         public void windowDeactivated(WindowEvent wEvt) {
            ((JFrame)wEvt.getSource()).dispose();
         }

      });
   }
}

编辑:我误读了你的代码;另一个答案是正确的——您需要使用WindowFocusListener而不是FocusListener

public class Listener extends WindowAdapter
{
    public void windowLostFocus(WindowEvent e)
    {
        Window w = e.getWindow();
        e.setVisible(false);
        e.dispose();
    }
}

main.addWindowFocusListener(新的Listener())

Edit2:将占位符替换为窗口关闭代码

然后将焦点侦听器添加到各个菜单组件中,每当组件失去焦点时,就会触发该侦听器。您只希望它在窗口失去焦点时被触发,因此将其添加到窗口中

main.addWindowFocusListener(f1)

应该能解决你的问题

public class Listener extends WindowAdapter
{
    public void windowLostFocus(WindowEvent e)
    {
        Window w = e.getWindow();
        e.setVisible(false);
        e.dispose();
    }
}