如何在不破坏其默认实现的情况下为JPanel实现MouseWheelListener? [英] How to implement MouseWheelListener for JPanel without breaking its default implementation?

查看:114
本文介绍了如何在不破坏其默认实现的情况下为JPanel实现MouseWheelListener?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Simply; I have a JPanel inside a JScrollPane;

符合预期;默认情况下,JScrollPane会收听MouseWheelEvent,因此滚动轮旋转时以及光标悬停在JPanel上时滚动效果都很好.

As expected; JScrollPane by default listens to MouseWheelEvent so that scrolling is working well for when the wheel is rotating and while the cursor is hovering over the JPanel.

但是之后;我刚刚更新了JPanel,以便它实现MouseWheelListener,并为JPanel本身添加了此鼠标滚轮侦听器.

But After that; I just updated JPanel so that it implements MouseWheelListener, and I added this mouse wheel listener for the 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");
        }
    }
}

JPanel在两个都响应此实现时;按下 Ctrl ,并且轮子在旋转,并且光标悬停在JPanel上.但是JScrollPane的默认行为意外丢失了!!!

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的滚动没有响应!

When I rotate the wheel while the cursor is hovering over the JPanel the scrolls of the JScrollPane is not responding!!!

似乎; MouseWheelListener的此实现破坏了JPanel的默认值.

It seems that; this implementation of MouseWheelListener breaks the default of a JPanel.

所以;如何在不破坏其默认实现的情况下为JPanel实现MouseWheelListener?

So; How to implement MouseWheelListener for JPanel without breaking its default implementation?

推荐答案

MouseWheelEvents和滚动行为有一些细微的警告.

MouseWheelEvents and the scrolling behavior have some subtle caveats.

例如,当您打开此页面(我指的是您当前正在阅读的页面),将鼠标放在中间,然后开始用滚轮向下滚动时,您将在代码段上滚动.请注意,尽管代码段包含在具有滚动条的代码块中,但不断旋转鼠标滚轮将不会触发滚动在代码段中,但仅在整个页面中.但是,当您一次将鼠标移动到内部代码块中并随后滚动鼠标滚轮时,您将在代码中滚动仅阻止-而不阻止整个页面.

For example, when you open this page (I mean THIS one, which you are currently reading), place the mouse in the middle, and start srolling down with the wheel, you will scroll over the code snippets. Note that although the code snippets are contained in code blocks that have a scrollbar, continuously rotating the mouse wheel will not trigger a scrolling in the code blocks, but only in the whole page. But when you once move the mouse while it is inside a code block, and afterwards roll the mouse wheel, then you will scroll in the code block only - and not the whole page.

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

Similarly, rotating the mouse wheel may not affect the hovered scrollable. I think it depends on the Window Manager and the Look & Feel, but in some cases, you will scroll the scroll pane that contains the focussed component - even if the mouse cursor is outside of this component, and even if it is over a scollable component (you can also observe this, for example, in the Windows Explorer)!

但是,其中一些机制和微妙之处也可以在Swing组件中找到.例如,

However, some of these mechanisms and subtleties can be found in the Swing components as well. For example, the redispatching mechanism that passes MouseWheelEvents to the ancestors if they are not handled by the component itself.

遵循此模式,可以找到一种解决方案(概念上类似于 LuxxMiner提出的解决方案,但可能有点麻烦更通用)可能只是将MouseWheelEvent重新分配给父组件:

Following this pattern, a solution (that is conceptually similar to the one that LuxxMiner proposed, but may be a tad more generic) may be to simply re-dispatch the MouseWheelEvent to the parent component:

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

    }
}

这篇关于如何在不破坏其默认实现的情况下为JPanel实现MouseWheelListener?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