From 81fc0c571d2ac355949a1bfdd7f6c97be369542c Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 9 Jan 2025 11:45:05 -0500 Subject: [PATCH] config panel: respect range on unit fields This fixes integer fields with both Range and Unit, as setting the unit formatter replaces the default formatter which is what imposes the range limit. This also fixes double fields with a unit, due to the Integer.valueOf() call failing to parse. --- .../client/plugins/config/ConfigPanel.java | 8 ++++-- .../plugins/config/NotificationPanel.java | 2 +- .../UICalculatorInputArea.java | 6 ++--- .../client/ui/UnitFormatterFactory.java | 26 +++++++------------ 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index e2e2584beff..4bb77860162 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -475,7 +475,9 @@ private JSpinner createIntSpinner(ConfigDescriptor cd, ConfigItemDescriptor cid) Units units = cid.getUnits(); if (units != null) { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units.value())); + // The existing DefaultFormatterFactory with a NumberEditorFormatter. Its model is the same SpinnerModel above. + JFormattedTextField.AbstractFormatterFactory delegate = spinnerTextField.getFormatterFactory(); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(delegate, units.value())); } return spinner; @@ -495,7 +497,9 @@ private JSpinner createDoubleSpinner(ConfigDescriptor cd, ConfigItemDescriptor c Units units = cid.getUnits(); if (units != null) { - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units.value())); + // The existing DefaultFormatterFactory with a NumberEditorFormatter. Its model is the same SpinnerModel above. + JFormattedTextField.AbstractFormatterFactory delegate = spinnerTextField.getFormatterFactory(); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(delegate, units.value())); } return spinner; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/NotificationPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/NotificationPanel.java index 56e42e869ed..b0d49069777 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/NotificationPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/NotificationPanel.java @@ -215,7 +215,7 @@ private JSpinner createIntSpinner(int min, int max, int value, String unit) Component editor = spinner.getEditor(); JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); spinnerTextField.setColumns(6); - spinnerTextField.setFormatterFactory(new UnitFormatterFactory(unit)); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(spinnerTextField.getFormatterFactory(), unit)); return spinner; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java index 1a139a18c4a..5021757eb78 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java @@ -25,6 +25,8 @@ */ package net.runelite.client.plugins.skillcalculator; +import com.google.inject.Inject; +import com.google.inject.Singleton; import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; @@ -37,8 +39,6 @@ import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; import javax.swing.border.EmptyBorder; -import com.google.inject.Inject; -import com.google.inject.Singleton; import lombok.Getter; import static net.runelite.client.plugins.skillcalculator.SkillCalculator.MAX_XP_MULTIPLIER; import net.runelite.client.ui.ColorScheme; @@ -194,7 +194,7 @@ private JSpinner addMultiplicationSpinnerComponent(String label, int max) JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) uiInput.getEditor(); JFormattedTextField spinnerTextField = editor.getTextField(); spinnerTextField.setHorizontalAlignment(JTextField.LEFT); - spinnerTextField.setFormatterFactory(new UnitFormatterFactory("x")); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(spinnerTextField.getFormatterFactory(), "x")); uiInput.setBackground(ColorScheme.DARKER_GRAY_COLOR); uiInput.setBorder(new EmptyBorder(5, 7, 5, 7)); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/UnitFormatterFactory.java b/runelite-client/src/main/java/net/runelite/client/ui/UnitFormatterFactory.java index 7259140c74d..26750f88c6b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/UnitFormatterFactory.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/UnitFormatterFactory.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Hydrox6 + * Copyright (c) 2025 Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,21 +31,20 @@ import javax.swing.JFormattedTextField; import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor final class UnitFormatter extends JFormattedTextField.AbstractFormatter { + private final JFormattedTextField.AbstractFormatter delegate; private final String units; - UnitFormatter(String units) - { - this.units = units; - } - @Override public Object stringToValue(final String text) throws ParseException { final String trimmedText; - // Using the spinner controls causes the value to have the unit on the end, so remove it + // Using the spinner controls causes the value to have the unit on the end, so remove it. + // This isn't actually required because NumberFormatter is very lax and will error out + // when encountering the unit, but we do it anyway. if (text.endsWith(units)) { trimmedText = text.substring(0, text.length() - units.length()); @@ -54,14 +54,7 @@ public Object stringToValue(final String text) throws ParseException trimmedText = text; } - try - { - return Integer.valueOf(trimmedText); - } - catch (NumberFormatException e) - { - throw new ParseException(trimmedText + " is not an integer.", 0); // NOPMD: PreserveStackTrace - } + return delegate.stringToValue(trimmedText); } @Override @@ -74,12 +67,13 @@ public String valueToString(final Object value) @RequiredArgsConstructor public final class UnitFormatterFactory extends JFormattedTextField.AbstractFormatterFactory { + private final JFormattedTextField.AbstractFormatterFactory delegateFactory; private final String units; - private final Map formatters = new HashMap<>(); + private final Map formatters = new HashMap<>(1); @Override public JFormattedTextField.AbstractFormatter getFormatter(final JFormattedTextField tf) { - return formatters.computeIfAbsent(tf, (key) -> new UnitFormatter(units)); + return formatters.computeIfAbsent(tf, (key) -> new UnitFormatter(delegateFactory.getFormatter(key), units)); } }