diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java b/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java index 73d957c..fcdb41c 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java @@ -202,7 +202,8 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener { } @Override - public void onConnectBookmark(Bookmark bookmark) { + public void onConnectBookmark(Bookmark bookmark, boolean newTab) { + if (newTab) selectTab(newTab()); connectToBookmark(bookmark); } @@ -571,21 +572,31 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener { */ private void startConnection(String address, int port, String nickname, String password, String identityId, String channel, String channelPassword) { + startConnection(address, port, nickname, password, identityId, channel, channelPassword, false); + } + + /** + * @param replaceCurrent connect on the current tab, leaving the server it is on, instead of + * moving to a free tab + */ + private void startConnection(String address, int port, String nickname, String password, String identityId, + String channel, String channelPassword, boolean replaceCurrent) { settings.lastAddress = address + ":" + port; settings.nickname = nickname; settings.serverPassword = password; settings.save(); - ServerTab tab = tabForNewConnection(); + ServerTab tab = (replaceCurrent && selected != null) ? selected : tabForNewConnection(); // The first connection to come up takes the microphone; later ones are muted // until the user activates them. if (micTab == null) setMicTab(tab); - tab.connect(address, port, nickname, password, identityId, channel, channelPassword); + tab.switchTo(address, port, nickname, password, identityId, channel, channelPassword); } + /** Connects on the current tab, leaving whatever server it is on. */ private void connectToBookmark(Bookmark b) { String nick = (b.nickname != null && !b.nickname.isBlank()) ? b.nickname : settings.nickname; - startConnection(b.address, b.port, nick, b.password, b.identityId, b.channel, b.channelPassword); + startConnection(b.address, b.port, nick, b.password, b.identityId, b.channel, b.channelPassword, true); } private void addCurrentServerBookmark() { diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/MainMenuBar.java b/ts3-client/swing/src/main/java/com/ts3client/ui/MainMenuBar.java index 7818c8c..4bee088 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/MainMenuBar.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/MainMenuBar.java @@ -8,6 +8,10 @@ import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.KeyStroke; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; /** * The main window's menu bar: Connections, Bookmarks, Self, Tools and Help. @@ -45,7 +49,8 @@ final class MainMenuBar extends JMenuBar { void onShowAbout(); - void onConnectBookmark(Bookmark bookmark); + /** @param newTab open the server in a new tab instead of replacing the current one */ + void onConnectBookmark(Bookmark bookmark, boolean newTab); void onAddCurrentServerBookmark(); @@ -141,7 +146,16 @@ final class MainMenuBar extends JMenuBar { bookmarksMenu.removeAll(); for (Bookmark b : bookmarks.all()) { JMenuItem item = new JMenuItem(b.displayName(), Icons.of("SERVER_GREEN")); - item.addActionListener(e -> listener.onConnectBookmark(b)); + item.setToolTipText("Connect here (middle-click to open a new tab)"); + item.addActionListener(e -> listener.onConnectBookmark(b, false)); + item.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (!SwingUtilities.isMiddleMouseButton(e)) return; + MenuSelectionManager.defaultManager().clearSelectedPath(); + listener.onConnectBookmark(b, true); + } + }); bookmarksMenu.add(item); } if (!bookmarks.all().isEmpty()) bookmarksMenu.addSeparator(); diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java index d47c4d0..abdb0a0 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java @@ -230,6 +230,24 @@ final class ServerTab implements ServerTabConnectionEvents.Listener { }, "identity-resolve").start(); } + /** + * Replaces this tab's connection: leaves the server it is on, then connects to the + * new one in its place — what left-clicking a bookmark does. + */ + void switchTo(String address, int port, String nickname, String password, String identityId, + String channel, String channelPassword) { + if (!isBusy()) { + connect(address, port, nickname, password, identityId, channel, channelPassword); + return; + } + new Thread(() -> { + conn.disconnectBlocking("Switching servers"); + // Queued behind the disconnect's own UI work, which clears the "connecting" flag. + SwingUtilities.invokeLater(() -> + connect(address, port, nickname, password, identityId, channel, channelPassword)); + }, "ts3j-switch-server").start(); + } + void disconnect() { if (conn.isConnected()) conn.disconnect(); }