Просмотр исходного кода

Generify BaseListEntry to use the "curiously recurring template" pattern

This allows it to specify the types of the input functions in terms of the inheriting class (eventually). The `self()` method is a type-safe `this`, since `this` doesn't know that it should be the same type as the `SELF` parameter.

This ultimately cleans up a lot of ugly casting and prevents some simple mistakes when accessing the entry from inside a function argument.
Mitchell Skaggs 6 лет назад
Родитель
Сommit
0ae3872741

+ 44 - 36
src/main/java/me/shedaniel/clothconfig2/gui/entries/BaseListEntry.java

@@ -21,8 +21,14 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 
 
-public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipListEntry<List<T>> {
-    
+/**
+ * @param <T>    the configuration object type
+ * @param <C>    the cell type
+ * @param <SELF> the "curiously recurring template pattern" type parameter
+ * @implNote See <a href="https://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current-type-with-a-type-variable">Is there a way to refer to the current type with a type variable?</href> on Stack Overflow.
+ */
+public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends BaseListEntry<T, C, SELF>> extends TooltipListEntry<List<T>> {
+
     protected static final Identifier CONFIG_TEX = new Identifier("cloth-config2", "textures/gui/cloth_config.png");
     protected static final Identifier CONFIG_TEX = new Identifier("cloth-config2", "textures/gui/cloth_config.png");
     protected final List<C> cells;
     protected final List<C> cells;
     protected final List<Element> widgets;
     protected final List<Element> widgets;
@@ -30,16 +36,16 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
     protected Consumer<List<T>> saveConsumer;
     protected Consumer<List<T>> saveConsumer;
     protected ListLabelWidget labelWidget;
     protected ListLabelWidget labelWidget;
     protected AbstractButtonWidget resetWidget;
     protected AbstractButtonWidget resetWidget;
-    protected Function<BaseListEntry, C> createNewInstance;
+    protected Function<SELF, C> createNewInstance;
     protected Supplier<List<T>> defaultValue;
     protected Supplier<List<T>> defaultValue;
     protected String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     protected String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
-    
+
     @Deprecated
     @Deprecated
-    public BaseListEntry(String fieldName, Supplier<Optional<String[]>> tooltipSupplier, Supplier<List<T>> defaultValue, Function<BaseListEntry, C> createNewInstance, Consumer<List<T>> saveConsumer, String resetButtonKey) {
+    public BaseListEntry(String fieldName, Supplier<Optional<String[]>> tooltipSupplier, Supplier<List<T>> defaultValue, Function<SELF, C> createNewInstance, Consumer<List<T>> saveConsumer, String resetButtonKey) {
         this(fieldName, tooltipSupplier, defaultValue, createNewInstance, saveConsumer, resetButtonKey, false);
         this(fieldName, tooltipSupplier, defaultValue, createNewInstance, saveConsumer, resetButtonKey, false);
     }
     }
-    
-    public BaseListEntry(String fieldName, Supplier<Optional<String[]>> tooltipSupplier, Supplier<List<T>> defaultValue, Function<BaseListEntry, C> createNewInstance, Consumer<List<T>> saveConsumer, String resetButtonKey, boolean requiresRestart) {
+
+    public BaseListEntry(String fieldName, Supplier<Optional<String[]>> tooltipSupplier, Supplier<List<T>> defaultValue, Function<SELF, C> createNewInstance, Consumer<List<T>> saveConsumer, String resetButtonKey, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         super(fieldName, tooltipSupplier, requiresRestart);
         this.cells = Lists.newArrayList();
         this.cells = Lists.newArrayList();
         this.labelWidget = new ListLabelWidget();
         this.labelWidget = new ListLabelWidget();
@@ -56,62 +62,64 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         this.defaultValue = defaultValue;
         this.defaultValue = defaultValue;
     }
     }
-    
+
+    public abstract SELF self();
+
     public boolean isDeleteButtonEnabled() {
     public boolean isDeleteButtonEnabled() {
         return true;
         return true;
     }
     }
-    
+
     protected abstract C getFromValue(T value);
     protected abstract C getFromValue(T value);
-    
-    public Function<BaseListEntry, C> getCreateNewInstance() {
+
+    public Function<SELF, C> getCreateNewInstance() {
         return createNewInstance;
         return createNewInstance;
     }
     }
-    
-    public void setCreateNewInstance(Function<BaseListEntry, C> createNewInstance) {
+
+    public void setCreateNewInstance(Function<SELF, C> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
     }
     }
-    
+
     public String getAddTooltip() {
     public String getAddTooltip() {
         return addTooltip;
         return addTooltip;
     }
     }
-    
+
     public void setAddTooltip(String addTooltip) {
     public void setAddTooltip(String addTooltip) {
         this.addTooltip = addTooltip;
         this.addTooltip = addTooltip;
     }
     }
-    
+
     public String getRemoveTooltip() {
     public String getRemoveTooltip() {
         return removeTooltip;
         return removeTooltip;
     }
     }
-    
+
     public void setRemoveTooltip(String removeTooltip) {
     public void setRemoveTooltip(String removeTooltip) {
         this.removeTooltip = removeTooltip;
         this.removeTooltip = removeTooltip;
     }
     }
-    
+
     @Override
     @Override
     public Optional<List<T>> getDefaultValue() {
     public Optional<List<T>> getDefaultValue() {
         return Optional.ofNullable(defaultValue.get());
         return Optional.ofNullable(defaultValue.get());
     }
     }
-    
+
     @Override
     @Override
     public int getItemHeight() {
     public int getItemHeight() {
         if (expended) {
         if (expended) {
             int i = 24;
             int i = 24;
-            for(BaseListCell entry : cells)
+            for (BaseListCell entry : cells)
                 i += entry.getCellHeight();
                 i += entry.getCellHeight();
             return i;
             return i;
         }
         }
         return 24;
         return 24;
     }
     }
-    
+
     @Override
     @Override
     public List<? extends Element> children() {
     public List<? extends Element> children() {
         return widgets;
         return widgets;
     }
     }
-    
+
     @Override
     @Override
     public Optional<String> getError() {
     public Optional<String> getError() {
         String error = null;
         String error = null;
-        for(BaseListCell entry : cells)
+        for (BaseListCell entry : cells)
             if (entry.getConfigError().isPresent()) {
             if (entry.getConfigError().isPresent()) {
                 if (error != null)
                 if (error != null)
                     return Optional.ofNullable(I18n.translate("text.cloth-config.multi_error"));
                     return Optional.ofNullable(I18n.translate("text.cloth-config.multi_error"));
@@ -119,13 +127,13 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
             }
             }
         return Optional.ofNullable(error);
         return Optional.ofNullable(error);
     }
     }
-    
+
     @Override
     @Override
     public void save() {
     public void save() {
         if (saveConsumer != null)
         if (saveConsumer != null)
             saveConsumer.accept(getValue());
             saveConsumer.accept(getValue());
     }
     }
-    
+
     @Override
     @Override
     public boolean isMouseInside(int mouseX, int mouseY, int x, int y, int entryWidth, int entryHeight) {
     public boolean isMouseInside(int mouseX, int mouseY, int x, int y, int entryWidth, int entryHeight) {
         labelWidget.rectangle.x = x - 15;
         labelWidget.rectangle.x = x - 15;
@@ -134,15 +142,15 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
         labelWidget.rectangle.height = 24;
         labelWidget.rectangle.height = 24;
         return labelWidget.rectangle.contains(mouseX, mouseY) && getParent().isMouseOver(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY);
         return labelWidget.rectangle.contains(mouseX, mouseY) && getParent().isMouseOver(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY);
     }
     }
-    
+
     protected boolean isInsideCreateNew(double mouseX, double mouseY) {
     protected boolean isInsideCreateNew(double mouseX, double mouseY) {
         return mouseX >= labelWidget.rectangle.x + 12 && mouseY >= labelWidget.rectangle.y + 3 && mouseX <= labelWidget.rectangle.x + 12 + 11 && mouseY <= labelWidget.rectangle.y + 3 + 11;
         return mouseX >= labelWidget.rectangle.x + 12 && mouseY >= labelWidget.rectangle.y + 3 && mouseX <= labelWidget.rectangle.x + 12 + 11 && mouseY <= labelWidget.rectangle.y + 3 + 11;
     }
     }
-    
+
     protected boolean isInsideDelete(double mouseX, double mouseY) {
     protected boolean isInsideDelete(double mouseX, double mouseY) {
         return isDeleteButtonEnabled() && mouseX >= labelWidget.rectangle.x + 25 && mouseY >= labelWidget.rectangle.y + 3 && mouseX <= labelWidget.rectangle.x + 25 + 11 && mouseY <= labelWidget.rectangle.y + 3 + 11;
         return isDeleteButtonEnabled() && mouseX >= labelWidget.rectangle.x + 25 && mouseY >= labelWidget.rectangle.y + 3 && mouseX <= labelWidget.rectangle.x + 25 + 11 && mouseY <= labelWidget.rectangle.y + 3 + 11;
     }
     }
-    
+
     public Optional<String[]> getTooltip(int mouseX, int mouseY) {
     public Optional<String[]> getTooltip(int mouseX, int mouseY) {
         if (addTooltip != null && isInsideCreateNew(mouseX, mouseY))
         if (addTooltip != null && isInsideCreateNew(mouseX, mouseY))
             return Optional.of(new String[]{addTooltip});
             return Optional.of(new String[]{addTooltip});
@@ -152,7 +160,7 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
             return getTooltipSupplier().get();
             return getTooltipSupplier().get();
         return Optional.empty();
         return Optional.empty();
     }
     }
-    
+
     @Override
     @Override
     public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
     public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         labelWidget.rectangle.x = x - 19;
         labelWidget.rectangle.x = x - 19;
@@ -181,20 +189,20 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
         MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), isDeleteButtonEnabled() ? x + 24 : x + 24 - 9, y + 5, labelWidget.rectangle.contains(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY) && !insideDelete && !insideCreateNew ? 0xffe6fe16 : getPreferredTextColor());
         MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), isDeleteButtonEnabled() ? x + 24 : x + 24 - 9, y + 5, labelWidget.rectangle.contains(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY) && !insideDelete && !insideCreateNew ? 0xffe6fe16 : getPreferredTextColor());
         if (expended) {
         if (expended) {
             int yy = y + 24;
             int yy = y + 24;
-            for(BaseListCell cell : cells) {
+            for (BaseListCell cell : cells) {
                 cell.render(-1, yy, x + 14, entryWidth - 14, cell.getCellHeight(), mouseX, mouseY, getParent().getFocused() != null && getParent().getFocused().equals(this) && getFocused() != null && getFocused().equals(cell), delta);
                 cell.render(-1, yy, x + 14, entryWidth - 14, cell.getCellHeight(), mouseX, mouseY, getParent().getFocused() != null && getParent().getFocused().equals(this) && getFocused() != null && getFocused().equals(cell), delta);
                 yy += cell.getCellHeight();
                 yy += cell.getCellHeight();
             }
             }
         }
         }
     }
     }
