diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee8647ae..0dffe6a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+- Fixed profile combo not refreshing when profiles are added or removed after session start
- Added ability to manually add, rename, and sort models in the Model Aliases dialog
- Fixed missing Claude Code icon in Tools → Options dialog
diff --git a/pom.xml b/pom.xml
index 602c5df6..23c24755 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.nbplugins
netbeans-plugin-claude-code-gui
- 1.1.3-SNAPSHOT
+ 1.1.4-SNAPSHOT
nbm
Netbeans Plugin Claude Code GUI
NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE.
diff --git a/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanel.java b/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanel.java
index 641d1490..f77bdf54 100644
--- a/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanel.java
+++ b/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanel.java
@@ -179,6 +179,15 @@ public ClaudeSessionSelectorPanel(File initialDirectory, OpenListener openListen
// Pre-fill from selected profile; update when profile changes
profileCombo.addActionListener(e -> onProfileSelected());
+ profileCombo.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
+ @Override public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent e) {
+ String current = (String) profileCombo.getSelectedItem();
+ populateProfileCombo();
+ if (current != null) profileCombo.setSelectedItem(current);
+ }
+ @Override public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent e) {}
+ @Override public void popupMenuCanceled(javax.swing.event.PopupMenuEvent e) {}
+ });
onProfileSelected();
// --- open button ---
diff --git a/src/test/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanelTest.java b/src/test/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanelTest.java
index 495c772b..2605f352 100644
--- a/src/test/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanelTest.java
+++ b/src/test/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionSelectorPanelTest.java
@@ -189,6 +189,44 @@ void projectComboSortIsStableForEqualCaseNames() {
"Second group must be 'beta' variants");
}
+ // -------------------------------------------------------------------------
+ // Profile combo refresh on popup open
+ // -------------------------------------------------------------------------
+
+ @Test
+ void profileComboRefreshesOnPopupOpen() {
+ ClaudeSessionSelectorPanel p = panel();
+ javax.swing.JComboBox> combo = getProfileCombo(p);
+ int countBefore = combo.getItemCount();
+ assertTrue(countBefore >= 1, "Profile combo must have at least the Default profile");
+
+ // Fire the popup-will-become-visible event (simulates user opening the dropdown)
+ for (javax.swing.event.PopupMenuListener l : combo.getPopupMenuListeners()) {
+ l.popupMenuWillBecomeVisible(new javax.swing.event.PopupMenuEvent(combo));
+ }
+
+ assertEquals(countBefore, combo.getItemCount(),
+ "Profile combo item count must stay the same after refresh when profiles did not change");
+ }
+
+ @Test
+ void profileComboPreservesSelectionAfterRefresh() {
+ ClaudeSessionSelectorPanel p = panel();
+ javax.swing.JComboBox> combo = getProfileCombo(p);
+
+ // Select the first profile (Default)
+ combo.setSelectedIndex(0);
+ String selectedBefore = (String) combo.getSelectedItem();
+
+ // Fire the popup listener
+ for (javax.swing.event.PopupMenuListener l : combo.getPopupMenuListeners()) {
+ l.popupMenuWillBecomeVisible(new javax.swing.event.PopupMenuEvent(combo));
+ }
+
+ assertEquals(selectedBefore, combo.getSelectedItem(),
+ "Profile selection must be preserved after refresh when the profile still exists");
+ }
+
// -------------------------------------------------------------------------
// History persistence helpers
// -------------------------------------------------------------------------
@@ -244,6 +282,18 @@ private static int getProfileComboIndex(ClaudeSessionSelectorPanel panel) {
return nonEditable.size() > 1 ? nonEditable.get(1).getSelectedIndex() : -1;
}
+ /** Returns the profile JComboBox (second non-editable combo). */
+ private static javax.swing.JComboBox> getProfileCombo(ClaudeSessionSelectorPanel panel) {
+ java.util.List> nonEditable = new java.util.ArrayList<>();
+ for (java.awt.Component c : getAllComponents(panel)) {
+ if (c instanceof javax.swing.JComboBox> combo && !combo.isEditable()) {
+ nonEditable.add(combo);
+ }
+ }
+ assertTrue(nonEditable.size() > 1, "Expected at least 2 non-editable combos (project + profile)");
+ return nonEditable.get(1);
+ }
+
/** Recursively collects all components from a container. */
private static java.util.List getAllComponents(java.awt.Container root) {
java.util.List result = new java.util.ArrayList<>();