【问题标题】:Selectively dispatch events to the children of a popup有选择地将事件分派给弹出窗口的子项
【发布时间】:2020-07-08 05:54:02
【问题描述】:

我正在尝试创建一个摆动弹出窗口,它将所有键盘事件转发到其中的文本字段,并将所有鼠标滚动事件转发到其中的 JScrollPane。我想出了这段代码,它覆盖了一些 processXXXEvent 方法,但是这种覆盖没有任何效果(您必须单击文本字段来键入并将鼠标移到 JScrollPane 上才能滚动它。

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.util.Random;

public class T extends JPanel {

    private final JTextField tf;
    private final JScrollPane sv;

    T() {
        this.tf = new JTextField();
        this.tf.setPreferredSize(new Dimension(100, 30));
        var lv = new JList<String>();
        lv.setListData(new String[] {"A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D"});
        this.sv = new JScrollPane(lv);
        add(this.sv);
        add(this.tf);
    }

    @Override
    protected void processKeyEvent(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            this.setVisible(false);
        } else {
            this.tf.dispatchEvent(e);
        }
    }

    @Override
    protected void processMouseWheelEvent(MouseWheelEvent e) {
        this.sv.dispatchEvent(e);
    }

    static JPopupMenu popup;

    static void showPopup(JFrame frame) {
        popup = new JPopupMenu();
        popup.add(new T());
        popup.show(frame, 0 ,0);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setPreferredSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.GRAY);

        var b = new JButton("CLICK");
        b.setPreferredSize(new Dimension(100, 100));
        b.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                showPopup(frame);
            }
            @Override
            public void mousePressed(MouseEvent mouseEvent) {}
            @Override
            public void mouseReleased(MouseEvent mouseEvent) {}
            @Override
            public void mouseEntered(MouseEvent mouseEvent) {}
            @Override
            public void mouseExited(MouseEvent mouseEvent) {}
        });
        frame.add(b);

        frame.pack();
        frame.setVisible(true);
    }
}

如何实现这种行为?

【问题讨论】:

    标签: java swing user-interface event-handling


    【解决方案1】:

    您的面板既没有实现也没有添加任何KeyListenerMouseWheelListener。因此,您实现的用于覆盖事件处理的方法永远不会被调用。

    这是您的 T 课程的简短 sn-p,应该适合您:

    T() {
        tf = new JTextField();
        tf.setPreferredSize(new Dimension(100, 30));
        JList lv = new JList<String>();
        lv.setListData(new String[] { "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D" });
        sv = new JScrollPane(lv);
        add(sv);
        add(tf);
        setFocusable(true);
        addMouseWheelListener(new MouseAdapter() { // this will react to the scrolling
            public void mouseWheelMoved(MouseWheelEvent e) {
                sv.dispatchEvent(e);
            }
        });
        addKeyListener(new KeyAdapter() { // this reacts to the key strokes
            public void keyTyped(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    popup.setVisible(false);
                } else {
                    tf.dispatchEvent(e);
                }
            }
        });
    }
    

    【讨论】:

    • 我添加了这段代码,滚动按预期工作,但关键事件仍然被忽略。未调用 keyAdapter 方法。
    • @thewolf 尝试在T 类的构造函数中添加setFocusable(true)
    • 是的,正如@Abra 所说,请注意我的sn-p 中的setFocusable(true)KeyAdapter 工作需要它。
    • @maloomeister 它不起作用。这是完整的程序:gist.github.com/fctorial/a83da786d404f3bdeca86f45e869c379
    • 究竟是什么不起作用?我只是拿了你的代码,自己尝试了一下,它完全按照你在问题中描述的那样做。
    猜你喜欢
    • 2022-10-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多