如何在不破坏 JPanel 的默认实现的情况下实现 MouseWheelListener?

2024-01-01

简单地;我有一个JPanel里面一个JScrollPane;

正如预期的那样;JScrollPane默认听MouseWheelEvent这样,当滚轮旋转且光标悬停在滚动条上时,滚动效果很好JPanel.

But在那之后;我刚刚更新了JPanel以便它实现MouseWheelListener,我添加了这个鼠标滚轮监听器JPanel itself.

@Override
public void mouseWheelMoved(MouseWheelEvent e) {
    if (e.isControlDown()) {
        if (e.getWheelRotation() < 0) {
            System.out.println("mouse wheel Up");
        } else {
            System.out.println("mouse wheel Down");
        }
    }
}

The JPanel responds to this implementation for when both; the Ctrl is pressed down and the wheel is rotating and while the cursor is hovering over the JPanel. But the default behaviour of the JScrollPane is unexpectedly lost!!!

当我旋转滚轮而光标悬停在JPanel的卷轴JScrollPane没有回应!!!

看起来;这个实施MouseWheelListener打破了默认的JPanel.

所以;如何实施MouseWheelListener for JPanel而不破坏其默认实现?


MouseWheelEvents并且滚动行为有一些微妙的警告。

例如,当您打开此页面(我的意思是您当前正在阅读的这个页面)时,将鼠标放在中间,然后开始向下滚动滚轮,您将滚动代码片段。注意although代码片段包含在代码块中有一个滚动条,连续转动鼠标滚轮会not触发滚动in代码块,但仅限于整个页面。但当你有一次move鼠标当前位置inside一个代码块,以及然后滚动鼠标滚轮,然后您将仅在代码块中滚动 - 并且not整个页面。

同样,旋转鼠标滚轮可能不会影响悬停滚动。我认为这取决于窗口管理器和外观和感觉,但在某些情况下,您会滚动包含焦点组件的滚动窗格- 即使鼠标光标位于该组件之外,并且即使它位于可伸缩组件上方(您也可以观察到这一点,例如,在 Windows 资源管理器中)!


然而,其中一些机制和微妙之处也可以在 Swing 组件中找到。例如,重调度机制 http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/3e95aadb479f/src/share/classes/java/awt/Component.java#l4762通过MouseWheelEvents如果组件本身不处理它们,则传递给祖先。

遵循这种模式,解决方案(概念上类似于LuxxMiner 提出的 https://stackoverflow.com/a/35259298/3182664,但可能更通用)可能只是简单地重新调度MouseWheelEvent到父组件:

package stackoverflow;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

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

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.getContentPane().setLayout(new GridLayout(1,2));

        MouseWheelListenerPanel m = new MouseWheelListenerPanel();
        m.setPreferredSize(new Dimension(100,4000));
        JScrollPane scrollPane = new JScrollPane(m);
        f.getContentPane().add(scrollPane);

        f.setSize(500,500);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class MouseWheelListenerPanel extends JPanel implements MouseWheelListener
{
    MouseWheelListenerPanel()
    {
        addMouseWheelListener(this);
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e)
    {
        if (e.isControlDown())
        {
            if (e.getWheelRotation() < 0)
            {
                System.out.println("mouse wheel Up");
            }
            else
            {
                System.out.println("mouse wheel Down");
            }
        }
        else
        {
            getParent().dispatchEvent(e);
        }

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在不破坏 JPanel 的默认实现的情况下实现 MouseWheelListener? 的相关文章

随机推荐