Java 将图像放入JFace表格单元格会导致图像出现在第一列中的间隙

Java 将图像放入JFace表格单元格会导致图像出现在第一列中的间隙,java,swt,jface,tableviewer,Java,Swt,Jface,Tableviewer,所以我有一个问题,当我向JFace表的任何列添加一个图像时,第一列的行为也类似于它在中有一个图像,文本按该图像的大小缩进 这里有一个屏幕截图,用生成它所需的代码来说明我的观点。有没有办法阻止这一切的发生,因为这真的让我心烦意乱 问候, 格伦x package widgets; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ArrayContentProvider; imp

所以我有一个问题,当我向JFace表的任何列添加一个图像时,第一列的行为也类似于它在中有一个图像,文本按该图像的大小缩进

这里有一个屏幕截图,用生成它所需的代码来说明我的观点。有没有办法阻止这一切的发生,因为这真的让我心烦意乱

问候,

格伦x

package widgets;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

public class ComponentTest {

    private static Image image;

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(1, true));

        TableViewer viewer1 = getViewer(shell, true);
        TableViewer viewer2 = getViewer(shell, false);

        List<String> rows = new ArrayList<String>();
        rows.add("Row 1");
        rows.add("Row 2");

        viewer1.setInput(rows);
        viewer2.setInput(rows);

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

    private static TableViewer getViewer(final Shell shell, boolean addImage) {
        TableViewer viewer = new TableViewer(shell, SWT.FULL_SELECTION
                | SWT.H_SCROLL | SWT.V_SCROLL | SWT.NONE);

        viewer.setContentProvider(ArrayContentProvider.getInstance());

        viewer.getTable().setLayoutData(
                new GridData(SWT.FILL, SWT.FILL, true, true));

        TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE);
        col.getColumn().setWidth(100);
        col.getColumn().setText("Text Column");
        col.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                cell.setText((String) cell.getElement());
            }
        });

        col = new TableViewerColumn(viewer, SWT.NONE);
        col.getColumn().setWidth(100);
        col.getColumn().setText("Second Text Column");
        col.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                cell.setText((String) cell.getElement());
            }
        });

        if (addImage) {
            col = new TableViewerColumn(viewer, SWT.NONE);
            col.getColumn().setWidth(100);
            col.getColumn().setText("Image Column");
            col.setLabelProvider(new StyledCellLabelProvider() {
                @Override
                public void update(ViewerCell cell) {
                    cell.setImage(getImage(shell.getDisplay()));
                }
            });
        }
        viewer.getTable().setHeaderVisible(true);

        return viewer;
    }

    // make a little green square
    private static Image getImage(Display display) {
        if (image == null) {
            PaletteData palette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
            ImageData imageData = new ImageData(16, 16, 24, palette);

            for (int x = 0; x < 16; x++) {
                for (int y = 0; y < 16; y++) {
                    imageData.setPixel(x, y, 0xFF00);
                }
            }
            ;
            image = new Image(display, imageData);
        }
        return image;
    }
}

