3

ここにはかなり基本的な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);
    }
}
4

1 に答える 1

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たとえば、フレームにaを入れてテキストフィールドにフォーカスを合わせると、どうなるかはまだわかりません。それによって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 );
  }
}

これにより、フレーム内の異なるテキストフィールド間でフォーカスを切り替えることができます。

于 2012-11-17T20:42:21.243 に答える