我在这里有一个相当基本的JFrame,我希望当用户在其外部点击时自动关闭窗口。当用户点击窗口时(通过某种方式检测窗口外的点击?),是否可以关闭窗口。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ExampleJFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("How can I make this window close when I click outside it?");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JLabel jlbempty = new JLabel("");
jlbempty.setPreferredSize(new Dimension(200, 200));
frame.getContentPane().add(jlbempty, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
答案 0 :(得分:8)
检测框架外的点击很困难,因为它可以点击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 );
}
}
这适用于这个简单的用例。还不确定如果你把...框架中的JTextField
和文本字段获得焦点。如果这导致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 );
}
}
这允许在帧中的不同文本字段之间切换焦点。