JScrollPane and setting knob increment?
Does anyone know of a way to set the increment of a 'knob' drag using JScrollPane? I have a JTextPane that I've added to the JScrollPane and I want any vertical scrolling to be done on a line by line basis. I've set both the unit and block increments to the appropriate value, which allows all vertical scrolling done by the buttons and track to be line by line, however when the knob is dragged it still seems to be pixel by pixel. I would like this feature to be line by line as well...
thanks in advance
You'll have to write your own version of JScrollBar in order to do that. You can listen for adjustment changes and make it 'snap' to the nearest line with a regular JScrollPane, but that won't prevent it from appearing to scroll by pixel, it will merely snap to the nearest line after they let go.
Also, if you go the adjustment listener and 'snap' route be sure you account for the fact that the act of 'snapping' it and changing the value will fire another adjustment listener. I did this with a JTable where I wanted it to snap to the nearest row when they let go and simply had an int member that represented the bar's last known value. Every adjustment, if the value didn't change I didn't care, if it did change I changed mine to meet the new one and then performed the snapping effect.
For the record, I discovered a workaround to be able to scroll by line rather than pixel using the drag knob. I installed an adjustment listener on the vertical scroll bar of the JScrollPane (which displays a JTextPane with a courier font). Seams to work for what I want it to do. Here is the code for my adjustmentValueChanged of AdjustmentListener function
public void adjustmentValueChanged( AdjustmentEvent e ){
JScrollBar bar = (JScrollBar)e.getAdjustable();
if ( bar.getValueIsAdjusting() ){
if ( ( oldValue - e.getValue() ) > fontHeight ){
int numberOfLines = (( oldValue - e.getValue() ) / fontHeight ) ;
bar.setValue( oldValue - (numberOfLines * fontHeight) );
oldValue = (e.getValue() / fontHeight) * fontHeight;
return;
}
else if ( ( oldValue - e.getValue() ) < -fontHeight ){
int numberOfLines = (( oldValue - e.getValue() ) / fontHeight );
bar.setValue( oldValue - (numberOfLines * fontHeight) );
oldValue = ( e.getValue() / fontHeight ) *fontHeight;
return;
}
else if ( ( oldValue - e.getValue() ) % fontHeight == 0 ){
oldValue = e.getValue();
return;
}
bar.setValue( oldValue );
return;
}
else{
if ( ( oldValue - e.getValue() ) % fontHeight == 0 ){
oldValue = e.getValue();
return;
}
}
bar.setValue( oldValue );
}
I did the exact same thing a few months ago and the knob would still drag but the viewport would constantly snap to the value. The end result was when they dragged it, they could drag it anywhere but it would constantly snap to the knob value and then back to the nearest line and create a flickering in the viewport.
Have you tested this in some various look and feels? Wondering if it works on some and not others.
> I did the exact same thing a few months ago and the
> knob would still drag but the viewport would
> constantly snap to the value. The end result was
> when they dragged it, they could drag it anywhere but
> it would constantly snap to the knob value and then
> back to the nearest line and create a flickering in
> the viewport.
>
> Have you tested this in some various look and feels?
> Wondering if it works on some and not others.
I haven't tried it with other LAF. If I get a chance maybe I'll try and see how global this code is.