-    
+
     public boolean insertInFront() {
     public boolean insertInFront() {
         return true;
         return true;
     }
     }
-    
+
     public class ListLabelWidget implements Element {
     public class ListLabelWidget implements Element {
         protected Rectangle rectangle = new Rectangle();
         protected Rectangle rectangle = new Rectangle();
-        
+
         @Override
         @Override
         public boolean mouseClicked(double double_1, double double_2, int int_1) {
         public boolean mouseClicked(double double_1, double double_2, int int_1) {
             if (resetWidget.isMouseOver(double_1, double_2)) {
             if (resetWidget.isMouseOver(double_1, double_2)) {
@@ -203,10 +211,10 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
                 expended = true;
                 expended = true;
                 C cell;
                 C cell;
                 if (insertInFront()) {
                 if (insertInFront()) {
-                    cells.add(0, cell = createNewInstance.apply(BaseListEntry.this));
+                    cells.add(0, cell = createNewInstance.apply(BaseListEntry.this.self()));
                     widgets.add(0, cell);
                     widgets.add(0, cell);
                 } else {
                 } else {
-                    cells.add(cell = createNewInstance.apply(BaseListEntry.this));
+                    cells.add(cell = createNewInstance.apply(BaseListEntry.this.self()));
                     widgets.add(cell);
                     widgets.add(cell);
                 }
                 }
                 getScreen().setEdited(true, isRequiresRestart());
                 getScreen().setEdited(true, isRequiresRestart());
@@ -229,5 +237,5 @@ public abstract class BaseListEntry<T, C extends BaseListCell> extends TooltipLi
             return false;
             return false;
         }
         }
     }
     }
-    
+
 }
 }

+ 14 - 9
src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListListEntry.java

