Unknown 5 yıl önce
ebeveyn
işleme
24133a39ee
21 değiştirilmiş dosya ile 142 ekleme ve 22 silme
  1. 1 1
      gradle.properties
  2. 13 9
      src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java
  3. 12 0
      src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigEntry.java
  4. 0 4
      src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigListEntry.java
  5. 3 3
      src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigScreen.java
  6. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/BooleanToggleBuilder.java
  7. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleFieldBuilder.java
  8. 8 1
      src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleListBuilder.java
  9. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/EnumSelectorBuilder.java
  10. 3 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FieldBuilder.java
  11. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatFieldBuilder.java
  12. 8 1
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatListBuilder.java
  13. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntFieldBuilder.java
  14. 8 1
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntListBuilder.java
  15. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntSliderBuilder.java
  16. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongFieldBuilder.java
  17. 8 1
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongListBuilder.java
  18. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongSliderBuilder.java
  19. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/StringFieldBuilder.java
  20. 8 1
      src/main/java/me/shedaniel/clothconfig2/impl/builders/StringListBuilder.java
  21. 7 0
      src/main/java/me/shedaniel/clothconfig2/impl/builders/TextFieldBuilder.java

+ 1 - 1
gradle.properties

@@ -2,5 +2,5 @@ minecraft_version=1.14.4
 yarn_version=1.14.4+build.8
 fabric_loader_version=0.4.8+build.159
 fabric_version=0.3.0+build.207
-mod_version=0.5.1
+mod_version=0.5.2
 modmenu_version=1.7.6+build.115

+ 13 - 9
src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java

