I have a mouse listener attached to a vertical jScrollbar. The horizontal aspect of the content is controlled by hover position. Right now, when the user drags the vertical scrollbar handle, the content scrolls vertically just fine, but they can only see the right-most content (horizontally speaking) because the cursor is off the right side of the jPanel.
What I would like to do is, once the user clicks to drag the vertical scrollbar, I want to allow them to hover the cursor over the content (while the mouse button is down) and have the horizontal position of the content updated.
However, even though I have added an over-ridden mouseDragged function to my jscrollbar's mouse listener to update a manually maintained hover position, it is not getting fired. Here's my code:
getSecondaryScrollBar().addMouseListener(new MouseAdapter() {
...
@Override
public void mouseDragged(final MouseEvent e) {
debug("Hover pixel position during drag: [" + e.getX() + "]",8);
if(e.getX() < 0) {
//Set the hover position to wherever the cursor has wandered to while dragging the secondary scrollbar
map.setHoverIndex(map.getIndex(scrollPane.getViewport().getSize().width + e.getX()));
} else {
//Set the hover position as the far right label
map.setHoverIndex(-1);
}
repaint();
}
});
The debug message does not print upon drag of the scrollbar. The labels are scrolling vertically. I even debugged by adding a breakpoint, so I know mouseDragged is not even getting called. I also tried the mouseMoved function with the same result.
I have an adjustment listener that takes an adjustment event object that handles the vertical dragging of content, but it does not have access to the mouse event getX() function.
I also have mouseDragged and mouseMoved functions as a part of the main class for when the cursor is over the jPanel. They're used for controlling horizontal position and making selections. Both work splendidly:
@Override
public void mouseMoved(final MouseEvent e) {
setHoverPosition(e);
hoverIndex = map.getIndex(getPrimaryHoverPosition(e));
repaint();
}
@Override
public void mouseDragged(final MouseEvent e) {
setHoverPosition(e);
hoverIndex = map.getIndex(getPrimaryHoverPosition(e));
map.setHoverIndex(hoverIndex);
debug("Selecting from " + map.getSelectingStart() + " to " + map.getIndex(getPrimaryHoverPosition(e)),8);
repaint();
}
Finally, here's a screen recording that should clarify what I'm doing in case my description is insufficient:
https://dl.dropboxusercontent.com/u/87939936/StackOverflow/getX_on_scrollbar_drag_question.mov
Does anyone know how to get the cursor position during a drag of the vertical scrollbar?
mouseDragged and mouseMoved (attached to the jscrollbar) are not called during a jscrollbar drag and the AdjustmentEvent object has no way to obtain the cursor position or to get access to an object that can return it either. Therefor you must find the cursor position externally using something like MouseInfo.getPointerInfo().getLocation() (see Get Mouse Position).
Then, to convert that coordinate to be relative to the jPanel, you can use SwingUtilities.convertPointFromScreen().
Here, I have updated the cursor position in an overridden updateBuffer function which then calls its parent to draw everything. Note that, I only update the hover position when the scrollbar is being dragged (e.g. areLabelsBeingScrolled()) which simply returns a boolean that is set to true when the mouse clicks on a scrollbar and set to false when it is released.
@Override
public void updateBuffer(final Graphics g,final Dimension offscreenSize) {
if(areLabelsBeingScrolled()) {
Point p = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(p,getComponent());
debug("Cursor x coordinate relative to column labels: [" + p.x + "]",8);
int hDI = map.getIndex(p.x); //Hover Data Index
if(hDI > map.getMaxIndex()) {
hDI = map.getMaxIndex();
} else if (hDI < 0) {
hDI = 0;
}
map.setHoverIndex(hDI);
}
super.updateBuffer(g,offscreenSize);
}
As you can see from this screen recording, it works quite well:
https://dl.dropboxusercontent.com/u/87939936/StackOverflow/getX_on_scrollbar_drag_answer.mov
Furthermore, to make cursor hovering changes smooth, I use a timer that causes updateBuffer to update continuously during the scrolling period. But that is ancillary to the question, so I won't go into further detail about it.