@Override
	public void stateChanged(ChangeEvent e) {

		if (mouseDown) {

			try {
				long filePosition = getFilePosition(getValue() - 1);
				int sliderRow = model.getRowForBytePos(filePosition);
				int lastLineRow = model.getRowForBytePos(reader.getFileSize() - 1);
				int numRowsVisible = viewportUtility.getNumRowsInViewport();

				// This is a special check for when the user has scrolled to the end of the
				// file. In this case, we don't want to continue moving the viewport once the
				// last row has become visible at the bottom. To ensure that this happens, we check
				// to see that: 
				// 		1) The last line in the file is in the table
				//		2) The last line is in the visible portion of the viewport
				//
				// If both conditions are met, we just automatically load the bottom
				// of the file and view that in the viewport.
				if (lastLineRow != -1) {
					if (lastLineRow - sliderRow < numRowsVisible) {
						FVEvent scrollEndEvt = new FVEvent(EventType.SCROLL_END, false);
						eventListener.send(scrollEndEvt);
						return;
					}
				}
			}
			catch (IOException e1) {
				Msg.error(this, e1);
			}

			long filePosition = getFilePosition(getValue() - 1);

			FVEvent tailOffEvt = new FVEvent(EventType.SCROLL_LOCK_ON, null);
			eventListener.send(tailOffEvt);
				
			FVEvent sliderChangedEvt = new FVEvent(EventType.SLIDER_CHANGED, filePosition);
			eventListener.send(sliderChangedEvt);

			previousSliderValue = getValue();
		}
	}
Invoked when the slider value has changed. When this happens we need to update the 
viewport to match, but ONLY if this event is triggered as a result of the user 
manually moving the slider (and not as a result of the slider being moved programmatically
in response to a viewport change).
Ghidra/Framework/Project/src/main/java/ghidra/framework/main/logviewer/ui/FVSlider.java