@@ -13,16 +13,16 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEntry.DoubleListCell> {
-    
+public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEntry.DoubleListCell, DoubleListListEntry> {
+
     private double minimum, maximum;
     private double minimum, maximum;
     private Function<Double, Optional<String>> cellErrorSupplier;
     private Function<Double, Optional<String>> cellErrorSupplier;
-    
+
     @Deprecated
     @Deprecated
     public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey) {
     public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey) {
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     }
-    
+
     @Deprecated
     @Deprecated
     public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey, boolean requiresRestart) {
     public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new DoubleListCell(0d, (DoubleListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new DoubleListCell(0d, (DoubleListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
@@ -46,24 +46,29 @@ public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEnt
     public List<Double> getValue() {
     public List<Double> getValue() {
         return cells.stream().map(DoubleListCell::getValue).collect(Collectors.toList());
         return cells.stream().map(DoubleListCell::getValue).collect(Collectors.toList());
     }
     }
-    
+
     public DoubleListListEntry setMaximum(Double maximum) {
     public DoubleListListEntry setMaximum(Double maximum) {
         this.maximum = maximum;
         this.maximum = maximum;
         return this;
         return this;
     }
     }
-    
+
     public DoubleListListEntry setMinimum(Double minimum) {
     public DoubleListListEntry setMinimum(Double minimum) {
         this.minimum = minimum;
         this.minimum = minimum;
         return this;
         return this;
     }
     }
-    
+
+    @Override
+    public DoubleListListEntry self() {
+        return this;
+    }
+
     @Override
     @Override
     protected DoubleListCell getFromValue(Double value) {
     protected DoubleListCell getFromValue(Double value) {
         return new DoubleListCell(value, this);
         return new DoubleListCell(value, this);
     }
     }
-    
+
     public static class DoubleListCell extends BaseListCell {
     public static class DoubleListCell extends BaseListCell {
-        
+
         private Function<String, String> stripCharacters = s -> {
         private Function<String, String> stripCharacters = s -> {
             StringBuilder stringBuilder_1 = new StringBuilder();
             StringBuilder stringBuilder_1 = new StringBuilder();
             char[] var2 = s.toCharArray();
             char[] var2 = s.toCharArray();

+ 31 - 26
src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListListEntry.java

@@ -13,72 +13,77 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.FloatListCell> {
-    
+public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.FloatListCell, FloatListListEntry> {
+
     private float minimum, maximum;
     private float minimum, maximum;
     private Function<Float, Optional<String>> cellErrorSupplier;
     private Function<Float, Optional<String>> cellErrorSupplier;
-    
+
     @Deprecated
     @Deprecated
     public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey) {
     public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey) {
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     }
-    
+
     @Deprecated
     @Deprecated
     public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey, boolean requiresRestart) {
     public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey, boolean requiresRestart) {
-        super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new FloatListCell(0, (FloatListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
+        super(fieldName, tooltipSupplier, defaultValue, floatListListEntry -> new FloatListCell(0, floatListListEntry), saveConsumer, resetButtonKey, requiresRestart);
         this.minimum = -Float.MAX_VALUE;
         this.minimum = -Float.MAX_VALUE;
         this.maximum = Float.MAX_VALUE;
         this.maximum = Float.MAX_VALUE;
-        for(float f : value)
+        for (float f : value)
             cells.add(new FloatListCell(f, this));
             cells.add(new FloatListCell(f, this));
         this.widgets.addAll(cells);
         this.widgets.addAll(cells);
         expended = defaultExpended;
         expended = defaultExpended;
     }
     }
-    
+
     public Function<Float, Optional<String>> getCellErrorSupplier() {
     public Function<Float, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public void setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
     public void setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
     }
     }
-    
+
     @Override
     @Override
     public List<Float> getValue() {
     public List<Float> getValue() {
         return cells.stream().map(FloatListCell::getValue).collect(Collectors.toList());
         return cells.stream().map(FloatListCell::getValue).collect(Collectors.toList());
     }
     }
-    
+
     public FloatListListEntry setMaximum(float maximum) {
     public FloatListListEntry setMaximum(float maximum) {
         this.maximum = maximum;
         this.maximum = maximum;
         return this;
         return this;
     }
     }
-    
+
     public FloatListListEntry setMinimum(float minimum) {
     public FloatListListEntry setMinimum(float minimum) {
         this.minimum = minimum;
         this.minimum = minimum;
         return this;
         return this;
     }
     }
-    
+
+    @Override
+    public FloatListListEntry self() {
+        return this;
+    }
+
     @Override
     @Override
     protected FloatListCell getFromValue(Float value) {
     protected FloatListCell getFromValue(Float value) {
         return new FloatListCell(value, this);
         return new FloatListCell(value, this);
     }
     }
-    
+
     public static class FloatListCell extends BaseListCell {
     public static class FloatListCell extends BaseListCell {
-        
+
         private Function<String, String> stripCharacters = s -> {
         private Function<String, String> stripCharacters = s -> {
             StringBuilder stringBuilder_1 = new StringBuilder();
             StringBuilder stringBuilder_1 = new StringBuilder();
             char[] var2 = s.toCharArray();
             char[] var2 = s.toCharArray();
             int var3 = var2.length;
             int var3 = var2.length;
-            
-            for(int var4 = 0; var4 < var3; ++var4)
+
+            for (int var4 = 0; var4 < var3; ++var4)
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-' || var2[var4] == '.')
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-' || var2[var4] == '.')
                     stringBuilder_1.append(var2[var4]);
                     stringBuilder_1.append(var2[var4]);
-            
+
             return stringBuilder_1.toString();
             return stringBuilder_1.toString();
         };
         };
         private TextFieldWidget widget;
         private TextFieldWidget widget;
         private boolean isSelected;
         private boolean isSelected;
         private FloatListListEntry listListEntry;
         private FloatListListEntry listListEntry;
-        
+
         public FloatListCell(float value, FloatListListEntry listListEntry) {
         public FloatListCell(float value, FloatListListEntry listListEntry) {
             this.listListEntry = listListEntry;
             this.listListEntry = listListEntry;
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
@@ -91,7 +96,7 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
                     super.render(int_1, int_2, float_1);
                     super.render(int_1, int_2, float_1);
                     setFocused(f);
                     setFocused(f);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void write(String string_1) {
                 public void write(String string_1) {
                     super.write(stripCharacters.apply(string_1));
                     super.write(stripCharacters.apply(string_1));
@@ -105,7 +110,7 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
             });
             });
         }
         }
-        
+
         public float getValue() {
         public float getValue() {
             try {
             try {
                 return Float.valueOf(widget.getText());
                 return Float.valueOf(widget.getText());
@@ -113,7 +118,7 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
                 return 0f;
                 return 0f;
             }
             }
         }
         }
-        
+
         @Override
         @Override
         public Optional<String> getError() {
         public Optional<String> getError() {
             try {
             try {
@@ -127,12 +132,12 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
             }
             }
             return Optional.empty();
             return Optional.empty();
         }
         }
-        
+
         @Override
         @Override
         public int getCellHeight() {
         public int getCellHeight() {
             return 20;
             return 20;
         }
         }
-        
+
         @Override
         @Override
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             widget.setWidth(entryWidth - 12);
             widget.setWidth(entryWidth - 12);
@@ -144,12 +149,12 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
             if (isSelected && listListEntry.isEditable())
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
         }
         }
-        
+
         @Override
         @Override
         public List<? extends Element> children() {
         public List<? extends Element> children() {
             return Collections.singletonList(widget);
             return Collections.singletonList(widget);
         }
         }
-        
+
     }
     }
-    
+
 }
 }

+ 31 - 26
src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListListEntry.java

@@ -13,72 +13,77 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListListEntry.IntegerListCell> {
-    
+public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListListEntry.IntegerListCell, IntegerListListEntry> {
+
     private int minimum, maximum;
     private int minimum, maximum;
     private Function<Integer, Optional<String>> cellErrorSupplier;
     private Function<Integer, Optional<String>> cellErrorSupplier;
-    
+
     @Deprecated
     @Deprecated
     public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey) {
     public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey) {
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     }
-    
+
     @Deprecated
     @Deprecated
     public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey, boolean requiresRestart) {
     public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey, boolean requiresRestart) {
-        super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new IntegerListCell(0, (IntegerListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
+        super(fieldName, tooltipSupplier, defaultValue, integerListListEntry -> new IntegerListCell(0, integerListListEntry), saveConsumer, resetButtonKey, requiresRestart);
         this.minimum = -Integer.MAX_VALUE;
         this.minimum = -Integer.MAX_VALUE;
         this.maximum = Integer.MAX_VALUE;
         this.maximum = Integer.MAX_VALUE;
-        for(int integer : value)
+        for (int integer : value)
             cells.add(new IntegerListCell(integer, this));
             cells.add(new IntegerListCell(integer, this));
         this.widgets.addAll(cells);
         this.widgets.addAll(cells);
         expended = defaultExpended;
         expended = defaultExpended;
     }
     }
-    
+
     public Function<Integer, Optional<String>> getCellErrorSupplier() {
     public Function<Integer, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public void setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
     public void setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
     }
     }
-    
+
     @Override
     @Override
     public List<Integer> getValue() {
     public List<Integer> getValue() {
         return cells.stream().map(IntegerListCell::getValue).collect(Collectors.toList());
         return cells.stream().map(IntegerListCell::getValue).collect(Collectors.toList());
     }
     }
-    
+
     public IntegerListListEntry setMaximum(int maximum) {
     public IntegerListListEntry setMaximum(int maximum) {
         this.maximum = maximum;
         this.maximum = maximum;
         return this;
         return this;
     }
     }
-    
+
     public IntegerListListEntry setMinimum(int minimum) {
     public IntegerListListEntry setMinimum(int minimum) {
         this.minimum = minimum;
         this.minimum = minimum;
         return this;
         return this;
     }
     }
-    
+
+    @Override
+    public IntegerListListEntry self() {
+        return this;
+    }
+
     @Override
     @Override
     protected IntegerListCell getFromValue(Integer value) {
     protected IntegerListCell getFromValue(Integer value) {
         return new IntegerListCell(value, this);
         return new IntegerListCell(value, this);
     }
     }
-    
+
     public static class IntegerListCell extends BaseListCell {
     public static class IntegerListCell extends BaseListCell {
-        
+
         private Function<String, String> stripCharacters = s -> {
         private Function<String, String> stripCharacters = s -> {
             StringBuilder stringBuilder_1 = new StringBuilder();
             StringBuilder stringBuilder_1 = new StringBuilder();
             char[] var2 = s.toCharArray();
             char[] var2 = s.toCharArray();
             int var3 = var2.length;
             int var3 = var2.length;
-            
-            for(int var4 = 0; var4 < var3; ++var4)
+
+            for (int var4 = 0; var4 < var3; ++var4)
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-')
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-')
                     stringBuilder_1.append(var2[var4]);
                     stringBuilder_1.append(var2[var4]);
-            
+
             return stringBuilder_1.toString();
             return stringBuilder_1.toString();
         };
         };
         private TextFieldWidget widget;
         private TextFieldWidget widget;
         private boolean isSelected;
         private boolean isSelected;
         private IntegerListListEntry listListEntry;
         private IntegerListListEntry listListEntry;
-        
+
         public IntegerListCell(int value, IntegerListListEntry listListEntry) {
         public IntegerListCell(int value, IntegerListListEntry listListEntry) {
             this.listListEntry = listListEntry;
             this.listListEntry = listListEntry;
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
@@ -91,7 +96,7 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
                     super.render(int_1, int_2, float_1);
                     super.render(int_1, int_2, float_1);
                     setFocused(f);
                     setFocused(f);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void write(String string_1) {
                 public void write(String string_1) {
                     super.write(stripCharacters.apply(string_1));
                     super.write(stripCharacters.apply(string_1));
@@ -105,7 +110,7 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
             });
             });
         }
         }
-        
+
         public int getValue() {
         public int getValue() {
             try {
             try {
                 return Integer.valueOf(widget.getText());
                 return Integer.valueOf(widget.getText());
@@ -113,7 +118,7 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
                 return 0;
                 return 0;
             }
             }
         }
         }
-        
+
         @Override
         @Override
         public Optional<String> getError() {
         public Optional<String> getError() {
             try {
             try {
@@ -127,12 +132,12 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
             }
             }
             return Optional.empty();
             return Optional.empty();
         }
         }
-        
+
         @Override
         @Override
         public int getCellHeight() {
         public int getCellHeight() {
             return 20;
             return 20;
         }
         }
-        
+
         @Override
         @Override
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             widget.setWidth(entryWidth - 12);
             widget.setWidth(entryWidth - 12);
@@ -144,12 +149,12 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
             if (isSelected && listListEntry.isEditable())
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
         }
         }
-        
+
         @Override
         @Override
         public List<? extends Element> children() {
         public List<? extends Element> children() {
             return Collections.singletonList(widget);
             return Collections.singletonList(widget);
         }
         }
-        
+
     }
     }