@@ -32,21 +32,25 @@ public class ClothConfigInitializer implements ClientModInitializer {
                         builder.setDefaultBackgroundTexture(new Identifier("minecraft:textures/block/oak_planks.png"));
                         ConfigCategory playZone = builder.getOrCreateCategory("Play Zone");
                         ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
-                        playZone.addEntry(entryBuilder.startBooleanToggle("Simple Boolean", false).buildEntry());
-                        playZone.addEntry(entryBuilder.startStrField("Simple Boolean", "ab").setDefaultValue(() -> "ab").buildEntry());
-                        playZone.addEntry(entryBuilder.startLongSlider("Long Slider", 0, -10, 10).setDefaultValue(() -> 0l).buildEntry());
+                        playZone.addEntry(entryBuilder.startBooleanToggle("Simple Boolean", false).build());
+                        playZone.addEntry(entryBuilder.startStrField("Simple String", "ab").setDefaultValue(() -> "ab").build());
+                        playZone.addEntry(entryBuilder.startLongSlider("Long Slider", 0, -10, 10).setDefaultValue(() -> 0l).build());
                         playZone.addEntry(entryBuilder.startIntList("Int List", Arrays.asList(1, 6, 14, 1414)).setTooltip("this is a bad tooltip").setSaveConsumer(integers -> integers.forEach(System.out::println)).setDefaultValue(Arrays.asList(1, 6, 14, 1414)).build());
                         playZone.addEntry(entryBuilder.startStrList("Party Member List", Arrays.asList("Tim", "Daniel", "John")).setTooltip("A list of party members.").setDefaultValue(Arrays.asList("Tim", "Daniel", "John")).build());
-                        playZone.addEntry(entryBuilder.startIntField("Integer Field", 2).setDefaultValue(() -> 2).setMin(2).setMax(99).buildEntry());
+                        playZone.addEntry(entryBuilder.startIntField("Integer Field", 2).setErrorSupplier(integer -> {
+                            if (integer == 4)
+                                return Optional.of("I hate the number 4 please stop");
+                            return Optional.empty();
+                        }).setDefaultValue(() -> 2).setMin(2).setMax(99).build());
                         SubCategoryBuilder randomCategory = entryBuilder.startSubCategory("Random Sub-Category");
-                        randomCategory.add(entryBuilder.startTextDescription("§7This is a promotional message brought to you by Danielshe. Shop your favorite Lil Tater at store.liltater.com!").setTooltipSupplier(() -> Optional.of(new String[]{"This is an example tooltip."})).buildEntry());
-                        randomCategory.add(entryBuilder.startSubCategory("Sub-Sub-Category", ImmutableList.of(entryBuilder.startEnumSelector("Enum Field No. 1", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).buildEntry(), entryBuilder.startEnumSelector("Enum Field No. 2", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).buildEntry())).buildEntry());
+                        randomCategory.add(entryBuilder.startTextDescription("§7This is a promotional message brought to you by Danielshe. Shop your favorite Lil Tater at store.liltater.com!").setTooltipSupplier(() -> Optional.of(new String[]{"This is an example tooltip."})).build());
+                        randomCategory.add(entryBuilder.startSubCategory("Sub-Sub-Category", ImmutableList.of(entryBuilder.startEnumSelector("Enum Field No. 1", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).build(), entryBuilder.startEnumSelector("Enum Field No. 2", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).build())).build());
                         for(int i = 0; i < 10; i++)
-                            randomCategory.add(entryBuilder.startIntSlider("Integer Slider No. " + (i + 1), 0, -99, 99).buildEntry());
-                        playZone.addEntry(randomCategory.buildEntry());
+                            randomCategory.add(entryBuilder.startIntSlider("Integer Slider No. " + (i + 1), 0, -99, 99).build());
+                        playZone.addEntry(randomCategory.build());
                         ConfigCategory enumZone = builder.getOrCreateCategory("Enum Zone");
                         enumZone.setCategoryBackground(new Identifier("minecraft:textures/block/stone.png"));
-                        enumZone.addEntry(entryBuilder.startEnumSelector("Enum Field", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).buildEntry());
+                        enumZone.addEntry(entryBuilder.startEnumSelector("Enum Field", DemoEnum.class, DemoEnum.CONSTANT_2).setDefaultValue(() -> DemoEnum.CONSTANT_1).build());
                         ConfigCategory partyZone = builder.getOrCreateCategory("Party Zone");
                         MinecraftClient.getInstance().openScreen(builder.build());
                     } catch (Throwable throwable) {

+ 12 - 0
src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigEntry.java

@@ -4,9 +4,11 @@ import me.shedaniel.clothconfig2.gui.ClothConfigScreen;
 import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
 
 import java.util.Optional;
+import java.util.function.Supplier;
 
 public abstract class AbstractConfigEntry<T> extends DynamicElementListWidget.ElementEntry<AbstractConfigEntry<T>> {
     private ClothConfigScreen screen;
+    private Supplier<Optional<String>> errorSupplier;
     
     public abstract boolean isRequiresRestart();
     
@@ -16,6 +18,16 @@ public abstract class AbstractConfigEntry<T> extends DynamicElementListWidget.El
     
     public abstract T getValue();
     
+    public Optional<String> getConfigError() {
+        if (errorSupplier != null && errorSupplier.get().isPresent())
+            return errorSupplier.get();
+        return getError();
+    }
+    
+    public void setErrorSupplier(Supplier<Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+    }
+    
     public Optional<String> getError() {
         return Optional.empty();
     }

+ 0 - 4
src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigListEntry.java

@@ -4,10 +4,6 @@ public abstract class AbstractConfigListEntry<T> extends AbstractConfigEntry<T>
     private String fieldName;
     private boolean editable = true;
     private boolean requiresRestart;
-    //
-    //    public AbstractConfigListEntry(String fieldName) {
-    //        this(fieldName, false);
-    //    }
     
     public AbstractConfigListEntry(String fieldName, boolean requiresRestart) {
         this.fieldName = fieldName;

+ 3 - 3
src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigScreen.java

@@ -202,7 +202,7 @@ public abstract class ClothConfigScreen extends Screen {
                 if (displayErrors)
                     for(List<AbstractConfigEntry> entries : Lists.newArrayList(tabbedEntries.values())) {
                         for(AbstractConfigEntry entry : entries)
-                            if (entry.getError().isPresent()) {
+                            if (entry.getConfigError().isPresent()) {
                                 hasErrors = true;
                                 break;
                             }
@@ -343,8 +343,8 @@ public abstract class ClothConfigScreen extends Screen {
             List<String> errors = Lists.newArrayList();
             for(List<AbstractConfigEntry> entries : Lists.newArrayList(tabbedEntries.values()))
                 for(AbstractConfigEntry entry : entries)
-                    if (entry.getError().isPresent())
-                        errors.add(((Optional<String>) entry.getError()).get());
+                    if (entry.getConfigError().isPresent())
+                        errors.add(((Optional<String>) entry.getConfigError()).get());
             if (errors.size() > 0) {
                 minecraft.getTextureManager().bindTexture(CONFIG_TEX);
                 GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/BooleanToggleBuilder.java

@@ -20,6 +20,11 @@ public class BooleanToggleBuilder extends FieldBuilder<Boolean, BooleanListEntry
         this.value = value;
     }
     
+    public BooleanToggleBuilder setErrorSupplier(Function<Boolean, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public BooleanToggleBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -75,6 +80,8 @@ public class BooleanToggleBuilder extends FieldBuilder<Boolean, BooleanListEntry
             }
         };
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleFieldBuilder.java

@@ -19,6 +19,11 @@ public class DoubleFieldBuilder extends FieldBuilder<Double, DoubleListEntry> {
         this.value = value;
     }
     
+    public DoubleFieldBuilder setErrorSupplier(Function<Double, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public DoubleFieldBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -87,6 +92,8 @@ public class DoubleFieldBuilder extends FieldBuilder<Double, DoubleListEntry> {
         if (max != null)
             entry.setMaximum(max);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 8 - 1
src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleListBuilder.java

@@ -26,6 +26,11 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         this.value = value;
     }
     
+    public DoubleListBuilder setErrorSupplier(Function<List<Double>, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public DoubleListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
@@ -137,7 +142,9 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
             entry.setCreateNewInstance(createNewInstance);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
         entry.setAddTooltip(addTooltip);
-        entry.setAddTooltip(removeTooltip);
+        entry.setRemoveTooltip(removeTooltip);
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/EnumSelectorBuilder.java

@@ -24,6 +24,11 @@ public class EnumSelectorBuilder<T extends Enum<?>> extends FieldBuilder<T, Enum
         this.clazz = clazz;
     }
     
+    public EnumSelectorBuilder<T> setErrorSupplier(Function<T, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public EnumSelectorBuilder<T> requireRestart() {
         requireRestart(true);
         return this;
@@ -75,6 +80,8 @@ public class EnumSelectorBuilder<T extends Enum<?>> extends FieldBuilder<T, Enum
     public EnumListEntry<T> build() {
         EnumListEntry<T> entry = new EnumListEntry<>(getFieldNameKey(), clazz, value, getResetButtonKey(), defaultValue, saveConsumer, enumNameProvider, null, isRequireRestart());
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 3 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/FieldBuilder.java

@@ -2,6 +2,8 @@ package me.shedaniel.clothconfig2.impl.builders;
 
 import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 
+import java.util.Optional;
+import java.util.function.Function;
 import java.util.function.Supplier;
 
 public abstract class FieldBuilder<T, A extends AbstractConfigListEntry> {
@@ -9,6 +11,7 @@ public abstract class FieldBuilder<T, A extends AbstractConfigListEntry> {
     private final String resetButtonKey;
     protected boolean requireRestart = false;
     protected Supplier<T> defaultValue = null;
+    protected Function<T, Optional<String>> errorSupplier;
     
     protected FieldBuilder(String resetButtonKey, String fieldNameKey) {
         this.resetButtonKey = resetButtonKey;

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatFieldBuilder.java

@@ -19,6 +19,11 @@ public class FloatFieldBuilder extends FieldBuilder<Float, FloatListEntry> {
         this.value = value;
     }
     
+    public FloatFieldBuilder setErrorSupplier(Function<Float, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public FloatFieldBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -87,6 +92,8 @@ public class FloatFieldBuilder extends FieldBuilder<Float, FloatListEntry> {
         if (max != null)
             entry.setMaximum(max);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 8 - 1
src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatListBuilder.java

@@ -31,6 +31,11 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
         return this;
     }
     
+    public FloatListBuilder setErrorSupplier(Function<List<Float>, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public FloatListBuilder setInsertInFront(boolean insertInFront) {
         this.insertInFront = insertInFront;
         return this;
@@ -137,7 +142,9 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
             entry.setCreateNewInstance(createNewInstance);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
         entry.setAddTooltip(addTooltip);
-        entry.setAddTooltip(removeTooltip);
+        entry.setRemoveTooltip(removeTooltip);
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntFieldBuilder.java

@@ -24,6 +24,11 @@ public class IntFieldBuilder extends FieldBuilder<Integer, IntegerListEntry> {
         return this;
     }
     
+    public IntFieldBuilder setErrorSupplier(Function<Integer, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public IntFieldBuilder setSaveConsumer(Consumer<Integer> saveConsumer) {
         this.saveConsumer = saveConsumer;
         return this;
@@ -87,6 +92,8 @@ public class IntFieldBuilder extends FieldBuilder<Integer, IntegerListEntry> {
         if (max != null)
             entry.setMaximum(max);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 8 - 1
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntListBuilder.java

@@ -26,6 +26,11 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
         this.value = value;
     }
     
+    public IntListBuilder setErrorSupplier(Function<List<Integer>, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public IntListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
@@ -137,7 +142,9 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
             entry.setCreateNewInstance(createNewInstance);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
         entry.setAddTooltip(addTooltip);
-        entry.setAddTooltip(removeTooltip);
+        entry.setRemoveTooltip(removeTooltip);
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntSliderBuilder.java

@@ -21,6 +21,11 @@ public class IntSliderBuilder extends FieldBuilder<Integer, IntegerSliderEntry>
         this.min = min;
     }
     
+    public IntSliderBuilder setErrorSupplier(Function<Integer, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public IntSliderBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -82,6 +87,8 @@ public class IntSliderBuilder extends FieldBuilder<Integer, IntegerSliderEntry>
         if (textGetter != null)
             entry.setTextGetter(textGetter);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongFieldBuilder.java

@@ -19,6 +19,11 @@ public class LongFieldBuilder extends FieldBuilder<Long, LongListEntry> {
         this.value = value;
     }
     
+    public LongFieldBuilder setErrorSupplier(Function<Long, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public LongFieldBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -87,6 +92,8 @@ public class LongFieldBuilder extends FieldBuilder<Long, LongListEntry> {
         if (max != null)
             entry.setMaximum(max);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 8 - 1
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongListBuilder.java

@@ -26,6 +26,11 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         this.value = value;
     }
     
+    public LongListBuilder setErrorSupplier(Function<List<Long>, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public LongListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
@@ -137,7 +142,9 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
             entry.setCreateNewInstance(createNewInstance);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
         entry.setAddTooltip(addTooltip);
-        entry.setAddTooltip(removeTooltip);
+        entry.setRemoveTooltip(removeTooltip);
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongSliderBuilder.java

@@ -21,6 +21,11 @@ public class LongSliderBuilder extends FieldBuilder<Long, LongSliderEntry> {
         this.min = min;
     }
     
+    public LongSliderBuilder setErrorSupplier(Function<Long, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public LongSliderBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -73,6 +78,8 @@ public class LongSliderBuilder extends FieldBuilder<Long, LongSliderEntry> {
         if (textGetter != null)
             entry.setTextGetter(textGetter);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/StringFieldBuilder.java

@@ -20,6 +20,11 @@ public class StringFieldBuilder extends FieldBuilder<String, StringListEntry> {
         this.value = value;
     }
     
+    public StringFieldBuilder setErrorSupplier(Function<String, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public StringFieldBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -64,6 +69,8 @@ public class StringFieldBuilder extends FieldBuilder<String, StringListEntry> {
     public StringListEntry build() {
         StringListEntry entry = new StringListEntry(getFieldNameKey(), value, getResetButtonKey(), defaultValue, saveConsumer, null, isRequireRestart());
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 8 - 1
src/main/java/me/shedaniel/clothconfig2/impl/builders/StringListBuilder.java

@@ -25,6 +25,11 @@ public class StringListBuilder extends FieldBuilder<List<String>, StringListList
         this.value = value;
     }
     
+    public StringListBuilder setErrorSupplier(Function<List<String>, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public StringListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
@@ -102,7 +107,9 @@ public class StringListBuilder extends FieldBuilder<List<String>, StringListList
             entry.setCreateNewInstance(createNewInstance);
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
         entry.setAddTooltip(addTooltip);
-        entry.setAddTooltip(removeTooltip);
+        entry.setRemoveTooltip(removeTooltip);
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }
     

+ 7 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/TextFieldBuilder.java

@@ -20,6 +20,11 @@ public class TextFieldBuilder extends FieldBuilder<String, StringListEntry> {
         this.value = value;
     }
     
+    public TextFieldBuilder setErrorSupplier(Function<String, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
     public TextFieldBuilder requireRestart() {
         requireRestart(true);
         return this;
@@ -64,6 +69,8 @@ public class TextFieldBuilder extends FieldBuilder<String, StringListEntry> {
     public StringListEntry build() {
         StringListEntry entry = new StringListEntry(getFieldNameKey(), value, getResetButtonKey(), defaultValue, saveConsumer, null, isRequireRestart());
         entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
     }