检测帧外的点击很困难,因为它可以是任何其他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);
}
}
这允许在帧中的不同的文本字段之间切换焦点。
我希望这是与我的问题有关:http://stackoverflow.com/questions/5717716/detecting-focus-on-frame-components-in-swing –
其实这个问题包含你需要的确切答案.. –
这不适用于所有情况,但是一旦它失去焦点,您可以关闭相框。 – Aaron