-    
+
 }
 }

+ 30 - 25
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListListEntry.java

@@ -13,72 +13,77 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.LongListCell> {
-    
+public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.LongListCell, LongListListEntry> {
+
     private long minimum, maximum;
     private long minimum, maximum;
     private Function<Long, Optional<String>> cellErrorSupplier;
     private Function<Long, Optional<String>> cellErrorSupplier;
-    
+
     @Deprecated
     @Deprecated
     public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey) {
     public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey) {
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     }
-    
+
     @Deprecated
     @Deprecated
     public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey, boolean requiresRestart) {
     public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new LongListCell(0, (LongListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new LongListCell(0, (LongListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
         this.minimum = -Long.MAX_VALUE;
         this.minimum = -Long.MAX_VALUE;
         this.maximum = Long.MAX_VALUE;
         this.maximum = Long.MAX_VALUE;
-        for(long l : value)
+        for (long l : value)
             cells.add(new LongListCell(l, this));
             cells.add(new LongListCell(l, this));
         this.widgets.addAll(cells);
         this.widgets.addAll(cells);
         expended = defaultExpended;
         expended = defaultExpended;
     }
     }
-    
+
     public Function<Long, Optional<String>> getCellErrorSupplier() {
     public Function<Long, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public void setCellErrorSupplier(Function<Long, Optional<String>> cellErrorSupplier) {
     public void setCellErrorSupplier(Function<Long, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
     }
     }
-    
+
     @Override
     @Override
     public List<Long> getValue() {
     public List<Long> getValue() {
         return cells.stream().map(LongListCell::getValue).collect(Collectors.toList());
         return cells.stream().map(LongListCell::getValue).collect(Collectors.toList());
     }
     }
-    
+
     public LongListListEntry setMaximum(long maximum) {
     public LongListListEntry setMaximum(long maximum) {
         this.maximum = maximum;
         this.maximum = maximum;
         return this;
         return this;
     }
     }
-    
+
     public LongListListEntry setMinimum(long minimum) {
     public LongListListEntry setMinimum(long minimum) {
         this.minimum = minimum;
         this.minimum = minimum;
         return this;
         return this;
     }
     }
-    
+
+    @Override
+    public LongListListEntry self() {
+        return this;
+    }
+
     @Override
     @Override
     protected LongListCell getFromValue(Long value) {
     protected LongListCell getFromValue(Long value) {
         return new LongListCell(value, this);
         return new LongListCell(value, this);
     }
     }
-    
+
     public static class LongListCell extends BaseListCell {
     public static class LongListCell extends BaseListCell {
-        
+
         private Function<String, String> stripCharacters = s -> {
         private Function<String, String> stripCharacters = s -> {
             StringBuilder stringBuilder_1 = new StringBuilder();
             StringBuilder stringBuilder_1 = new StringBuilder();
             char[] var2 = s.toCharArray();
             char[] var2 = s.toCharArray();
             int var3 = var2.length;
             int var3 = var2.length;
-            
-            for(int var4 = 0; var4 < var3; ++var4)
+
+            for (int var4 = 0; var4 < var3; ++var4)
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-')
                 if (Character.isDigit(var2[var4]) || var2[var4] == '-')
                     stringBuilder_1.append(var2[var4]);
                     stringBuilder_1.append(var2[var4]);
-            
+
             return stringBuilder_1.toString();
             return stringBuilder_1.toString();
         };
         };
         private TextFieldWidget widget;
         private TextFieldWidget widget;
         private boolean isSelected;
         private boolean isSelected;
         private LongListListEntry listListEntry;
         private LongListListEntry listListEntry;
-        
+
         public LongListCell(long value, LongListListEntry listListEntry) {
         public LongListCell(long value, LongListListEntry listListEntry) {
             this.listListEntry = listListEntry;
             this.listListEntry = listListEntry;
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
@@ -91,7 +96,7 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
                     super.render(int_1, int_2, float_1);
                     super.render(int_1, int_2, float_1);
                     setFocused(f);
                     setFocused(f);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void write(String string_1) {
                 public void write(String string_1) {
                     super.write(stripCharacters.apply(string_1));
                     super.write(stripCharacters.apply(string_1));
@@ -105,7 +110,7 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
             });
             });
         }
         }
-        
+
         public long getValue() {
         public long getValue() {
             try {
             try {
                 return Long.valueOf(widget.getText());
                 return Long.valueOf(widget.getText());
@@ -113,7 +118,7 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
                 return 0;
                 return 0;
             }
             }
         }
         }
-        
+
         @Override
         @Override
         public Optional<String> getError() {
         public Optional<String> getError() {
             try {
             try {
@@ -127,12 +132,12 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
             }
             }
             return Optional.empty();
             return Optional.empty();
         }
         }
-        
+
         @Override
         @Override
         public int getCellHeight() {
         public int getCellHeight() {
             return 20;
             return 20;
         }
         }
-        
+
         @Override
         @Override
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             widget.setWidth(entryWidth - 12);
             widget.setWidth(entryWidth - 12);
@@ -144,12 +149,12 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
             if (isSelected && listListEntry.isEditable())
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
         }
         }
-        
+
         @Override
         @Override
         public List<? extends Element> children() {
         public List<? extends Element> children() {
             return Collections.singletonList(widget);
             return Collections.singletonList(widget);
         }
         }
-        
+
     }
     }
