JFrame 的 getFocusOwner() 没有帮助

DYS*_*DYS 5 java swing

我正在使用 Swing 程序,但遇到了一些麻烦。该程序有两个窗口(都是 JFrames)。主窗口很好,应该与此问题无关。

我遇到问题的窗口包含一个带有 JPanel 的 JScrollPane,并且有一个 JMenuBar。JPanel 上有一堆 JTextComponents(一些 JTextFields,一些 JTextAreas)。

我想要做的是将 ActionListener 附加到 JMenuItem 找到具有焦点的 JTextComponent。

我在focused component referenceHow to find out which object current has focus 上看过之前的帖子。我的问题是调用特定窗口的getFocusOwner()方法只会返回 JFrame 的JRootPane,这完全没有帮助。有问题的 JScrollPane 和 JPanel 都可以根据它们的isFocusable()方法聚焦。即使我在单击菜单项之前实际将文本输入到 JTextComponent 之一中,也会发生这种情况。当我打开菜单和所有内容时,光标仍然在文本字段中闪烁。对于它的价值,getMostRecentFocusOwner()也简单地返回 JRootPane。

Dav*_*amp 1

我想我已经解决了这个问题,因为当您单击菜单项时您会失去焦点,我们只需等待焦点返回到组件,然后再检查谁拥有焦点,我已经使用摆动计时器完成了此操作等待 100 毫秒,然后执行其方法来检查哪个组件获得焦点:

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
import javax.swing.*;

public class JavaApplication180 extends JFrame {

    private JTextField[] JTextFields;
    private JMenuBar menuBar;
    private JMenu menu;
    private JMenuItem item;

    public JavaApplication180() {
        initComponents();

        createAndShowUI();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JavaApplication180();
            }
        });
    }

    private void createAndShowUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridLayout(2, 2, 10, 10));
        setJMenuBar(menuBar);
        addComponentsToPane();

        pack();
        setVisible(true);
    }

    private void initComponents() {
        JTextFields = new JTextField[4];

        menuBar = new JMenuBar();
        item = new JMenuItem("Who has focus?");
        item.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                TimerTask tt = new TimerTask() {

                    @Override
                    public void run() {
                        JOptionPane.showMessageDialog(null, getMostRecentFocusOwner().getName());
                    }
                };
                new java.util.Timer().schedule(tt, 100);
            }
        });

        menu = new JMenu("File");
        menu.add(item);
        menuBar.add(menu);
    }

    private void addComponentsToPane() {
        for (int i = 0; i < JTextFields.length; i++) {
            JTextFields[i] = new JTextField();
            JTextFields[i].setText(String.valueOf(i));
            JTextFields[i].setName(String.valueOf(i));
            getContentPane().add(JTextFields[i]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)