From 9819f63c111d8240114bcab3ae2c79084963f522 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Thu, 9 Apr 2026 19:35:37 +0900 Subject: [PATCH 1/3] feat: print the project name in the title bar Co-authored-by: Cursor --- .../java/core/packetproxy/PacketProxy.java | 4 +- .../java/core/packetproxy/gui/GUIMain.java | 78 ++++++++++++++++--- 2 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/main/java/core/packetproxy/PacketProxy.java b/src/main/java/core/packetproxy/PacketProxy.java index 31f61e0c..8ecf5ee3 100644 --- a/src/main/java/core/packetproxy/PacketProxy.java +++ b/src/main/java/core/packetproxy/PacketProxy.java @@ -18,7 +18,6 @@ import java.io.File; import java.sql.SQLException; import javax.swing.*; -import packetproxy.common.AppVersion; import packetproxy.common.I18nString; import packetproxy.common.Utils; import packetproxy.gui.GUIMain; @@ -118,8 +117,7 @@ public void start() throws Exception { } private void startGUI() throws Exception { - var version = AppVersion.get(); - gui = GUIMain.getInstance(String.format("PacketProxy %s", version)); + gui = GUIMain.getInstance(); gui.setVisible(true); } } diff --git a/src/main/java/core/packetproxy/gui/GUIMain.java b/src/main/java/core/packetproxy/gui/GUIMain.java index f91cac5e..a5de5385 100644 --- a/src/main/java/core/packetproxy/gui/GUIMain.java +++ b/src/main/java/core/packetproxy/gui/GUIMain.java @@ -25,14 +25,20 @@ import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.nio.file.Path; import javax.swing.*; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; +import org.apache.commons.io.FilenameUtils; +import packetproxy.common.AppVersion; import packetproxy.common.FontManager; import packetproxy.common.I18nString; +import packetproxy.model.Database; +import packetproxy.model.Database.DatabaseMessage; import packetproxy.model.InterceptModel; +import packetproxy.model.PropertyChangeEventType; import packetproxy.util.PacketProxyUtility; public class GUIMain extends JFrame implements PropertyChangeListener { @@ -50,23 +56,16 @@ public class GUIMain extends JFrame implements PropertyChangeListener { private GUIVulCheckHelper gui_vulcheckhelper; private GUILog gui_log; private InterceptModel interceptModel; + private String version; public enum Panes { HISTORY, INTERCEPT, RESENDER, VULCHECKHELPER, BULKSENDER, EXTENSIONS, OPTIONS, LOG }; - public static GUIMain getInstance(String title) throws Exception { - if (instance == null) { - - instance = new GUIMain(title); - } - return instance; - } - public static GUIMain getInstance() throws Exception { if (instance == null) { - throw new Exception("GUIMain instance not found."); + instance = new GUIMain(); } return instance; } @@ -97,13 +96,20 @@ private String getPaneString(Panes num) { return null; } - private GUIMain(String title) { + private GUIMain() { try { + this.version = AppVersion.get(); setIcon(); gui_history = initProjectAndHistory(); setLookandFeel(); - setTitle(title); + + // Register for database events + Database.getInstance().addPropertyChangeListener(this); + + // Set initial title with project name + updateTitle(); + setBounds(10, 10, 1100, 850); enableFullScreenForMac(this); @@ -326,8 +332,48 @@ private void setInterceptDownLight() { tabbedpane.repaint(); } + private String getProjectDisplayName() { + try { + Database db = Database.getInstance(); + Path dbPath = db.getDatabasePath(); + + if (dbPath == null) { + return "Unknown"; + } + + String fileName = dbPath.getFileName().toString(); + + // Handle default database + if (fileName.equals("resources.sqlite3")) { + return "Default"; + } + + // Handle temporary/loaded databases + if (fileName.equals("resources_temp.sqlite3")) { + return "Temporary"; + } + + // Handle temporary projects (format: packetproxy-yyyyMMdd-HHmmss.sqlite3) + if (fileName.startsWith("packetproxy-") && fileName.matches("packetproxy-\\d{8}-\\d{6}\\.sqlite3")) { + return "Temporary"; + } + + // Extract project name from filename (remove .sqlite3 extension) + return FilenameUtils.removeExtension(fileName); + } catch (Exception e) { + return "Unknown"; + } + } + + public void updateTitle() { + String projectName = getProjectDisplayName(); + String titleText = String.format("PacketProxy %s - %s", version, projectName); + setTitle(titleText); + } + @Override public void propertyChange(PropertyChangeEvent evt) { + // Handle intercept model events if (interceptModel.getData() == null) { setInterceptDownLight(); @@ -335,5 +381,15 @@ public void propertyChange(PropertyChangeEvent evt) { setInterceptHighLight(); } + + // Handle database reconnection events to update title + if (PropertyChangeEventType.DATABASE_MESSAGE.matches(evt)) { + if (evt.getNewValue() instanceof DatabaseMessage) { + DatabaseMessage msg = (DatabaseMessage) evt.getNewValue(); + if (msg == DatabaseMessage.RECONNECT) { + SwingUtilities.invokeLater(this::updateTitle); + } + } + } } } From 5673af05a1f5badb79bac4bab1329462ad2fc340 Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Fri, 29 May 2026 12:54:23 +0900 Subject: [PATCH 2/3] refactor(gui): remove redundant version field from GUIMain Use AppVersion.get() in updateTitle() instead of caching version in a field. Co-authored-by: Cursor --- src/main/java/core/packetproxy/gui/GUIMain.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/core/packetproxy/gui/GUIMain.java b/src/main/java/core/packetproxy/gui/GUIMain.java index a5de5385..ec677f86 100644 --- a/src/main/java/core/packetproxy/gui/GUIMain.java +++ b/src/main/java/core/packetproxy/gui/GUIMain.java @@ -56,7 +56,6 @@ public class GUIMain extends JFrame implements PropertyChangeListener { private GUIVulCheckHelper gui_vulcheckhelper; private GUILog gui_log; private InterceptModel interceptModel; - private String version; public enum Panes { HISTORY, INTERCEPT, RESENDER, VULCHECKHELPER, BULKSENDER, EXTENSIONS, OPTIONS, LOG @@ -98,8 +97,6 @@ private String getPaneString(Panes num) { private GUIMain() { try { - this.version = AppVersion.get(); - setIcon(); gui_history = initProjectAndHistory(); setLookandFeel(); @@ -366,8 +363,8 @@ private String getProjectDisplayName() { } public void updateTitle() { - String projectName = getProjectDisplayName(); - String titleText = String.format("PacketProxy %s - %s", version, projectName); + var projectName = getProjectDisplayName(); + var titleText = String.format("PacketProxy %s - %s", AppVersion.get(), projectName); setTitle(titleText); } From f3f1ba6ecd84e240f6e177b114056bce022baf0a Mon Sep 17 00:00:00 2001 From: Hiroki Tokunaga Date: Fri, 29 May 2026 13:25:25 +0900 Subject: [PATCH 3/3] refactor(gui): extract ProjectDisplayName for title bar Move DB display-name rules into packetproxy.common and add unit tests. Co-authored-by: Cursor --- .../common/ProjectDisplayName.java | 59 +++++++++++++++++++ .../java/core/packetproxy/gui/GUIMain.java | 39 +----------- .../common/ProjectDisplayNameTest.java | 43 ++++++++++++++ 3 files changed, 104 insertions(+), 37 deletions(-) create mode 100644 src/main/java/core/packetproxy/common/ProjectDisplayName.java create mode 100644 src/test/java/packetproxy/common/ProjectDisplayNameTest.java diff --git a/src/main/java/core/packetproxy/common/ProjectDisplayName.java b/src/main/java/core/packetproxy/common/ProjectDisplayName.java new file mode 100644 index 00000000..c6c9d125 --- /dev/null +++ b/src/main/java/core/packetproxy/common/ProjectDisplayName.java @@ -0,0 +1,59 @@ +/* + * Copyright 2026 DeNA Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package packetproxy.common; + +import org.apache.commons.io.FilenameUtils; +import packetproxy.model.Database; + +public final class ProjectDisplayName { + + private static final String UNKNOWN = "Unknown"; + private static final String DEFAULT = "Default"; + private static final String TEMPORARY = "Temporary"; + + private ProjectDisplayName() { + } + + public static String get() { + try { + var dbPath = Database.getInstance().getDatabasePath(); + if (dbPath == null) { + + return UNKNOWN; + } + return fromFileName(dbPath.getFileName().toString()); + } catch (Exception e) { + + return UNKNOWN; + } + } + + static String fromFileName(String fileName) { + if (fileName.equals("resources.sqlite3")) { + + return DEFAULT; + } + if (fileName.equals("resources_temp.sqlite3")) { + + return TEMPORARY; + } + if (fileName.startsWith("packetproxy-") && fileName.matches("packetproxy-\\d{8}-\\d{6}\\.sqlite3")) { + + return TEMPORARY; + } + return FilenameUtils.removeExtension(fileName); + } +} diff --git a/src/main/java/core/packetproxy/gui/GUIMain.java b/src/main/java/core/packetproxy/gui/GUIMain.java index ec677f86..dadbecb0 100644 --- a/src/main/java/core/packetproxy/gui/GUIMain.java +++ b/src/main/java/core/packetproxy/gui/GUIMain.java @@ -25,16 +25,15 @@ import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.nio.file.Path; import javax.swing.*; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; -import org.apache.commons.io.FilenameUtils; import packetproxy.common.AppVersion; import packetproxy.common.FontManager; import packetproxy.common.I18nString; +import packetproxy.common.ProjectDisplayName; import packetproxy.model.Database; import packetproxy.model.Database.DatabaseMessage; import packetproxy.model.InterceptModel; @@ -329,42 +328,8 @@ private void setInterceptDownLight() { tabbedpane.repaint(); } - private String getProjectDisplayName() { - try { - Database db = Database.getInstance(); - Path dbPath = db.getDatabasePath(); - - if (dbPath == null) { - return "Unknown"; - } - - String fileName = dbPath.getFileName().toString(); - - // Handle default database - if (fileName.equals("resources.sqlite3")) { - return "Default"; - } - - // Handle temporary/loaded databases - if (fileName.equals("resources_temp.sqlite3")) { - return "Temporary"; - } - - // Handle temporary projects (format: packetproxy-yyyyMMdd-HHmmss.sqlite3) - if (fileName.startsWith("packetproxy-") && fileName.matches("packetproxy-\\d{8}-\\d{6}\\.sqlite3")) { - return "Temporary"; - } - - // Extract project name from filename (remove .sqlite3 extension) - return FilenameUtils.removeExtension(fileName); - } catch (Exception e) { - return "Unknown"; - } - } - public void updateTitle() { - var projectName = getProjectDisplayName(); - var titleText = String.format("PacketProxy %s - %s", AppVersion.get(), projectName); + var titleText = String.format("PacketProxy %s - %s", AppVersion.get(), ProjectDisplayName.get()); setTitle(titleText); } diff --git a/src/test/java/packetproxy/common/ProjectDisplayNameTest.java b/src/test/java/packetproxy/common/ProjectDisplayNameTest.java new file mode 100644 index 00000000..9c5db1c6 --- /dev/null +++ b/src/test/java/packetproxy/common/ProjectDisplayNameTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2026 DeNA Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package packetproxy.common; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ProjectDisplayNameTest { + + @Test + public void fromFileName_defaultDatabase() { + assertEquals("Default", ProjectDisplayName.fromFileName("resources.sqlite3")); + } + + @Test + public void fromFileName_namedProject() { + assertEquals("myproject", ProjectDisplayName.fromFileName("myproject.sqlite3")); + } + + @Test + public void fromFileName_temporaryTimestampedProject() { + assertEquals("Temporary", ProjectDisplayName.fromFileName("packetproxy-20260409-193537.sqlite3")); + } + + @Test + public void fromFileName_resourcesTemp() { + assertEquals("Temporary", ProjectDisplayName.fromFileName("resources_temp.sqlite3")); + } +}