-    
+
 }
 }

+ 23 - 18
src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListListEntry.java

@@ -12,48 +12,53 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class StringListListEntry extends BaseListEntry<String, StringListListEntry.StringListCell> {
-    
+public class StringListListEntry extends BaseListEntry<String, StringListListEntry.StringListCell, StringListListEntry> {
+
     private Function<String, Optional<String>> cellErrorSupplier;
     private Function<String, Optional<String>> cellErrorSupplier;
-    
+
     @Deprecated
     @Deprecated
     public StringListListEntry(String fieldName, List<String> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey) {
     public StringListListEntry(String fieldName, List<String> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey) {
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
         this(fieldName, value, defaultExpended, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     }
-    
+
     @Deprecated
     @Deprecated
     public StringListListEntry(String fieldName, List<String> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey, boolean requiresRestart) {
     public StringListListEntry(String fieldName, List<String> value, boolean defaultExpended, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new StringListCell("", (StringListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
         super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new StringListCell("", (StringListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart);
-        for(String str : value)
+        for (String str : value)
             cells.add(new StringListCell(str, this));
             cells.add(new StringListCell(str, this));
         this.widgets.addAll(cells);
         this.widgets.addAll(cells);
         expended = defaultExpended;
         expended = defaultExpended;
     }
     }
-    
+
     public Function<String, Optional<String>> getCellErrorSupplier() {
     public Function<String, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public void setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
     public void setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
     }
     }
-    
+
     @Override
     @Override
     public List<String> getValue() {
     public List<String> getValue() {
         return cells.stream().map(cell -> cell.widget.getText()).collect(Collectors.toList());
         return cells.stream().map(cell -> cell.widget.getText()).collect(Collectors.toList());
     }
     }
-    
+
+    @Override
+    public StringListListEntry self() {
+        return this;
+    }
+
     @Override
     @Override
     protected StringListCell getFromValue(String value) {
     protected StringListCell getFromValue(String value) {
         return new StringListCell(value, this);
         return new StringListCell(value, this);
     }
     }
-    
+
     public static class StringListCell extends BaseListCell {
     public static class StringListCell extends BaseListCell {
-        
+
         private TextFieldWidget widget;
         private TextFieldWidget widget;
         private boolean isSelected;
         private boolean isSelected;
         private StringListListEntry listListEntry;
         private StringListListEntry listListEntry;
-        
+
         public StringListCell(String value, StringListListEntry listListEntry) {
         public StringListCell(String value, StringListListEntry listListEntry) {
             this.listListEntry = listListEntry;
             this.listListEntry = listListEntry;
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(widget.getText()));
             this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(widget.getText()));
@@ -75,17 +80,17 @@ public class StringListListEntry extends BaseListEntry<String, StringListListEnt
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
                     listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
             });
             });
         }
         }
-        
+
         @Override
         @Override
         public Optional<String> getError() {
         public Optional<String> getError() {
             return Optional.empty();
             return Optional.empty();
         }
         }
-        
+
         @Override
         @Override
         public int getCellHeight() {
         public int getCellHeight() {
             return 20;
             return 20;
         }
         }
-        
+
         @Override
         @Override
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             widget.setWidth(entryWidth - 12);
             widget.setWidth(entryWidth - 12);
@@ -97,12 +102,12 @@ public class StringListListEntry extends BaseListEntry<String, StringListListEnt
             if (isSelected && listListEntry.isEditable())
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
         }
         }
-        
+
         @Override
         @Override
         public List<? extends Element> children() {
         public List<? extends Element> children() {
             return Collections.singletonList(widget);
             return Collections.singletonList(widget);
         }
         }
-        
+
     }
     }
-    
+
 }
 }

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

@@ -1,9 +1,9 @@
 package me.shedaniel.clothconfig2.impl.builders;
 package me.shedaniel.clothconfig2.impl.builders;
 
 
