当你点击其他地方时,如何隐藏Swing Popup

Cas*_*son 12 java swing popup

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

  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);
    }
}
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 11

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

  • 我也能够使用这种方法.它最终变得更加简单.显然,当菜单失去焦点时隐藏的行为仅在您将主框架作为show()方法上的调用者传递时才起作用.如果使用setVisible(true),则无法获得所需的行为. (4认同)
  • 我也经常这样做.只需将JPopupMenu的布局设置为BorderLayout,并使用CENTER约束添加内容.JPopupMenu渲染任意摆动内容没有问题. (2认同)

Noe*_*Ang 6

正如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);
    }
}
Run Code Online (Sandbox Code Playgroud)