单击其他位置时如何隐藏 Swing 弹出窗口

2022-09-04 01:14:15

我有一个弹出窗口,当用户单击按钮时显示。我想在发生以下任何事件时隐藏弹出窗口:

  1. 用户单击应用程序中的其他位置。(例如背景面板)
  2. 用户最小化应用程序。

JPopupMenu有这种行为,但我需要的不仅仅是JMenuItems。下面的代码块是演示当前用法的简化图示。

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class PopupTester extends JFrame {
  public static void main(String[] args) {
    final PopupTester popupTester = new PopupTester();
    popupTester.setLayout(new FlowLayout());
    popupTester.setSize(300, 100);
    popupTester.add(new JButton("Click Me") {
      @Override
      protected void fireActionPerformed(ActionEvent event) {
        Point location = getLocationOnScreen();
          int y = (int) (location.getY() + getHeight());
          int x = (int) location.getX();
          JLabel myComponent = new JLabel("Howdy");
          Popup popup = PopupFactory.getSharedInstance().getPopup(popupTester, myComponent, x, y);
          popup.show();
        }
      });
      popupTester.add(new JButton("No Click Me"));
      popupTester.setVisible(true);
      popupTester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

答案 1

使用 JPopupMenu。您可以向其添加任何组件,而不仅仅是菜单项。


答案 2

正如pajton在之前的评论中指出的那样,Popup不是一个可以很容易地绑定到听众的JComponent。但是,正如其文档所述,“Popup的实现负责创建和维护自己的组件,以向用户呈现[其主题]。

因此,在将其用作表示机制时,无论如何,Popup 都必须将自己呈现为实际的 Swing 组件。让它将自己注册到该组件。让它在组件失去焦点时隐藏自身。

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.Popup;

public class PopupTester extends JFrame {
    private static class MessagePopup extends Popup
        implements WindowFocusListener
    {
        private final JDialog dialog;

        public MessagePopup(Frame base, String message) {
            super();
            dialog = new JOptionPane().createDialog( base, "Message" );
            dialog.setModal( false );
            dialog.setContentPane( new JLabel( message ) );
        }
        @Override public void show() {
            dialog.addWindowFocusListener( this );
            dialog.setVisible( true );
        }
        @Override public void hide() {
            dialog.setVisible( false );
            dialog.removeWindowFocusListener( this );
        }
        public void windowGainedFocus( WindowEvent e ) {
            // NO-OP
        }

        public void windowLostFocus( WindowEvent e ) {
            hide();
        }
    }

    public static void main(String[] args) {
    final PopupTester popupTester = new PopupTester();
    popupTester.setLayout(new FlowLayout());
    popupTester.setSize(300, 100);
    popupTester.add(new JButton("Click Me") {
      @Override
      protected void fireActionPerformed(ActionEvent event) {
        Point location = getLocationOnScreen();
          MessagePopup popup = new MessagePopup( popupTester, "Howdy" );
          popup.show();
        }
      });
      popupTester.add(new JButton("No Click Me"));
      popupTester.setVisible(true);
      popupTester.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

推荐