From 05ba61d44c316e9a1d9e6d7207cbbd5564a7329c Mon Sep 17 00:00:00 2001 From: sdburns1998 Date: Thu, 6 Jun 2019 15:30:36 +0200 Subject: [PATCH] Debounce textfield input so the parse function isn't run every keypress --- .../client/plugins/config/ConfigPanel.java | 20 +++---- .../DeferredDocumentChangedListener.java | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/config/DeferredDocumentChangedListener.java 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 3e3f5aa0bf..1daaad5a29 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 @@ -36,8 +36,6 @@ import java.awt.Rectangle; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; @@ -468,9 +466,8 @@ public class ConfigPanel extends PluginPanel try { Method parse = item.clazz().getMethod(item.method(), String.class); - boolean result = (boolean) parse.invoke(null, value); - return result; + return (boolean) parse.invoke(null, value); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { @@ -506,7 +503,7 @@ public class ConfigPanel extends PluginPanel openGroupConfigPanel(listItem, config, cd, false); } - void openGroupConfigPanel(PluginListItem listItem, Config config, ConfigDescriptor cd, boolean refresh) + private void openGroupConfigPanel(PluginListItem listItem, Config config, ConfigDescriptor cd, boolean refresh) { showingPluginList = false; @@ -781,17 +778,14 @@ public class ConfigPanel extends PluginPanel parsingLabel.setHorizontalAlignment(SwingConstants.CENTER); parsingLabel.setPreferredSize(new Dimension(PANEL_WIDTH, 15)); - textField.addKeyListener(new KeyAdapter() - { - public void keyReleased(KeyEvent e) + DeferredDocumentChangedListener listener = new DeferredDocumentChangedListener(); + listener.addChangeListener(e -> { + if (cid.getItem().parse()) { - ConfigItem item = cid.getItem(); - if (item.parse()) - { - parseLabel(item, parsingLabel, textField.getText()); - } + parseLabel(cid.getItem(), parsingLabel, textField.getText()); } }); + textField.getDocument().addDocumentListener(listener); item.add(textField, BorderLayout.CENTER); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/DeferredDocumentChangedListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/DeferredDocumentChangedListener.java new file mode 100644 index 0000000000..c8ce0b37dc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/DeferredDocumentChangedListener.java @@ -0,0 +1,58 @@ +package net.runelite.client.plugins.config; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.Timer; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +class DeferredDocumentChangedListener implements DocumentListener +{ + private Timer timer; + private List listeners; + + DeferredDocumentChangedListener() + { + listeners = new ArrayList<>(25); + timer = new Timer(350, e -> fireStateChanged()); + timer.setRepeats(false); + } + + void addChangeListener(ChangeListener listener) + { + listeners.add(listener); + } + + private void fireStateChanged() + { + if (!listeners.isEmpty()) + { + ChangeEvent evt = new ChangeEvent(this); + for (ChangeListener listener : listeners) + { + listener.stateChanged(evt); + } + } + } + + @Override + public void insertUpdate(DocumentEvent e) + { + timer.restart(); + } + + @Override + public void removeUpdate(DocumentEvent e) + { + timer.restart(); + } + + @Override + public void changedUpdate(DocumentEvent e) + { + timer.restart(); + } + +}