diff --git a/Client/src/main/java/dev/blackilykat/pmp/client/ClientIds.java b/Client/src/main/java/dev/blackilykat/pmp/client/ClientIds.java
new file mode 100644
index 0000000..dff69f6
--- /dev/null
+++ b/Client/src/main/java/dev/blackilykat/pmp/client/ClientIds.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2026 Blackilykat and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.blackilykat.pmp.client;
+
+import dev.blackilykat.pmp.FilterInfo;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.IntPredicate;
+
+public final class ClientIds {
+ private ClientIds() {}
+
+ public static int randomFilterId() {
+ return randomUnusedId(id -> {
+ for(Filter filter : ClientStorage.MAIN.filters.get()) {
+ if(filter.id == id) {
+ return true;
+ }
+ }
+
+ for(FilterInfo filterInfo : ClientStorage.MAIN.lastKnownServerFilters.get()) {
+ if(filterInfo.id() == id) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+ }
+
+ public static int randomHeaderId() {
+ return randomUnusedId(id -> {
+ for(Header header : ClientStorage.MAIN.headers.get()) {
+ if(header.id == id) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+ }
+
+ private static int randomUnusedId(IntPredicate isUsed) {
+ int id;
+ do {
+ id = ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE);
+ } while(isUsed.test(id));
+ return id;
+ }
+}
diff --git a/Client/src/main/java/dev/blackilykat/pmp/client/ClientStorage.java b/Client/src/main/java/dev/blackilykat/pmp/client/ClientStorage.java
index 92fd7fe..b06282e 100644
--- a/Client/src/main/java/dev/blackilykat/pmp/client/ClientStorage.java
+++ b/Client/src/main/java/dev/blackilykat/pmp/client/ClientStorage.java
@@ -52,8 +52,6 @@ public static class Main extends Storage {
public StoredMap tracks = new StoredMap<>(String.class, Track.class, this);
public StoredList headers = new StoredList<>(Header.class, this);
public StoredList filters = new StoredList<>(Filter.class, this);
- public StoredInt currentFilterID = new StoredInt(this, 0);
- public StoredInt currentHeaderID = new StoredInt(this, 0);
public Stored serverAddress = new Stored<>(String.class, this, "localhost");
public StoredInt serverPort = new StoredInt(this, PMPConnection.DEFAULT_MESSAGE_PORT);
public StoredInt serverFilePort = new StoredInt(this, PMPConnection.DEFAULT_FILE_PORT);
diff --git a/Client/src/main/java/dev/blackilykat/pmp/client/Filter.java b/Client/src/main/java/dev/blackilykat/pmp/client/Filter.java
index 7e0f4f8..7fe47cf 100644
--- a/Client/src/main/java/dev/blackilykat/pmp/client/Filter.java
+++ b/Client/src/main/java/dev/blackilykat/pmp/client/Filter.java
@@ -43,7 +43,7 @@ public class Filter {
public String key;
public Filter(String key) {
- this(ClientStorage.MAIN.currentFilterID.getAndIncrement(), key);
+ this(ClientIds.randomFilterId(), key);
}
@JsonCreator
diff --git a/Client/src/main/java/dev/blackilykat/pmp/client/Library.java b/Client/src/main/java/dev/blackilykat/pmp/client/Library.java
index ff223f1..14a456a 100644
--- a/Client/src/main/java/dev/blackilykat/pmp/client/Library.java
+++ b/Client/src/main/java/dev/blackilykat/pmp/client/Library.java
@@ -394,11 +394,10 @@ public static void init() {
if(ClientStorage.MAIN.headers.empty()) {
- ClientStorage.MAIN.headers.add(new Header(0, "N°", "tracknumber"));
- ClientStorage.MAIN.headers.add(new Header(1, "Title", "title"));
- ClientStorage.MAIN.headers.add(new Header(2, "Artist", "artist"));
- ClientStorage.MAIN.headers.add(new Header(3, "Duration", "duration"));
- ClientStorage.MAIN.currentHeaderID.set(4);
+ ClientStorage.MAIN.headers.add(new Header(ClientIds.randomHeaderId(), "N°", "tracknumber"));
+ ClientStorage.MAIN.headers.add(new Header(ClientIds.randomHeaderId(), "Title", "title"));
+ ClientStorage.MAIN.headers.add(new Header(ClientIds.randomHeaderId(), "Artist", "artist"));
+ ClientStorage.MAIN.headers.add(new Header(ClientIds.randomHeaderId(), "Duration", "duration"));
} else {
for(Header header : ClientStorage.MAIN.headers.get()) {
header.updateType();
diff --git a/Client/src/main/java/dev/blackilykat/pmp/client/gui/TracksPanel.java b/Client/src/main/java/dev/blackilykat/pmp/client/gui/TracksPanel.java
index 556e7d8..9a9d259 100644
--- a/Client/src/main/java/dev/blackilykat/pmp/client/gui/TracksPanel.java
+++ b/Client/src/main/java/dev/blackilykat/pmp/client/gui/TracksPanel.java
@@ -19,6 +19,7 @@
import com.github.weisj.jsvg.view.ViewBox;
import dev.blackilykat.pmp.Order;
+import dev.blackilykat.pmp.client.ClientIds;
import dev.blackilykat.pmp.client.ClientStorage;
import dev.blackilykat.pmp.client.Header;
import dev.blackilykat.pmp.client.Library;
@@ -312,7 +313,7 @@ private static JMenuItem buildAddHeaderItem() {
return;
}
- Header header = new Header(ClientStorage.MAIN.currentHeaderID.getAndIncrement(), label.get(), key.get());
+ Header header = new Header(ClientIds.randomHeaderId(), label.get(), key.get());
Library.addHeader(header);