-import me.shedaniel.clothconfig2.gui.entries.BaseListEntry;
 import me.shedaniel.clothconfig2.gui.entries.DoubleListListEntry;
 import me.shedaniel.clothconfig2.gui.entries.DoubleListListEntry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 
 
+import javax.annotation.Nonnull;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -18,7 +18,7 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
     private List<Double> value;
     private List<Double> value;
     private boolean expended = false;
     private boolean expended = false;
     private Double min = null, max = null;
     private Double min = null, max = null;
-    private Function<BaseListEntry, DoubleListListEntry.DoubleListCell> createNewInstance;
+    private Function<DoubleListListEntry, DoubleListListEntry.DoubleListCell> createNewInstance;
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
     
@@ -65,8 +65,8 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         requireRestart(true);
         requireRestart(true);
         return this;
         return this;
     }
     }
-    
-    public DoubleListBuilder setCreateNewInstance(Function<BaseListEntry, DoubleListListEntry.DoubleListCell> createNewInstance) {
+
+    public DoubleListBuilder setCreateNewInstance(Function<DoubleListListEntry, DoubleListListEntry.DoubleListCell> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         return this;
         return this;
     }
     }
@@ -130,7 +130,8 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
         return this;
     }
     }
-    
+
+    @Nonnull
     @Override
     @Override
     public DoubleListListEntry build() {
     public DoubleListListEntry build() {
         DoubleListListEntry entry = new DoubleListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
         DoubleListListEntry entry = new DoubleListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
@@ -138,7 +139,7 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
             public boolean isDeleteButtonEnabled() {
             public boolean isDeleteButtonEnabled() {
                 return deleteButtonEnabled;
                 return deleteButtonEnabled;
             }
             }
-            
+
             @Override
             @Override
             public boolean insertInFront() {
             public boolean insertInFront() {
                 return insertInFront;
                 return insertInFront;
@@ -159,4 +160,4 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         return entry;
         return entry;
     }
     }
     
     
-}
+}

+ 31 - 30
src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatListBuilder.java

@@ -1,9 +1,9 @@
 package me.shedaniel.clothconfig2.impl.builders;
 package me.shedaniel.clothconfig2.impl.builders;
 
 
-import me.shedaniel.clothconfig2.gui.entries.BaseListEntry;
 import me.shedaniel.clothconfig2.gui.entries.FloatListListEntry;
 import me.shedaniel.clothconfig2.gui.entries.FloatListListEntry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 
 
