2012-11-17 55 views
2

我在这里有一个相当基本的JFrame,当用户在外面点击时我想让窗口自动关闭。当用户在外面点击时是否可以关闭窗口(通过某种方式检测窗口外的点击?)。在外部点击时自动关闭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); 
    } 
} 
+1

我希望这是与我的问题有关:http://stackoverflow.com/questions/5717716/detecting-focus-on-frame-components-in-swing –

+0

其实这个问题包含你需要的确切答案.. –

+0

这不适用于所有情况,但是一旦它失去焦点,您可以关闭相框。 – Aaron

回答

6

检测帧外的点击很困难,因为它可以是任何其他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); 
    } 
} 

这允许在帧中的不同的文本字段之间切换焦点。

+1

你可以使用WindowListener#windowDeactivated或WindowFocusListener#windowLostFocus – MadProgrammer

+0

@MadProgrammer是的,其次,但你必须小心所拥有的JDialog(因为你必须使用FocusListener)。 –

相关问题