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/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 f91cac5e..dadbecb0 100644 --- a/src/main/java/core/packetproxy/gui/GUIMain.java +++ b/src/main/java/core/packetproxy/gui/GUIMain.java @@ -30,9 +30,14 @@ import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; +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; +import packetproxy.model.PropertyChangeEventType; import packetproxy.util.PacketProxyUtility; public class GUIMain extends JFrame implements PropertyChangeListener { @@ -55,18 +60,10 @@ 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 +94,18 @@ private String getPaneString(Panes num) { return null; } - private GUIMain(String title) { + private GUIMain() { try { - 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 +328,14 @@ private void setInterceptDownLight() { tabbedpane.repaint(); } + public void updateTitle() { + var titleText = String.format("PacketProxy %s - %s", AppVersion.get(), ProjectDisplayName.get()); + setTitle(titleText); + } + @Override public void propertyChange(PropertyChangeEvent evt) { + // Handle intercept model events if (interceptModel.getData() == null) { setInterceptDownLight(); @@ -335,5 +343,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); + } + } + } } } 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")); + } +}