首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何知道何时显示JMenuItem?添加ComponentListener和使用componentShown不起作用

我如何知道何时显示JMenuItem?添加ComponentListener和使用componentShown不起作用
EN

Stack Overflow用户
提问于 2021-09-11 15:59:27
回答 2查看 63关注 0票数 2

下面是一个完整的编译,运行失败的例子,说明我的问题。JMenuItem扩展了JComponent。当添加到JPopupMenu并显示在上下文菜单中时.它是..。好吧..。显示,但不调用componentShown方法。我如何知道何时显示JMenuItem?我需要从JMenuItem内部知道。我正在创建这个JMenuItem并将其交给一个更大的框架。我不了解或控制JPopupMenu,容器,或任何其他组件。当显示我的JMenuItem时,我必须根据应用程序的上下文和当前状态更新它的文本。我怎么知道是什么时候展示的?

在下面的示例中,文本“显示的组件”在任何情况下都不会被打印。在JPanel中右键单击获取上下文菜单,您将看到JMenuItem文本“应答Hi",但现在输出到控制台。

我正在运行macOS 11.5.2BigSur和JDK11.0.6LTS(来自甲骨文)。

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JMenuItemListeners {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.setMinimumSize(new Dimension(800, 600));
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel("Hello World... right click me."),
                BorderLayout.CENTER);
        //========================================
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItem = new JMenuItem("Reply Hi");
        menuItem.addComponentListener(
        new ComponentListener() {
            @Override
            public void componentResized(ComponentEvent e) {}
            @Override
            public void componentMoved(ComponentEvent e) {}
            @Override
            public void componentShown(ComponentEvent e) {
                System.out.println("component shown");
            }
            @Override
            public void componentHidden(ComponentEvent e) {}
        }
                );
        popupMenu.add(menuItem);
        panel.setComponentPopupMenu(popupMenu);
        //========================================
        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
EN

回答 2

Stack Overflow用户

发布于 2021-09-11 19:47:24

您可以使用AncestorListener

代码语言:javascript
复制
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class JMenuItemListeners {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.setMinimumSize(new Dimension(800, 600));
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel("Hello World... right click me."),
                BorderLayout.CENTER);
        //========================================
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItem = new JMenuItem("Reply Hi");

        menuItem.addAncestorListener(new AncestorListener()
        {
            @Override
            public void ancestorRemoved(AncestorEvent e) {}
            @Override
            public void ancestorMoved(AncestorEvent e) {}
            @Override
            public void ancestorAdded(AncestorEvent e) {
                System.out.println("ancestor shown");
            }
        });

        popupMenu.add(menuItem);
        panel.setComponentPopupMenu(popupMenu);
        //========================================
        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-09-11 19:44:04

我认为您不会在显示JMenuItem时找到某种通知的侦听器。

相反,我将尝试将JMenuItem与应用程序的状态分离开来,我将使用javax.swing.AbstractAction来实现这一点。

您可以随时更新应用程序的上下文和/或状态,并在显示AbstractAction时神奇地显示它将反映应用程序的上下文和状态。

下面的代码片段替换了JPopupMenuJMenuItem的创建。第二部分展示了如何通过将AbstractAction转换为时钟来更新JMenuItem

代码语言:javascript
复制
    //========================================
    JPopupMenu popupMenu = new JPopupMenu();
    AbstractAction a = new AbstractAction("Reply Hi") {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Hi");
        }
    };
    JMenuItem menuItem = new JMenuItem(a);
    popupMenu.add(menuItem);
    panel.setComponentPopupMenu(popupMenu);
    //========================================
    Timer t = new Timer(100, (e) -> {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("'Its 'HH:mm:ss");
        a.putValue(Action.NAME, dtf.format(LocalTime.now()));
    });
    t.start();
    //========================================
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69144597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档