如何将mouseListener添加到jscrollbar?

时间:2015-06-18 23:10:40

标签: java swing mouse mouselistener jscrollbar

我有mouseEntered和mouseExited事件导致jPanel内容发生变化,这会改变jPanel的大小。在mouseEntered上,内容增长并可滚动。在mouseExited上,内容缩小并且不可滚动。

问题是将鼠标悬停在滚动条上会触发jPanel的mouseExited事件,因此当用户想要拖动滚动条的旋钮时,它们会在点击它时消失。

如果我可以在滚动条本身添加一个mouseListener,我想我可以防止内容缩小。但我从未在滚动条中添加mouseListener。如何通过滚动条触发mouseEntered / Exited上的事件?

2 个答案:

答案 0 :(得分:0)

是的,您可以将mouseListener附加到滚动条。当你的内容在mouseEntered / mouseExited WRT a jPanel上发生变化时,这是必要的,因为将鼠标悬停在jPanel的滚动条上会触发mouseExited。您必须实现2个方面,以保持内容,就像您在jPanel上盘旋一样:mouseEntered / mouseExited和mouseClicked / mouseReleased。这样做的原因是,当拖动滚动条的旋钮时,鼠标可以悬停在滚动条上,并且您不希望内容在滚动中滚动。

您需要做的就是将侦听器直接添加到滚动条:

myscrollbar.addMouseListener(new MouseAdapter() {

        @Override
        public void mouseEntered(MouseEvent e) {
            if(overScrollOffTimer != null) {
                overScrollOffTimer.stop();
                overScrollOffTimer = null;
            }
            mymodel.setOverScrollbar(true);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            if(overScrollOffTimer == null) {
                overScrollOffTimer = new Timer(250,
                        overScrollOffListener);
                overScrollOffTimer.start();
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
            if(activeScrollOffTimer != null) {
                activeScrollOffTimer.stop();
                activeScrollOffTimer = null;
            }
            mymodel.setBeingScrolled(true);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if(activeScrollOffTimer == null) {
                activeScrollOffTimer =
                    new Timer(250,
                              activeScrollOffListener);
                activeScrollOffTimer.start();
            }
        }
    });

在我的mouseListener中,我添加了2个启动jPanel内容更改的计时器(250ms之后)(加上jPanel悬停的第三个计时器)。如果没有计时器,当您从面板悬停到滚动条或返回时,内容可能会出现视觉上的打嗝。一个计时器在mouseExit上从滚动条启动。另一个在mouse重新启动滚动条旋钮时启动。我一直跟踪鼠标是否在滚动条上,移动滚动条以及鼠标是否在jPanel上。如果这些事情都是真的,我会展示我的大量内容。否则,如果它们都是假的,我会画出我的小内容。

以下是计时器的示例:

private javax.swing.Timer overScrollOffTimer;
ActionListener overScrollOffListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        if(evt.getSource() == overScrollOffTimer) {
            /* Stop timer */
            overScrollOffTimer.stop();
            overScrollOffTimer = null;

            mymodel.setOverScrollbar(false);
            mymodel.notifyObservers();
            revalidate();
            repaint();
        }
    }
};

private javax.swing.Timer activeScrollOffTimer;
ActionListener activeScrollOffListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        if (evt.getSource() == activeScrollOffTimer) {
            /* Stop timer */
            activeScrollOffTimer.stop();
            activeScrollOffTimer = null;

            mymodel.setBeingScrolled(false);
            mymodel.notifyObservers();
            revalidate();
            repaint();
        }
    }
};

我没有为jPanel包含计时器或鼠标监听器,但是没有点击/释放的方法也是类似的努力。

注意,我跟踪了悬停状态和模型中的滚动状态,因为其他jPanel也会根据此悬停交互显示不同的内容,并且他们都可以访问模型。

顺便说一下,我使用的是" OffTimer"," OffListener"等等,因为我基本上只在悬停在一组面板上时显示真实内容。将这些面板中的任何一个悬停掉都会导致内容消失。我希望内容消失的原因是因为当您将鼠标悬停在内容上时内容会发生变化,我不希望用户对静态不动的内容感到困惑,并导致他们做出不正确的视觉结论(例如关联视觉对齐的数据) 2个面板,其对齐方式根据悬停位置而变化。)

答案 1 :(得分:0)

为什么不将滚动窗格放在另一个JPanel中,而是在该外部窗格上添加侦听器。然后进入滚动条不会触发mouseExited事件;只有在您滚动滚动条(退出外部面板)或滚动面板的另一个方向外,它才会被触发。