Java SWT中如何为Tree内图像添加缩进?解决白背景问题
SWT Tree 图像缩进的替代实现方法
方法1:直接偏移GC绘制坐标(推荐,无需创建新图像)
不用额外创建图像,直接在Tree的PaintItem事件中调整绘制坐标,避开透明图像的坑:
tree.addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { TreeItem item = (TreeItem) e.item; if (item == null) return; Image originalImg = item.getImage(); if (originalImg == null) return; int indent = 20; // 自定义缩进像素值 Point imgSize = originalImg.getSize(); // 计算垂直居中的Y坐标,X坐标加上缩进值 int drawX = e.x + indent; int drawY = e.y + (e.height - imgSize.y) / 2; e.gc.drawImage(originalImg, drawX, drawY); // 屏蔽默认图像绘制,防止叠加 e.detail &= ~SWT.IMAGE; } });
这种方式直接复用原图像,不需要处理透明背景和图像销毁,性能更优。
方法2:正确创建带透明通道的缩进图像
如果一定要生成缩进后的图像,之前出现白色背景是因为没正确创建透明图像,试试这个写法:
Image original = ...; // 你的原图像 int indent = 20; Rectangle imgBounds = original.getBounds(); // 创建支持透明的图像,必须指定SWT.TRANSPARENT Image indentedImg = new Image(Display.getDefault(), imgBounds.width + indent, imgBounds.height, SWT.TRANSPARENT); GC gc = new GC(indentedImg); // 直接将原图像绘制到偏移位置,透明背景会自动保留 gc.drawImage(original, indent, 0); gc.dispose(); // 绑定到TreeItem treeItem.setImage(indentedImg); // 注意:Tree销毁时要手动调用indentedImg.dispose()释放资源
核心是创建图像时加上SWT.TRANSPARENT参数,避免默认白色背景。
方法3:结合TreeViewer的LabelProvider处理
如果用TreeViewer管理数据,可以在LabelProvider中动态生成缩进图像(建议加缓存避免重复创建):
treeViewer.setLabelProvider(new LabelProvider() { // 缓存已生成的缩进图像,key为原图像+缩进值的组合 private Map<String, Image> imgCache = new HashMap<>(); @Override public Image getImage(Object element) { Image original = getOriginalImageForElement(element); int indent = calculateIndentByLevel(element); // 根据节点层级计算缩进 if (indent <= 0) return original; String cacheKey = original.hashCode() + "_" + indent; if (imgCache.containsKey(cacheKey)) { return imgCache.get(cacheKey); } Rectangle bounds = original.getBounds(); Image indented = new Image(Display.getDefault(), bounds.width + indent, bounds.height, SWT.TRANSPARENT); GC gc = new GC(indented); gc.drawImage(original, indent, 0); gc.dispose(); imgCache.put(cacheKey, indented); return indented; } @Override public void dispose() { // 销毁缓存中的所有图像,避免内存泄漏 for (Image img : imgCache.values()) { img.dispose(); } super.dispose(); } });
内容的提问来源于stack exchange,提问作者user22061831
相关产品推荐
相关产品推荐