packagewidgets;
导入java.util.ArrayList;
导入java.util.List;
导入org.eclipse.jface.viewers.ArrayContentProvider;
导入org.eclipse.jface.viewers.StyledCellLabelProvider;
导入org.eclipse.jface.viewers.TableViewer;
导入org.eclipse.jface.viewers.TableViewerColumn;
导入org.eclipse.jface.viewers.ViewerCell;
导入org.eclipse.swt.swt;
导入org.eclipse.swt.graphics.Image;
导入org.eclipse.swt.graphics.ImageData;
导入org.eclipse.swt.graphics.PaletteData;
导入org.eclipse.swt.layout.GridData;
导入org.eclipse.swt.layout.GridLayout;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Shell;
公共类组件测试{
私有静态图像;
公共静态void main(字符串[]args){
最终显示=新显示();
最终外壳=新外壳(显示);
setLayout(新的GridLayout(1,true));
tableviewer1=getViewer(shell,true);
tableviewer2=getViewer(shell,false);
列表行=新建ArrayList();
行。添加(“第1行”);
行。添加(“第2行”);
viewer1.setInput(行);
viewer2.setInput(行);
shell.pack();
shell.open();
而(!shell.isDisposed()){
如果(!display.readAndDispatch()){
display.sleep();
}
}
display.dispose();
}
私有静态TableViewer getViewer(最终Shell,布尔addImage){
TableViewer=新的TableViewer(shell,SWT.FULL\u选择
|SWT.H|U卷轴| SWT.V|U卷轴| SWT.NONE);
setContentProvider(ArrayContentProvider.getInstance());
viewer.getTable().setLayoutData(
新的GridData(SWT.FILL,SWT.FILL,true,true));
TableViewerColumn col=新的TableViewerColumn(查看器,SWT.NONE);
col.getColumn().setWidth(100);
col.getColumn().setText(“文本列”);
col.setLabelProvider(新样式CellLabelProvider(){
@凌驾
公共无效更新(ViewerCell单元格){
cell.setText((字符串)cell.getElement());
}
});
col=新的TableViewerColumn(查看器,SWT.NONE);
col.getColumn().setWidth(100);
col.getColumn().setText(“第二个文本列”);
col.setLabelProvider(新样式CellLabelProvider(){
@凌驾
公共无效更新(ViewerCell单元格){
cell.setText((字符串)cell.getElement());
}
});
如果(添加图像){
col=新的TableViewerColumn(查看器,SWT.NONE);
col.getColumn().setWidth(100);
col.getColumn().setText(“图像列”);
col.setLabelProvider(新样式CellLabelProvider(){
@凌驾
公共无效更新(ViewerCell单元格){
cell.setImage(getImage(shell.getDisplay());
}
});
}
viewer.getTable().setheadervible(true);
返回查看器;
}
//做一个绿色的小正方形
私有静态图像getImage(显示){
if(image==null){
PaletteData调色板=新PaletteData(0xFF、0xFF00、0xFF0000);
ImageData ImageData=新的ImageData(16,16,24,调色板);
对于(int x=0;x<16;x++){
对于(int y=0;y<16;y++){
设置像素(x,y,0xFF00);
}
}
;
图像=新图像(显示,图像数据);
}
返回图像;
}
}
使用Windows时,这是一个非常烦人的问题。可以通过跳过第一列(不使用)并将其宽度设置为零来使用脏修复


据我记忆所及,这将在使用MacOS时引入一些小故障。

TableItem行:301:我在这里看到SWT代码有问题

if (code == 0) return new RECT ();
            if (!getImage) {
                RECT iconRect = new RECT ();
                iconRect.left = OS.LVIR_ICON;
                parent.ignoreCustomDraw = true;
                code = OS.SendMessage (hwnd, OS. LVM_GETITEMRECT, row, iconRect);
                parent.ignoreCustomDraw = false;
                if (code != 0) rect.left = iconRect.right;


//****problem
    code = OS.SendMessage (hwnd, OS. LVM_GETITEMRECT, row, iconRect);
对于第一个带有图像的表格查看器,这里的代码是1,这就是开始绘制文本的原因。 对于没有图像的第二个表viwer,代码为零。所以它总是从实际的边界开始


如果你真的很想在
CellStyledCellLabelProvider上修复它,我建议你在那里重写paint方法。

我也遇到了同样的问题,通过使用一个带有所有者绘制的StyledCellLabelProvider并重写paint方法来绘制图像来解决它。关键是,您不应该设置查看器单元格的图像,因为这会导致错误。我在Eclipse bug报告中发布了示例代码。

我花了3个小时缩小了差距的原因,又花了半个小时在谷歌上搜索问题,但毫无乐趣,又花了半个小时来编写场景并在这里发布。你花了3分钟回答我的问题。荣誉,我的朋友,荣誉,我不久前也面临同样的问题。这就是为什么我知道如何回答你的问题;)这很有意思,因为bug报告指责window。是的。这是窗户。如果要使文本在SWT窗口修复之前工作,请重写绘制方法并忽略第一列的ViewerCell.getTextBounds(),并绘制文本。绘制文本也无法真正工作,因为它在文本周围绘制的背景是白色而不是透明的,这会使高光看起来很糟糕,使用GC.drawText(String、int x、int y、boolean isTransparent)