Repaint the whole tree viewport while scrolling
The right-aligned icon strip is positioned against the viewport rather than the row, so the pixels a blit scroll reuses are stale and the icons leave ghosts behind. Scroll the viewport in simple mode, and widen every repaint request to the full visible width so a row whose label changes size cannot leave its icons behind either. Also stop blacklisting an icon whose download failed only because the file transfer channel was not up yet: channel rows are painted during connect, well before that point, so their icons would never be retried. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -118,6 +118,9 @@ public final class IconRepository {
|
||||
icons.put(id, data);
|
||||
writeDiskCache(id, data);
|
||||
if (onIconLoaded != null) onIconLoaded.run();
|
||||
} catch (IllegalStateException e) {
|
||||
// Not connected (yet): a channel icon can be asked for while the tree is
|
||||
// first painted, before file transfers are up. Leave it retryable.
|
||||
} catch (Exception e) {
|
||||
// Missing or permission-denied icons are common; don't ask again.
|
||||
failed.add(id);
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.TransferHandler;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
@@ -96,6 +97,9 @@ public final class ServerTreePanel extends JScrollPane {
|
||||
tree.setCellRenderer(new Renderer());
|
||||
setViewportView(tree);
|
||||
getViewport().setBackground(Theme.TREE_BG);
|
||||
// The icon strip is drawn against the viewport's right edge, so the blitted
|
||||
// pixels a scroll would reuse are stale; repaint the whole viewport instead.
|
||||
getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
|
||||
|
||||
// Within the tree a drag moves the client or channel; dropped elsewhere it
|
||||
// yields the TS3 link BBCode, which the chat input accepts as plain text.
|
||||
@@ -426,6 +430,17 @@ public final class ServerTreePanel extends JScrollPane {
|
||||
super(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Widens every repaint request to the full visible width. Swing only asks for
|
||||
* the row rectangle, which stops short of the right-aligned icon strip and would
|
||||
* leave it behind when a row's label changes width.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(long tm, int x, int y, int width, int height) {
|
||||
Rectangle visible = getVisibleRect();
|
||||
super.repaint(tm, visible.x, y, visible.width, height);
|
||||
}
|
||||
|
||||
void highlightChannel(TreePath path) {
|
||||
if (path == highlight || (path != null && path.equals(highlight))) return;
|
||||
highlight = path;
|
||||
|
||||
Reference in New Issue
Block a user