From acfe25db15d02b19e8c3eb32ec71117d28cdc676 Mon Sep 17 00:00:00 2001 From: ericek111 Date: Wed, 19 Aug 2026 19:59:55 +0000 Subject: [PATCH] Show our own name in bold, in the row and in its editor The renderer asks the panel which id is ours rather than reading ClientEntry.self: our own row usually arrives among the enter-view events of the connect handshake, before the connection knows its own client id, so that flag was left false. It is now stamped once the id is known, which also fixes the "(you)" marker in the info panel. The inline editor matches, and sits 2px further left so its text lines up with the label it replaces rather than with its own border. Co-Authored-By: Claude Opus 5 --- .../java/com/ts3client/net/TeamspeakConnection.java | 5 +++++ .../java/com/ts3client/ui/NicknameCellEditor.java | 9 +++++++-- .../com/ts3client/ui/ServerTreeCellRenderer.java | 13 +++++++++++-- .../main/java/com/ts3client/ui/ServerTreePanel.java | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java b/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java index 09c4749..5d97371 100644 --- a/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java +++ b/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java @@ -274,6 +274,11 @@ public final class TeamspeakConnection implements TS3Listener { // Protocol connection established; anything past this point is best-effort. selfClientId = client.getClientId(); + // Our own row usually arrives among the enter-view events the connect + // handshake carries, i.e. before our id was known here, so it has to be + // marked once it is. + ClientEntry ourselves = model.getClient(selfClientId); + if (ourselves != null) ourselves.self = true; fileTransfers = new FileTransferManager(client, () -> serverHost); client.setMicrophone(microphone); icons.retryFailed(); diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/NicknameCellEditor.java b/ts3-client/swing/src/main/java/com/ts3client/ui/NicknameCellEditor.java index 789fd57..2f935a2 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/NicknameCellEditor.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/NicknameCellEditor.java @@ -27,6 +27,9 @@ import java.util.function.IntPredicate; */ final class NicknameCellEditor extends DefaultTreeCellEditor { + /** Pulls the field left by its own border, so the text sits where the label did. */ + private static final int FIELD_NUDGE = 2; + /** Long enough for the click's own release to have been handled first. */ private static final int SELECT_DELAY_MS = 80; @@ -43,7 +46,8 @@ final class NicknameCellEditor extends DefaultTreeCellEditor { static NicknameCellEditor create(JTree tree, DefaultTreeCellRenderer renderer, IntPredicate isSelf) { JTextField field = new JTextField(); - field.setFont(Theme.UI_FONT); + // Only our own row is edited, and that name is bold in the tree. + field.setFont(Theme.UI_BOLD); return new NicknameCellEditor(tree, renderer, field, isSelf); } @@ -98,7 +102,8 @@ final class NicknameCellEditor extends DefaultTreeCellEditor { row, false); if (!(c instanceof JLabel)) return; editingIcon = ((JLabel) c).getIcon(); - offset = editingIcon == null ? 0 : editingIcon.getIconWidth() + renderer.getIconTextGap(); + offset = editingIcon == null ? 0 + : editingIcon.getIconWidth() + renderer.getIconTextGap() - FIELD_NUDGE; } /** The edited nickname, trimmed; empty when nothing usable was typed. */ diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreeCellRenderer.java b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreeCellRenderer.java index c1fc4e8..5824978 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreeCellRenderer.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTreeCellRenderer.java @@ -8,6 +8,7 @@ import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import java.awt.Component; +import java.util.function.IntPredicate; /** * Draws a {@link ServerTreePanel} row: the status icon and the label. The group @@ -15,6 +16,13 @@ import java.awt.Component; */ final class ServerTreeCellRenderer extends DefaultTreeCellRenderer { + /** Whether a client id is our own, which the panel learns on connecting. */ + private final IntPredicate isSelf; + + ServerTreeCellRenderer(IntPredicate isSelf) { + this.isSelf = isSelf; + } + @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, @@ -47,9 +55,10 @@ final class ServerTreeCellRenderer extends DefaultTreeCellRenderer { setIcon(iconFor(cl)); // Talking shows in the client's icon, as it does in TeamSpeak. Marking the // name as well would also re-measure the row mid-speech, which leaves the - // nickname clipped to an ellipsis for as long as it lasts. + // nickname clipped to an ellipsis for as long as it lasts. Our own name is + // bold throughout, so its width never changes either. setForeground(Theme.TREE_TEXT); - setFont(Theme.UI_FONT); + setFont(isSelf.test(cl.id) ? Theme.UI_BOLD : Theme.UI_FONT); } else { // root / server setText(String.valueOf(obj)); 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 40463f2..74e855d 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 @@ -153,7 +153,7 @@ public final class ServerTreePanel extends JScrollPane { tree.setRowHeight(20); tree.setBackground(Theme.TREE_BG); tree.setFont(Theme.UI_FONT); - ServerTreeCellRenderer renderer = new ServerTreeCellRenderer(); + ServerTreeCellRenderer renderer = new ServerTreeCellRenderer(id -> id == selfClientId); tree.setCellRenderer(renderer); nicknameEditor = NicknameCellEditor.create(tree, renderer, id -> id == selfClientId); tree.setCellEditor(nicknameEditor);