diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java index 766b34c57c..efda12a992 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxManager.java @@ -29,6 +29,7 @@ import com.google.common.collect.ComparisonChain; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Predicate; @@ -71,12 +72,12 @@ public class InfoBoxManager synchronized (this) { - int idx = Collections.binarySearch(infoBoxes, infoBox, (b1, b2) -> ComparisonChain + int idx = findInsertionIndex(infoBoxes, infoBox, (b1, b2) -> ComparisonChain .start() .compare(b1.getPriority(), b2.getPriority()) .compare(b1.getPlugin().getName(), b2.getPlugin().getName()) .result()); - infoBoxes.add(idx < 0 ? -idx - 1 : idx, infoBox); + infoBoxes.add(idx, infoBox); } BufferedImage image = infoBox.getImage(); @@ -150,4 +151,38 @@ public class InfoBoxManager infoBox.setScaledImage(resultImage); } + + /** + * Find insertion point for the given key into the given sorted list. If key already exists in the list, + * return the index after the last occurrence. + * @param list + * @param key + * @param c + * @param + * @return + */ + private static int findInsertionIndex(List list, T key, Comparator c) + { + int idx = Collections.binarySearch(list, key, c); + + if (idx < 0) + { + // key isn't found in the list + return -idx - 1; + } + + // list(idx) is equal to key, so it is not necessary to recheck it + for (int i = idx + 1; i < list.size(); ++i) + { + T cur = list.get(i); + int cmp = c.compare(cur, key); + if (cmp > 0) + { + // this is the first element which is greater + return i; + } + } + + return list.size(); + } } diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/infobox/InfoBoxManagerTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/infobox/InfoBoxManagerTest.java index e0ce1e6a6e..49c9c2c484 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/infobox/InfoBoxManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/infobox/InfoBoxManagerTest.java @@ -114,5 +114,8 @@ public class InfoBoxManagerTest infoBoxManager.addInfoBox(new TestInfobox(InfoBoxPriority.MED, "three")); assertEquals(3, infoBoxManager.getInfoBoxes().size()); + assertEquals("one", infoBoxManager.getInfoBoxes().get(0).getText()); + assertEquals("two", infoBoxManager.getInfoBoxes().get(1).getText()); + assertEquals("three", infoBoxManager.getInfoBoxes().get(2).getText()); } } \ No newline at end of file