为什么我的 JPopupMenu 没有调用 componentHidden?

发布于 2024-09-05 21:39:39 字数 1147 浏览 1 评论 0原文

我希望在我的 JPopupMenu 隐藏时收到通知 - 无论是因为选择了某个项目、菜单被关闭,还是因为调用了 setVisible(false) 。这是我的测试代码:

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

public class A extends ComponentAdapter implements Runnable, ActionListener {
    private JButton b;

    public static void main(String[] args) {
        EventQueue.invokeLater(new A());
    }

    public void run() {
        JFrame f = new JFrame("Test");
        b = new JButton("Click me");
        b.addActionListener(this);
        f.add(b);
        f.pack();
        f.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        JPopupMenu pm = new JPopupMenu();
        pm.addComponentListener(this);
        pm.add("Popup...");
        pm.add("...menu!");
        pm.show(b, 10, 10);
    }

    public void componentShown(ComponentEvent e) { System.out.println("componentShown"); }
    public void componentHidden(ComponentEvent e) { System.out.println("componentHidden"); }
}

无论我如何与菜单交互,这两个 ComponentListener 方法都不会被调用。这是为什么?是否有不同/更好/正确的方法来找出我的 JPopupMenu 何时隐藏?

谢谢,

卡梅伦

I want to be notified when my JPopupMenu is hidden — whether because an item was selected, the menu was dismissed, or setVisible(false) was called on it. Here is my test code:

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

public class A extends ComponentAdapter implements Runnable, ActionListener {
    private JButton b;

    public static void main(String[] args) {
        EventQueue.invokeLater(new A());
    }

    public void run() {
        JFrame f = new JFrame("Test");
        b = new JButton("Click me");
        b.addActionListener(this);
        f.add(b);
        f.pack();
        f.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        JPopupMenu pm = new JPopupMenu();
        pm.addComponentListener(this);
        pm.add("Popup...");
        pm.add("...menu!");
        pm.show(b, 10, 10);
    }

    public void componentShown(ComponentEvent e) { System.out.println("componentShown"); }
    public void componentHidden(ComponentEvent e) { System.out.println("componentHidden"); }
}

Regardless of how I interact with the menu, neither of the two ComponentListener methods are being called. Why is that? Is there different/better/correct way of finding out when my JPopupMenu is hidden?

Thanks,

Cameron

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

知你几分 2024-09-12 21:39:39

JPopupMenu 有一个用于可见性更改事件的特殊侦听器:

pm.addPopupMenuListener(new PopupMenuListener() {
    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {
        System.out.println("cancelled");
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        System.out.println("vanishing");
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        System.out.println("appearing");
    }
});

但是请注意,正如方法名称所暗示的那样,它们在可见性更改之前调用,因此如果您调用 isVisible () 在事件处理程序中的某个位置,您应该意识到这一点,例如:

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    updateMenu();
}

private void updateMenu() {
    if (!menu.isVisible()) { // this won't work!
        // perform some updates
    }
}

关于为什么 ComponentListener 没有向您发送菜单消失的事件,这可能会解释:

组件隐藏和组件显示事件仅作为调用 Component 的 setVisible 方法的结果而发生。例如,窗口可能会缩小为图标(图标化),而无需组件隐藏事件被触发。

资料来源:ComponentListener 教程(可能不是规范的,但来自马口中。)

考虑与 JPopupMenusetVisible 实现结合起来:

    public void setVisible(boolean b) {
        // Not supported for MenuComponents
    }

您可能知道它是如何发生的,但不知道为什么会发生(什么是理由以及在哪里正确记录?)

JPopupMenu has a special listener for visibility change events:

pm.addPopupMenuListener(new PopupMenuListener() {
    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {
        System.out.println("cancelled");
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        System.out.println("vanishing");
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        System.out.println("appearing");
    }
});

Note, however, as method names hint, they are called before visibility changes, so if you're calling isVisible() somewhere in the event handlers, you should be aware of that, for example:

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    updateMenu();
}

private void updateMenu() {
    if (!menu.isVisible()) { // this won't work!
        // perform some updates
    }
}

With regards to why ComponentListener isn't sending you events on the menu disappearing, this might explain:

The component-hidden and component-shown events occur only as the result of calls to a Component 's setVisible method. For example, a window might be miniaturized into an icon (iconified) without a component-hidden event being fired.

Source: ComponentListener tutorial (non-canonical perhaps, but from the horse's mouth.)

Consider that in conjunction with JPopupMenu's implementation of setVisible:

    public void setVisible(boolean b) {
        // Not supported for MenuComponents
    }

And you might know how it so happens, but not why it happens (what is the justification and where is that properly documented?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文