public Field getField(BigInteger index) {
		if (indexMap == null) {
			return null;
		}
		// translate index to block and offset into the block
		ByteBlockInfo info = indexMap.getBlockInfo(index, fieldOffset);
		if (info == null) {
			if (indexMap.isBlockSeparatorIndex(index)) {
				ByteField bf = new ByteField(noValueStr, fm, startX, width, false, fieldOffset,
					index, highlightFactory);
				bf.setForeground(separatorColor);
				return bf;
			}
			return null;
		}
		try {
			ByteBlock block = info.getBlock();
			BigInteger offset = info.getOffset();

			if (!block.hasValue(offset)) {
				// if the ByteBlock doesn't have initialized values at the offset, don't try to read
				// as it causes visual slowness when exceptions are thrown and caught.
				// The following line is the same as the catch (ByteBlockAccessException) handler.
				return getByteField(readErrorStr, index);
			}
			String str = model.getDataRepresentation(block, offset);
			ByteField bf =
				new ByteField(str, fm, startX, width, false, fieldOffset, index, highlightFactory);
			if (blockSet.isChanged(block, offset, unitByteSize)) {
				bf.setForeground(editColor);
			}
			return bf;
		}
		catch (ByteBlockAccessException e) {
			// usually caused by unInitialized memory block
			return getByteField(readErrorStr, index);
		}
		catch (AddressOutOfBoundsException e) {
			return getByteField(noValueStr, index);
		}
		catch (IndexOutOfBoundsException e) {
			return getByteField(noValueStr, index);
		}
	}
Gets a Field object for the given index.
This method is called for the given index and the fieldOffset
that is defined in the constructor.
Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/FieldFactory.java