Split ServerTab into focused collaborator classes
Extract mic/speaker/away/commander state handling into ServerTabSelfState, ServerTreePanel.Actions delegation (context menus, drag-drop, link clicks) into ServerTabTreeActions, and ConnectionListener event marshaling onto the EDT into ServerTabConnectionEvents. ServerTab keeps its full public API (636 -> 377 lines); no behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import com.ts3client.net.ConnectionListener;
|
||||
import com.ts3client.net.TeamspeakConnection;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Marshals {@link ConnectionListener} callbacks onto the EDT and fans them out to
|
||||
* this tab's views (tree, chat, info panel) and to {@link MainFrame}.
|
||||
*
|
||||
* <p>Constructed before the {@link TeamspeakConnection} it listens to exists — the
|
||||
* connection's constructor needs a listener up front — so {@link #attach} wires the
|
||||
* rest of the tab in once everything else has been built.
|
||||
*/
|
||||
final class ServerTabConnectionEvents implements ConnectionListener {
|
||||
|
||||
/** The handful of {@link ServerTab} fields this class updates but can't reach directly. */
|
||||
interface Listener {
|
||||
void setStatus(String status);
|
||||
|
||||
void setTitle(String title);
|
||||
|
||||
void setConnecting(boolean connecting);
|
||||
}
|
||||
|
||||
private final MainFrame host;
|
||||
private final ServerTab tab;
|
||||
private final Listener listener;
|
||||
|
||||
private TeamspeakConnection conn;
|
||||
private ServerTreePanel treePanel;
|
||||
private ChatPanel chatPanel;
|
||||
private ServerTabSelfState selfState;
|
||||
private ServerTabTreeActions treeActions;
|
||||
|
||||
ServerTabConnectionEvents(MainFrame host, ServerTab tab, Listener listener) {
|
||||
this.host = host;
|
||||
this.tab = tab;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
void attach(TeamspeakConnection conn, ServerTreePanel treePanel, ChatPanel chatPanel,
|
||||
ServerTabSelfState selfState, ServerTabTreeActions treeActions) {
|
||||
this.conn = conn;
|
||||
this.treePanel = treePanel;
|
||||
this.chatPanel = chatPanel;
|
||||
this.selfState = selfState;
|
||||
this.treeActions = treeActions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatus(String text) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
listener.setStatus(text);
|
||||
host.tabUpdated(tab);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
listener.setConnecting(false);
|
||||
treePanel.setSelfClientId(conn.getSelfClientId());
|
||||
selfState.resetOnConnect();
|
||||
chatPanel.setInputEnabled(true);
|
||||
chatPanel.appendSystem("Connected.");
|
||||
host.tabConnected(tab);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(String reason) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
listener.setConnecting(false);
|
||||
conn.getModel().clear();
|
||||
treePanel.showDisconnected();
|
||||
treeActions.clearSelection();
|
||||
chatPanel.setInputEnabled(false);
|
||||
chatPanel.closePrivateChats();
|
||||
chatPanel.closeNoteTabs();
|
||||
chatPanel.appendSystem("Disconnected" + (reason == null || reason.isEmpty() ? "." : ": " + reason));
|
||||
host.tabDisconnected(tab);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModelChanged() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
treePanel.rebuild();
|
||||
treeActions.renderInfo();
|
||||
String name = conn.getModel().getServerName();
|
||||
if (conn.isConnected() && name != null && !name.isBlank() && !name.equals(tab.title())) {
|
||||
listener.setTitle(name);
|
||||
host.tabUpdated(tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoUpdated() {
|
||||
SwingUtilities.invokeLater(treeActions::renderInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIconsUpdated() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
treePanel.refreshRowSizes();
|
||||
treeActions.renderInfo();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChat(ChatScope scope, int fromClientId, String fromName, String message) {
|
||||
switch (scope) {
|
||||
case PRIVATE:
|
||||
chatPanel.appendPrivateMessage(fromClientId, fromName, fromClientId, fromName, message);
|
||||
break;
|
||||
case SERVER:
|
||||
chatPanel.appendServerMessage(fromClientId, fromName, message);
|
||||
break;
|
||||
default:
|
||||
chatPanel.appendChannelMessage(fromClientId, fromName, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTalkStateChanged(int clientId, boolean talking) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
treePanel.refreshVisual();
|
||||
if (clientId == conn.getSelfClientId()) host.selfStateChanged(tab);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String message) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
chatPanel.appendSystem("Error: " + message);
|
||||
listener.setStatus(message);
|
||||
host.tabUpdated(tab);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerLog(String message) {
|
||||
SwingUtilities.invokeLater(() -> chatPanel.appendServerLog(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPoke(String fromName, String message) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
chatPanel.appendSystem("You were poked by " + fromName + ": " + message);
|
||||
host.selectTab(tab);
|
||||
JOptionPane.showMessageDialog(host, fromName + " poked you:\n\n" + message,
|
||||
"Poke", JOptionPane.INFORMATION_MESSAGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user