首页 > 解决方案 > 如何使 JMenu 的 FocusEvent 不是临时的?

问题描述

在 Java Swing 中,来自 JMenu 的 FocusEvent 是一种临时类型。当我们在 focusLost() 方法中检查 e.isTempoary() 时,结果为真。我们如何覆盖此默认行为以使其返回 false?

例如,我有一个带有文本字段、菜单和按钮的小程序。文本字段显示默认值 30。文本字段是一个 FocusListener,在其 focusLost 方法中,它将检查 e.isTemporary 是否为真。如果为真,则什么都没有,否则,将显示默认值。

程序运行后,您可以将默认值更改为您想要的任何值。然后当您单击按钮时,默认值将返回。但是当您更改默认值后单击菜单时,默认值将不会恢复。原因是菜单中的 FocusEvent 是一个临时事件。我们怎样才能让它永久化?

运行程序是这样的:

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class MenuLookDemo
{
    JPanel panel;
    JScrollPane scrollPane;
    int value = 30;

    public JMenuBar createMenuBar()
    {
        JMenuBar menuBar;
        JMenu menu, submenu;
        JMenuItem menuItem;

        menuBar = new JMenuBar();

        menu = new JMenu("A Menu");
        menuBar.add(menu);

        menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T);

        return menuBar;
    }

    public Container createContentPane()
    {
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setOpaque(true);

        panel = new JPanel();

        JTextField txtTest = new JTextField("" + value);
        txtTest.setPreferredSize(new Dimension(60, 30));
        panel.add(txtTest);

        txtTest.addFocusListener(new FocusListener()
        {
            @Override
            public void focusLost(FocusEvent e)
            {
                System.out.println("focusLost: called isTemporary()=" + e.isTemporary());
                if (e.isTemporary())
                {
                    return;
                }
                System.out.println("focusLost: show value");
                txtTest.setText("" + value);
            }

            @Override
            public void focusGained(FocusEvent e)
            {
                System.out.println("focusGained:");
            }
        });

        JButton btnTest = new JButton("Click Me");
        panel.add(btnTest);
        scrollPane = new JScrollPane(panel);
        contentPane.add(scrollPane, BorderLayout.CENTER);

        return contentPane;
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("MenuLookDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        MenuLookDemo demo = new MenuLookDemo();
        frame.setJMenuBar(demo.createMenuBar());
        frame.setContentPane(demo.createContentPane());

        frame.setSize(450, 260);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                MenuLookDemo.createAndShowGUI();
            }
        });
    }
}

编辑:

我需要单击菜单时在 JTextField 中恢复默认值的结果。这是来自一个大项目,我还有其他一些需要 isTemporay() 检查的案例。

标签: javaswing

解决方案


推荐阅读