JPopupMenu дает начальный фокус дочернему элементу (JTextField), даже когда выходит за пределы родительского фрейма (тяжелый вес) - PullRequest
0 голосов
/ 05 января 2019

У меня есть ситуация, когда JTextField внутри JPopupMenu не получает фокус, несмотря на вызов requestFocus, когда всплывающее меню превышает границы родительского кадра. Это выглядит по-другому (например, Metal) в Linux / Gtk (не уверен, что это связано с платформой). Пример:

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FocusTest implements Runnable {
    public static void main(String[] args) {
        EventQueue.invokeLater(new FocusTest());
    }

    public void run() {
        final JFrame f = new JFrame();
        final JButton invoker = new JButton("Pop");
        final JPopupMenu pop = new JPopupMenu();
        final JTextField text = new JTextField(12);
        pop.add(text);
        pop.pack();
        invoker.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pop.show(invoker, 0, 0);
                System.out.println("here");
                text.requestFocus();
            }
        });
        f.getContentPane().add(invoker);
        f.pack();
        f.setVisible(true);
    }
}

При размере кадра по умолчанию всплывающее окно больше, чем рамка, и фокус не указывается:

enter image description here

Когда окно становится больше, открытие всплывающего окна дает начальный фокус, и я могу начать вводить текстовое поле без взаимодействия с мышью:

enter image description here

Похоже, это связано с тем, что в первом случае всплывающее окно делается тяжелым, а во втором - легким. Например, если я добавлю pop.setLightWeightPopupEnabled(false);, то фокус не будет дан, даже если всплывающее окно содержится внутри родительского фрейма.

Как мне обеспечить фокусировку в любом случае (в том числе для тяжеловесов)?

1 Ответ

0 голосов
/ 05 января 2019

Так что использование недекорированного диалогового окна явно работает:

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FocusTest implements Runnable {
    public static void main(String[] args) {
        EventQueue.invokeLater(new FocusTest());
    }

    public void run() {
        final JFrame f = new JFrame();
        final JButton invoker = new JButton("Pop");
        final JDialog pop = new JDialog();
        pop.setUndecorated(true);
        final JTextField text = new JTextField(12);
        pop.add(text);
        pop.pack();
        invoker.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pop.setLocationRelativeTo(invoker);
                pop.setVisible(true);
            }
        });
        f.getContentPane().add(invoker);
        f.pack();
        f.setVisible(true);
    }
}
...