/** @return A list of the settable fields. */ public static List<Field> getSettableFields() { // Init the search in the root package. Reflections reflections = new Reflections("org.saucistophe", new FieldAnnotationsScanner()); Set<Field> annotatedFields = reflections.getFieldsAnnotatedWith(SettingsField.class); // Turn the set to a list to sort it. List<Field> fieldsList = new ArrayList<>(annotatedFields); fieldsList.sort( (Field field1, Field field2) -> { // Retrieve the fields info. SettingsField fieldInfo1 = field1.getAnnotation(SettingsField.class); SettingsField fieldInfo2 = field2.getAnnotation(SettingsField.class); // If the name wasn't set, get the field's declared name. String actualName1 = fieldInfo1.name().isEmpty() ? field1.getName() : fieldInfo1.name(); String actualName2 = fieldInfo2.name().isEmpty() ? field2.getName() : fieldInfo2.name(); // Elaborate a sortable string representation. String sortableString1 = fieldInfo1.category() + "." + actualName1; String sortableString2 = fieldInfo2.category() + "." + actualName2; return sortableString1.compareTo(sortableString2); }); return fieldsList; }