Keep the window responsive while the channel tree loads
Connecting to a server with ~560 channels froze the UI for over two seconds: every model event queued its own full tree rebuild, and each rebuild expanded row by row with Swing's variable-height layout cache, which measures every row on each expansion. Coalesce model-change bursts into one rebuild and switch the tree to the large-model layout (it already has a fixed row height), which only measures rows on screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user