void restoreFromXML(Element xmlElement) {

		try {
			List<?> children = xmlElement.getChildren(XML_COLUMN);
			List<TableColumn> oldCompleteList = columnModel.getAllColumns();

			if (children.size() != oldCompleteList.size()) {
				// this implies that the available set of columns has changed
				setDefaultColumnsVisible();
				return;
			}

			List<TableColumn> visibleList = new ArrayList<>();
			List<TableColumn> completeList = new ArrayList<>();
			List<Settings> settingsList = new ArrayList<>();

			for (Object object : children) {

				Element element = (Element) object;
				String columnName = element.getAttributeValue(XML_COLUMN_NAME);

				TableColumn column = getColumn(columnName, oldCompleteList);
				if (column == null) {
					setDefaultColumnsVisible();
					return; // dynamic columns can be removed or somehow unavailable
				}

				Attribute widthAttribute = element.getAttribute(XML_COLUMN_WIDTH);
				int width = widthAttribute.getIntValue();

				Attribute visibleAttribute = element.getAttribute(XML_COLUMN_VISIBLE);
				boolean visible = visibleAttribute.getBooleanValue();

				Settings columnSettings = getColumnSettings(element);
				completeList.add(column);

				column.setWidth(width);
				column.setPreferredWidth(width);
				if (visible) {
					SystemUtilities.assertTrue(!visibleList.contains(column),
						"Duplicate columns being added to the visible columns of table: " +
							getTableModelName() + " - column: " + column.getHeaderValue());
					visibleList.add(column);
				}

				settingsList.add(columnSettings);
			}

			columnModel.restoreState(completeList, settingsList, visibleList);

			restoreColumnSortState(xmlElement);

			doSaveState(xmlElement);
		}
		catch (DataConversionException dce) {
			throw new IllegalStateException(
				"Unexpected data format reading saved TableColumn state.");
		}
	}
Gets the most unique identifier possible for a given column.
Ghidra/Framework/Docking/src/main/java/docking/widgets/table/TableColumnModelState.java