diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTabConnectionEvents.java b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTabConnectionEvents.java index 7de44e6..d77d70e 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTabConnectionEvents.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTabConnectionEvents.java @@ -8,6 +8,7 @@ import com.ts3client.net.TeamspeakConnection; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * Marshals {@link ConnectionListener} callbacks onto the EDT and fans them out to @@ -32,6 +33,8 @@ final class ServerTabConnectionEvents implements ConnectionListener { private final ServerTab tab; private final Listener listener; + private final AtomicBoolean modelChangePending = new AtomicBoolean(); + private TeamspeakConnection conn; private ServerTreePanel treePanel; private ChatPanel chatPanel; @@ -101,7 +104,10 @@ final class ServerTabConnectionEvents implements ConnectionListener { @Override public void onModelChanged() { + // Events arrive in bursts (hundreds while connecting); one rebuild covers all of them. + if (!modelChangePending.compareAndSet(false, true)) return; SwingUtilities.invokeLater(() -> { + modelChangePending.set(false); treePanel.rebuild(); treeActions.renderInfo(); treeActions.refreshGroupsDialog(); diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreePanel.java b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreePanel.java index 15644b9..710f30e 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreePanel.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreePanel.java @@ -170,6 +170,9 @@ public final class ServerTreePanel extends JScrollPane { ui.setRightChildIndent(10); } tree.setRowHeight(UIScale.scale(20)); + // Lays out only the rows on screen. The default cache measures every row as it is + // expanded, which freezes the window for seconds on servers with hundreds of channels. + tree.setLargeModel(true); tree.setBackground(Theme.treeBg()); tree.setFont(Theme.uiFont()); ServerTreeCellRenderer renderer = new ServerTreeCellRenderer(id -> id == selfClientId, contacts, settings);