@Override
	public void viewChanged(FieldPanel fp, BigInteger index, int xPos, int yPos) {
		if (valuesChanging) {
			return;
		}
		try {
			valuesChanging = true;
			// "lockedLineIndex" is the IndexMap index indicating where this field panel 
			// is locked to the other when scrolling.
			BigInteger lockedLineIndex1 = getLockedLineForPanel(fp);
			if (lockedLineIndex1 == null) { // This shouldn't happen.
				throw new AssertException("Couldn't find line number for indicated field panel." +
					" FieldPanel is not one of those being managed by this coordinator.");
			}

			// "topIndex" is the IndexMap index of the top of the listing in view.
			BigInteger topIndex1 = index;
			LayoutModel layoutModel1 = fp.getLayoutModel();
			Layout lockedLineLayout1 = layoutModel1.getLayout(lockedLineIndex1);
			if (lockedLineLayout1 == null) {
				return; // transitioning from one function to another.
			}

			// "lockedLineHeight" is the height of the layout in this field panel 
			// where it is locked to the other panel when scrolling.
			int lockedLineHeight1 = lockedLineLayout1.getHeight();

			// numIndexes is the total number of indexes in this field panels indexMap.
			BigInteger numIndexes1 = layoutModel1.getNumIndexes();
			Layout firstLayout1 = layoutModel1.getLayout(topIndex1);

			// "yPos" is a negative number indicating the number of pixels the start of the current 
			// layout is above the top of the field panel view.

			// "remainingHeight" is the number of pixels vertically from the first visible pixel 
			// in the layout at the top of the listing view to the end of that layout.
			int remainingHeight = firstLayout1.getHeight() + yPos;

			// "offsetInLayout" is the number of pixels that the top of the listing view is below
			// the start of the current layout.
			int offsetInLayout1 = 0;
			int offsetFromLockedIndex1 = 0;
			if (lockedLineIndex1.compareTo(topIndex1) == 0) {
				offsetInLayout1 -= yPos;
				offsetFromLockedIndex1 += offsetInLayout1;
			}
			else if (lockedLineIndex1.compareTo(topIndex1) < 0) {
				BigInteger currentIndex1 = lockedLineIndex1;
				while (currentIndex1 != null && (currentIndex1.compareTo(numIndexes1) < 0) &&
					currentIndex1.compareTo(topIndex1) < 0) {
					Layout currentLayout = layoutModel1.getLayout(currentIndex1);
					if (currentLayout != null) {
						offsetFromLockedIndex1 += currentLayout.getHeight();
					}
					currentIndex1 = layoutModel1.getIndexAfter(currentIndex1);
				}
				offsetFromLockedIndex1 -= yPos;
			}
			else { // lockedlineIndex1 > topIndex1
				BigInteger currentIndex1 = layoutModel1.getIndexAfter(topIndex1);
				while (currentIndex1 != null && (currentIndex1.compareTo(numIndexes1) < 0) &&
					currentIndex1.compareTo(lockedLineIndex1) < 0) {
					Layout currentLayout = layoutModel1.getLayout(currentIndex1);
					if (currentLayout != null) {
						offsetFromLockedIndex1 -= currentLayout.getHeight();
					}
					currentIndex1 = layoutModel1.getIndexAfter(currentIndex1);
				}
				offsetFromLockedIndex1 -= remainingHeight;
			}

			// Position the views for the other panels to match the changed one the best they can.
			for (int i = 0; i < panels.length; i++) {
				if (panels[i] != fp) {
					// Get the difference in height between our two line locked layouts.
					LayoutModel layoutModel2 = panels[i].getLayoutModel();
					BigInteger numIndexes2 = layoutModel2.getNumIndexes();
					BigInteger lockedLineIndex2 = lockedLineNumbers[i];
					Layout lockedLineLayout2 = layoutModel2.getLayout(lockedLineIndex2);
					if (lockedLineLayout2 == null) {
						return; // Initializing panels.
					}
					int lockedLineHeight2 = lockedLineLayout2.getHeight();

					// Handle when the locked line's layout is at the top of the viewer.
					if (lockedLineIndex1.equals(topIndex1)) {
						int difference = lockedLineHeight1 - lockedLineHeight2; // positive means layout1 is larger.
						int yPos2 = yPos + difference;
						// A negative yPos indicates the number of pixels to move the layout
						// above the top of the view.
						panels[i].setViewerPosition(lockedLineIndex2, xPos, yPos2);
						return;
					}

					// Start with the layout of the line locked index and position the top of the 
					// view at the same distance from it as the other view is from the layout for
					// its locked line.
					int offsetFromLockedIndex2 =
						offsetFromLockedIndex1 + (lockedLineHeight2 - lockedLineHeight1);
					int remainingOffset2 = offsetFromLockedIndex2;
					BigInteger currentIndex2 = lockedLineIndex2;
					if (remainingOffset2 < 0) {
						currentIndex2 = layoutModel2.getIndexBefore(currentIndex2);
					}
					while (currentIndex2 != null && currentIndex2.compareTo(BigInteger.ZERO) >= 0 &&
						currentIndex2.compareTo(numIndexes2) < 0) {
						Layout currentLayout2 = layoutModel2.getLayout(currentIndex2);
						// Gaps in the code will cause the currentIndex to be the last byte's 
						// index before the gap. This results in a null layout for that index, 
						// so we need to go again to get past it.
						if (currentLayout2 == null) {
							if (remainingOffset2 < 0) {
								// Go again when processing layout heights in reverse direction.
								currentIndex2 = layoutModel2.getIndexBefore(currentIndex2);
								continue;
							}
							else if (remainingOffset2 > 0) {
								// Go again when processing layout heights in forward direction.
								currentIndex2 = layoutModel2.getIndexAfter(currentIndex2);
								continue;
							}
							return; // currentLayout2 is null.
						}
						int height = currentLayout2.getHeight();
						if (remainingOffset2 == 0) {
							panels[i].setViewerPosition(currentIndex2, xPos, 0);
							return;
						}
						else if (remainingOffset2 < 0) {
							int offset = height + remainingOffset2;
							if (offset >= 0) {
								panels[i].setViewerPosition(currentIndex2, xPos, -offset);
								return;
							}
							currentIndex2 = layoutModel2.getIndexBefore(currentIndex2);
							remainingOffset2 = offset;
						}
						else { // remainingOffset2 > 0
							if (remainingOffset2 < height) {
								panels[i].setViewerPosition(currentIndex2, xPos, -remainingOffset2);
								return;
							}
							currentIndex2 = layoutModel2.getIndexAfter(currentIndex2);
							remainingOffset2 -= height;
						}
					}
				}
			}
		}
		finally {
			valuesChanging = false;
		}
	}
Constructor for the coordinator.
@param panels the field panels that will have their positions coordinated with each other.
Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/internal/LayoutLockedFieldPanelCoordinator.java