检测框架外的点击很困难,因为它可能是对 java 无法访问的任何其他应用程序的点击。
您可以尝试FocusListener
如下所示
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class AutoCloseFrameDemo {
public static void main( String[] args ) {
final JFrame frame = new JFrame( "Test" );
frame.addFocusListener( new FocusListener() {
private boolean gained = false;
@Override
public void focusGained( FocusEvent e ) {
gained = true;
}
@Override
public void focusLost( FocusEvent e ) {
if ( gained ){
frame.dispose();
}
}
} );
frame.add( new JLabel( "testlabel" ) );
frame.pack();
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
这适用于这个简单的用例。尚不确定如果将例如 aJTextField
放在框架中并且文本字段获得焦点会发生什么。如果这也导致JFrame
焦点松动,那么您的应用程序将毫无用处。
编辑
更强大的解决方案可能是将侦听器附加到KeyboardFocusManager
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
public class AutoCloseFrameDemo {
public static void main( String[] args ) {
final JFrame frame = new JFrame( "Test" );
KeyboardFocusManager.getCurrentKeyboardFocusManager().
addVetoableChangeListener( "focusedWindow",
new VetoableChangeListener() {
private boolean gained = false;
@Override
public void vetoableChange( PropertyChangeEvent evt ) throws PropertyVetoException {
if ( evt.getNewValue() == frame ) {
gained = true;
}
if ( gained && evt.getNewValue() != frame ) {
frame.dispose();
}
}
} );
frame.add( new JTextField( 10 ), BorderLayout.NORTH );
frame.add( new JTextField( 10 ), BorderLayout.SOUTH );
frame.pack();
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
这允许在框架中的不同文本字段之间切换焦点。