代码之家  ›  专栏  ›  技术社区  ›  0__

JPopupMenu为子帧(JTextField)提供初始焦点,即使超出父帧的边界(权重)

  •  0
  • 0__  · 技术社区  · 6 年前

    我遇到过这样的情况 JTextField 内部 JPopupMenu requestFocus 当弹出菜单超出父帧的边界时。这在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 回复  |  直到 6 年前
        1
  •  0
  •   0__    6 年前

    因此,显式使用未修饰的对话框似乎是可行的:

    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);
        }
    }