+import javax.annotation.Nonnull;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -11,126 +11,127 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 
 
 public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEntry> {
 public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEntry> {
-    
+
     protected Function<Float, Optional<String>> cellErrorSupplier;
     protected Function<Float, Optional<String>> cellErrorSupplier;
     private Consumer<List<Float>> saveConsumer = null;
     private Consumer<List<Float>> saveConsumer = null;
     private Function<List<Float>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private Function<List<Float>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private List<Float> value;
     private List<Float> value;
     private boolean expended = false;
     private boolean expended = false;
     private Float min = null, max = null;
     private Float min = null, max = null;
-    private Function<BaseListEntry, FloatListListEntry.FloatListCell> createNewInstance;
+    private Function<FloatListListEntry, FloatListListEntry.FloatListCell> createNewInstance;
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     private boolean deleteButtonEnabled = true, insertInFront = true;
-    
+
     public FloatListBuilder(String resetButtonKey, String fieldNameKey, List<Float> value) {
     public FloatListBuilder(String resetButtonKey, String fieldNameKey, List<Float> value) {
         super(resetButtonKey, fieldNameKey);
         super(resetButtonKey, fieldNameKey);
         this.value = value;
         this.value = value;
     }
     }
-    
+
     public Function<Float, Optional<String>> getCellErrorSupplier() {
     public Function<Float, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public FloatListBuilder setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
     public FloatListBuilder setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
     public FloatListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setErrorSupplier(Function<List<Float>, Optional<String>> errorSupplier) {
     public FloatListBuilder setErrorSupplier(Function<List<Float>, Optional<String>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         this.errorSupplier = errorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setInsertInFront(boolean insertInFront) {
     public FloatListBuilder setInsertInFront(boolean insertInFront) {
         this.insertInFront = insertInFront;
         this.insertInFront = insertInFront;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setAddButtonTooltip(String addTooltip) {
     public FloatListBuilder setAddButtonTooltip(String addTooltip) {
         this.addTooltip = addTooltip;
         this.addTooltip = addTooltip;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setRemoveButtonTooltip(String removeTooltip) {
     public FloatListBuilder setRemoveButtonTooltip(String removeTooltip) {
         this.removeTooltip = removeTooltip;
         this.removeTooltip = removeTooltip;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder requireRestart() {
     public FloatListBuilder requireRestart() {
         requireRestart(true);
         requireRestart(true);
         return this;
         return this;
     }
     }
-    
-    public FloatListBuilder setCreateNewInstance(Function<BaseListEntry, FloatListListEntry.FloatListCell> createNewInstance) {
+
+    public FloatListBuilder setCreateNewInstance(Function<FloatListListEntry, FloatListListEntry.FloatListCell> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setExpended(boolean expended) {
     public FloatListBuilder setExpended(boolean expended) {
         this.expended = expended;
         this.expended = expended;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setSaveConsumer(Consumer<List<Float>> saveConsumer) {
     public FloatListBuilder setSaveConsumer(Consumer<List<Float>> saveConsumer) {
         this.saveConsumer = saveConsumer;
         this.saveConsumer = saveConsumer;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setDefaultValue(Supplier<List<Float>> defaultValue) {
     public FloatListBuilder setDefaultValue(Supplier<List<Float>> defaultValue) {
         this.defaultValue = defaultValue;
         this.defaultValue = defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setMin(float min) {
     public FloatListBuilder setMin(float min) {
         this.min = min;
         this.min = min;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setMax(float max) {
     public FloatListBuilder setMax(float max) {
         this.max = max;
         this.max = max;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder removeMin() {
     public FloatListBuilder removeMin() {
         this.min = null;
         this.min = null;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder removeMax() {
     public FloatListBuilder removeMax() {
         this.max = null;
         this.max = null;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setDefaultValue(List<Float> defaultValue) {
     public FloatListBuilder setDefaultValue(List<Float> defaultValue) {
         this.defaultValue = () -> defaultValue;
         this.defaultValue = () -> defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
     public FloatListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setTooltipSupplier(Function<List<Float>, Optional<String[]>> tooltipSupplier) {
     public FloatListBuilder setTooltipSupplier(Function<List<Float>, Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         this.tooltipSupplier = tooltipSupplier;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setTooltip(Optional<String[]> tooltip) {
     public FloatListBuilder setTooltip(Optional<String[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         this.tooltipSupplier = list -> tooltip;
         return this;
         return this;
     }
     }
-    
+
     public FloatListBuilder setTooltip(String... tooltip) {
     public FloatListBuilder setTooltip(String... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
         return this;
     }
     }
-    
+
+    @Nonnull
     @Override
     @Override
     public FloatListListEntry build() {
     public FloatListListEntry build() {
         FloatListListEntry entry = new FloatListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
         FloatListListEntry entry = new FloatListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
@@ -138,7 +139,7 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
             public boolean isDeleteButtonEnabled() {
             public boolean isDeleteButtonEnabled() {
                 return deleteButtonEnabled;
                 return deleteButtonEnabled;
             }
             }
-            
+
             @Override
             @Override
             public boolean insertInFront() {
             public boolean insertInFront() {
                 return insertInFront;
                 return insertInFront;
@@ -158,5 +159,5 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
         return entry;
     }
     }
-    
-}
+
+}

+ 31 - 30
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntListBuilder.java

@@ -1,9 +1,9 @@
 package me.shedaniel.clothconfig2.impl.builders;
 package me.shedaniel.clothconfig2.impl.builders;
 
 
-import me.shedaniel.clothconfig2.gui.entries.BaseListEntry;
 import me.shedaniel.clothconfig2.gui.entries.IntegerListListEntry;
 import me.shedaniel.clothconfig2.gui.entries.IntegerListListEntry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 
 
+import javax.annotation.Nonnull;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -11,126 +11,127 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 
 
 public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListEntry> {
 public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListEntry> {
-    
+
     protected Function<Integer, Optional<String>> cellErrorSupplier;
     protected Function<Integer, Optional<String>> cellErrorSupplier;
     private Consumer<List<Integer>> saveConsumer = null;
     private Consumer<List<Integer>> saveConsumer = null;
     private Function<List<Integer>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private Function<List<Integer>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private List<Integer> value;
     private List<Integer> value;
     private boolean expended = false;
     private boolean expended = false;
     private Integer min = null, max = null;
     private Integer min = null, max = null;
-    private Function<BaseListEntry, IntegerListListEntry.IntegerListCell> createNewInstance;
+    private Function<IntegerListListEntry, IntegerListListEntry.IntegerListCell> createNewInstance;
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     private boolean deleteButtonEnabled = true, insertInFront = true;
-    
+
     public IntListBuilder(String resetButtonKey, String fieldNameKey, List<Integer> value) {
     public IntListBuilder(String resetButtonKey, String fieldNameKey, List<Integer> value) {
         super(resetButtonKey, fieldNameKey);
         super(resetButtonKey, fieldNameKey);
         this.value = value;
         this.value = value;
     }
     }
-    
+
     public Function<Integer, Optional<String>> getCellErrorSupplier() {
     public Function<Integer, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public IntListBuilder setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
     public IntListBuilder setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setErrorSupplier(Function<List<Integer>, Optional<String>> errorSupplier) {
     public IntListBuilder setErrorSupplier(Function<List<Integer>, Optional<String>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         this.errorSupplier = errorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
     public IntListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setInsertInFront(boolean insertInFront) {
     public IntListBuilder setInsertInFront(boolean insertInFront) {
         this.insertInFront = insertInFront;
         this.insertInFront = insertInFront;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setAddButtonTooltip(String addTooltip) {
     public IntListBuilder setAddButtonTooltip(String addTooltip) {
         this.addTooltip = addTooltip;
         this.addTooltip = addTooltip;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setRemoveButtonTooltip(String removeTooltip) {
     public IntListBuilder setRemoveButtonTooltip(String removeTooltip) {
         this.removeTooltip = removeTooltip;
         this.removeTooltip = removeTooltip;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder requireRestart() {
     public IntListBuilder requireRestart() {
         requireRestart(true);
         requireRestart(true);
         return this;
         return this;
     }
     }
-    
-    public IntListBuilder setCreateNewInstance(Function<BaseListEntry, IntegerListListEntry.IntegerListCell> createNewInstance) {
+
+    public IntListBuilder setCreateNewInstance(Function<IntegerListListEntry, IntegerListListEntry.IntegerListCell> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setExpended(boolean expended) {
     public IntListBuilder setExpended(boolean expended) {
         this.expended = expended;
         this.expended = expended;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setSaveConsumer(Consumer<List<Integer>> saveConsumer) {
     public IntListBuilder setSaveConsumer(Consumer<List<Integer>> saveConsumer) {
         this.saveConsumer = saveConsumer;
         this.saveConsumer = saveConsumer;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setDefaultValue(Supplier<List<Integer>> defaultValue) {
     public IntListBuilder setDefaultValue(Supplier<List<Integer>> defaultValue) {
         this.defaultValue = defaultValue;
         this.defaultValue = defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setMin(int min) {
     public IntListBuilder setMin(int min) {
         this.min = min;
         this.min = min;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setMax(int max) {
     public IntListBuilder setMax(int max) {
         this.max = max;
         this.max = max;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder removeMin() {
     public IntListBuilder removeMin() {
         this.min = null;
         this.min = null;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder removeMax() {
     public IntListBuilder removeMax() {
         this.max = null;
         this.max = null;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setDefaultValue(List<Integer> defaultValue) {
     public IntListBuilder setDefaultValue(List<Integer> defaultValue) {
         this.defaultValue = () -> defaultValue;
         this.defaultValue = () -> defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setTooltipSupplier(Function<List<Integer>, Optional<String[]>> tooltipSupplier) {
     public IntListBuilder setTooltipSupplier(Function<List<Integer>, Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         this.tooltipSupplier = tooltipSupplier;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
     public IntListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setTooltip(Optional<String[]> tooltip) {
     public IntListBuilder setTooltip(Optional<String[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         this.tooltipSupplier = list -> tooltip;
         return this;
         return this;
     }
     }
-    
+
     public IntListBuilder setTooltip(String... tooltip) {
     public IntListBuilder setTooltip(String... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
         return this;
     }
     }
-    
+
+    @Nonnull
     @Override
     @Override
     public IntegerListListEntry build() {
     public IntegerListListEntry build() {
         IntegerListListEntry entry = new IntegerListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
         IntegerListListEntry entry = new IntegerListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
@@ -138,7 +139,7 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
             public boolean isDeleteButtonEnabled() {
             public boolean isDeleteButtonEnabled() {
                 return deleteButtonEnabled;
                 return deleteButtonEnabled;
             }
             }
-            
+
             @Override
             @Override
             public boolean insertInFront() {
             public boolean insertInFront() {
                 return insertInFront;
                 return insertInFront;
@@ -158,5 +159,5 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
         return entry;
     }
     }
-    
-}
+
+}

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

@@ -1,9 +1,9 @@
 package me.shedaniel.clothconfig2.impl.builders;
 package me.shedaniel.clothconfig2.impl.builders;
 
 
-import me.shedaniel.clothconfig2.gui.entries.BaseListEntry;
 import me.shedaniel.clothconfig2.gui.entries.LongListListEntry;
 import me.shedaniel.clothconfig2.gui.entries.LongListListEntry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 
 
+import javax.annotation.Nonnull;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -18,7 +18,7 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
     private List<Long> value;
     private List<Long> value;
     private boolean expended = false;
     private boolean expended = false;
     private Long min = null, max = null;
     private Long min = null, max = null;
-    private Function<BaseListEntry, LongListListEntry.LongListCell> createNewInstance;
+    private Function<LongListListEntry, LongListListEntry.LongListCell> createNewInstance;
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
     
@@ -65,8 +65,8 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         requireRestart(true);
         requireRestart(true);
         return this;
         return this;
     }
     }
-    
-    public LongListBuilder setCreateNewInstance(Function<BaseListEntry, LongListListEntry.LongListCell> createNewInstance) {
+
+    public LongListBuilder setCreateNewInstance(Function<LongListListEntry, LongListListEntry.LongListCell> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         return this;
         return this;
     }
     }
@@ -130,7 +130,8 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
         return this;
     }
     }
-    
+
+    @Nonnull
     @Override
     @Override
     public LongListListEntry build() {
     public LongListListEntry build() {
         LongListListEntry entry = new LongListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
         LongListListEntry entry = new LongListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart()) {
@@ -138,7 +139,7 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
             public boolean isDeleteButtonEnabled() {
             public boolean isDeleteButtonEnabled() {
                 return deleteButtonEnabled;
                 return deleteButtonEnabled;
             }
             }
-            
+
             @Override
             @Override
             public boolean insertInFront() {
             public boolean insertInFront() {
                 return insertInFront;
                 return insertInFront;
@@ -159,4 +160,4 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         return entry;
         return entry;
     }
     }
     
     
-}
+}

+ 24 - 25
src/main/java/me/shedaniel/clothconfig2/impl/builders/StringListBuilder.java

@@ -1,6 +1,5 @@
 package me.shedaniel.clothconfig2.impl.builders;
 package me.shedaniel.clothconfig2.impl.builders;
 
 
-import me.shedaniel.clothconfig2.gui.entries.BaseListEntry;
 import me.shedaniel.clothconfig2.gui.entries.StringListListEntry;
 import me.shedaniel.clothconfig2.gui.entries.StringListListEntry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 
 
@@ -11,105 +10,105 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 
 
 public class StringListBuilder extends FieldBuilder<List<String>, StringListListEntry> {
 public class StringListBuilder extends FieldBuilder<List<String>, StringListListEntry> {
-    
+
     private Function<String, Optional<String>> cellErrorSupplier;
     private Function<String, Optional<String>> cellErrorSupplier;
     private Consumer<List<String>> saveConsumer = null;
     private Consumer<List<String>> saveConsumer = null;
     private Function<List<String>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private Function<List<String>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
     private List<String> value;
     private List<String> value;
     private boolean expended = false;
     private boolean expended = false;
-    private Function<BaseListEntry, StringListListEntry.StringListCell> createNewInstance;
+    private Function<StringListListEntry, StringListListEntry.StringListCell> createNewInstance;
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     private boolean deleteButtonEnabled = true, insertInFront = true;
-    
+
     public StringListBuilder(String resetButtonKey, String fieldNameKey, List<String> value) {
     public StringListBuilder(String resetButtonKey, String fieldNameKey, List<String> value) {
         super(resetButtonKey, fieldNameKey);
         super(resetButtonKey, fieldNameKey);
         this.value = value;
         this.value = value;
     }
     }
-    
+
     public Function<String, Optional<String>> getCellErrorSupplier() {
     public Function<String, Optional<String>> getCellErrorSupplier() {
         return cellErrorSupplier;
         return cellErrorSupplier;
     }
     }
-    
+
     public StringListBuilder setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
     public StringListBuilder setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setErrorSupplier(Function<List<String>, Optional<String>> errorSupplier) {
     public StringListBuilder setErrorSupplier(Function<List<String>, Optional<String>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         this.errorSupplier = errorSupplier;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
     public StringListBuilder setDeleteButtonEnabled(boolean deleteButtonEnabled) {
         this.deleteButtonEnabled = deleteButtonEnabled;
         this.deleteButtonEnabled = deleteButtonEnabled;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setInsertInFront(boolean insertInFront) {
     public StringListBuilder setInsertInFront(boolean insertInFront) {
         this.insertInFront = insertInFront;
         this.insertInFront = insertInFront;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setAddButtonTooltip(String addTooltip) {
     public StringListBuilder setAddButtonTooltip(String addTooltip) {
         this.addTooltip = addTooltip;
         this.addTooltip = addTooltip;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setRemoveButtonTooltip(String removeTooltip) {
     public StringListBuilder setRemoveButtonTooltip(String removeTooltip) {
         this.removeTooltip = removeTooltip;
         this.removeTooltip = removeTooltip;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder requireRestart() {
     public StringListBuilder requireRestart() {
         requireRestart(true);
         requireRestart(true);
         return this;
         return this;
     }
     }
-    
-    public StringListBuilder setCreateNewInstance(Function<BaseListEntry, StringListListEntry.StringListCell> createNewInstance) {
+
+    public StringListBuilder setCreateNewInstance(Function<StringListListEntry, StringListListEntry.StringListCell> createNewInstance) {
         this.createNewInstance = createNewInstance;
         this.createNewInstance = createNewInstance;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setExpended(boolean expended) {
     public StringListBuilder setExpended(boolean expended) {
         this.expended = expended;
         this.expended = expended;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setSaveConsumer(Consumer<List<String>> saveConsumer) {
     public StringListBuilder setSaveConsumer(Consumer<List<String>> saveConsumer) {
         this.saveConsumer = saveConsumer;
         this.saveConsumer = saveConsumer;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setDefaultValue(Supplier<List<String>> defaultValue) {
     public StringListBuilder setDefaultValue(Supplier<List<String>> defaultValue) {
         this.defaultValue = defaultValue;
         this.defaultValue = defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setDefaultValue(List<String> defaultValue) {
     public StringListBuilder setDefaultValue(List<String> defaultValue) {
         this.defaultValue = () -> defaultValue;
         this.defaultValue = () -> defaultValue;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
     public StringListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setTooltipSupplier(Function<List<String>, Optional<String[]>> tooltipSupplier) {
     public StringListBuilder setTooltipSupplier(Function<List<String>, Optional<String[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         this.tooltipSupplier = tooltipSupplier;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setTooltip(Optional<String[]> tooltip) {
     public StringListBuilder setTooltip(Optional<String[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         this.tooltipSupplier = list -> tooltip;
         return this;
         return this;
     }
     }
-    
+
     public StringListBuilder setTooltip(String... tooltip) {
     public StringListBuilder setTooltip(String... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
         return this;
     }
     }
-    
+
     @Override
     @Override
     public StringListListEntry build() {
     public StringListListEntry build() {
         StringListListEntry entry = new StringListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart());
         StringListListEntry entry = new StringListListEntry(getFieldNameKey(), value, expended, null, saveConsumer, defaultValue, getResetButtonKey(), isRequireRestart());
@@ -123,5 +122,5 @@ public class StringListBuilder extends FieldBuilder<List<String>, StringListList
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
             entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
         return entry;
         return entry;
     }
     }
-    
-}
+
+}