简体   繁体   English

如何将mouseListener添加到jscrollbar?

[英]How do you add a mouseListener to a jscrollbar?

I have mouseEntered and mouseExited events that cause jPanel content to change which changes the size of the jPanel. 我有mouseEntered和mouseExited事件,这些事件会导致jPanel内容更改,从而更改jPanel的大小。 Upon mouseEntered, the content grows and is scrollable. 鼠标进入后,内容会增长并且可以滚动。 Upon mouseExited, the content shrinks and is not scrollable. mouseExited后,内容将缩小并且不可滚动。

The problem is that hovering the mouse over the scrollbar triggers the mouseExited event from the jPanel, so when the user wants to drag the scrollbar's knob, it disappears when they go to click on it. 问题在于,将鼠标悬停在滚动条上会触发jPanel中的mouseExited事件,因此,当用户要拖动滚动条的旋钮时,鼠标单击时它就会消失。

If I could add a mouseListener to the scrollbar itself, I imagine I could keep the content from shrinking. 如果我可以将mouseListener添加到滚动条本身,那么我可以防止内容缩水。 But I've never added a mouseListener to a scrollbar. 但是我从未将mouseListener添加到滚动条中。 How can I trigger an event on mouseEntered/Exited over a scrollbar? 如何通过滚动条在mouseEntered / exited上触发事件?

Yes, you can attach a mouseListener to a scrollbar. 是的,您可以将mouseListener附加到滚动条。 It's necessary when your content changes on mouseEntered/mouseExited WRT a jPanel because hovering over the jPanel's scrollbar triggers mouseExited. 当jPanel的mouseEntered / mouseExited WRT上的内容更改时,这是必要的,因为将鼠标悬停在jPanel的滚动条上会触发mouseExited。 You must implement 2 aspects in order to keep the content as if you were hovered over the jPanel: mouseEntered/mouseExited and mouseClicked/mouseReleased. 您必须实现2个方面,才能像将鼠标悬停在jPanel上一样保留内容:mouseEntered / mouseExited和mouseClicked / mouseReleased。 The reason for this is because the mouse can hover off the scrollbar when the scrollbar's knob is being dragged, and you don't want the content to change mid-scroll. 这样做的原因是因为在拖动滚动条的旋钮时鼠标可以将鼠标悬停在滚动条上,并且您不希望内容在中间滚动时更改。

All you need to do is, add the listener directly to the scrollbar: 您需要做的就是将侦听器直接添加到滚动条:

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

In my mouseListener, I added 2 timers that initiated the change of the jPanel content (after 250ms) (plus a third timer for the jPanel hover). 在我的mouseListener中,我添加了2个计时器(在250ms之后)启动了jPanel内容的更改(另外还有一个用于jPanel悬停的计时器)。 Without the timers, the content can visually hiccup as you hover from the panel to the scrollbar or back. 如果没有计时器,当您从面板悬停到滚动条或后退时,内容可能会在视觉上打h。 One timer started on mouseExited from the scrollbar. 从滚动条上的mouseExit启动了一个计时器。 The other started when mouseReleased the scrollbar knob. 另一个在鼠标松开滚动条旋钮时启动。 I kept track of whether either the mouse was over the scrollbar, moving the scrollbar, and whether the mouse was over the jPanel. 我一直跟踪鼠标是否在滚动条上方,移动滚动条以及鼠标是否在jPanel上方。 If any of those things was true, I displayed my large content. 如果其中任何一个是正确的,那么我展示了我的大量内容。 Otherwise, if they were all false, I would draw my small content. 否则,如果它们全都是假的,我会画一些小内容。

Here is an example of the timers: 这是计时器的示例:

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

I have not included the timer or mouse listener for the jPanel, but it's a similar endeavor without the clicked/released methods. 我没有为jPanel包括计时器或鼠标侦听器,但是没有单击/释放方法,这是类似的尝试。

Note, I tracked the status of the hover and the scrolling in the model because other jPanels display different content based on this hover interaction as well and they all have access to the model. 注意,我跟踪了悬停状态和模型中的滚动,因为其他jPanels也基于此悬停交互显示了不同的内容,并且它们都可以访问模型。

BTW, I used the terms "OffTimer", "OffListener", etc. because I'm basically only showing real content on hover over a set of panels. 顺便说一句,我使用了“ OffTimer”,“ OffListener”等术语,因为我基本上只是在将鼠标悬停在一组面板上时才显示真实内容。 Hovering off any of these panels basically causes the content to disappear. 将鼠标悬停在任何这些面板上基本上都会导致内容消失。 The reason I want the content to disappear is because the content changes as you hover over it and I don't want the user to be confused by static unmoving content and lead them to make incorrect visual conclusions (eg associate visually aligned data in 2 panels whose alignment changes based on hover position). 我希望内容消失的原因是,当您将鼠标悬停在内容上时内容会发生变化,并且我不希望用户被静态的固定内容所迷惑并导致他们做出不正确的视觉结论(例如,将视觉对齐的数据关联到2个面板中其对齐方式会根据悬停位置发生变化)。

Why not place the scroll pane inside another JPanel, and add the listener on that external pane instead. 为什么不将滚动窗格放在另一个JPanel内,然后在该外部窗格上添加侦听器。 Then moving into the scrollbar will not trigger a mouseExited event; 然后进入滚动条将不会触发mouseExited事件; it will be triggered only when you go PAST the scrollbar (exiting the outer panel) or outside the scrolled panel in another direction. 仅当您向前滚动滚动条(退出外部面板)或在另一个方向上滚动面板的外部时,才触发它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM