Putting an image in to a JFace table Cell is causing gap for image to appear in first column
Asked Answered
D

3

6

So I have a problem, when I add an image to any column of a JFace table the first column also behaves like it has an image in and the text is indented by the size of that image.

Here's a screenshot illustrating my point with the code needed to produce it. Is there anyway to stop this from happening because it's really getting on my wick?

Regards,

Glen x

enter image description here

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;
    }
}
Dirkdirks answered 28/9, 2012 at 13:51 Comment(0)
J
2

That is a quite annoying bug when using Windows. You can use a dirty fix by skipping the first column (not using it) and setting its width to zero.

As far as I remember correctly, this will introduce some minor glitches when using MacOS.

Julienne answered 28/9, 2012 at 13:55 Comment(2)
It took me 3 hours to narrow down the reason why I was getting the gap, another half hour spent googling the problem with no joy and a further half hour to write the scenario and post up on here. It took you 3 minutes to answer my question. Kudos my friend, kudos.Dirkdirks
@GlenLamb I was facing the same problem a while ago. That's why I knew how to answer you question ;)Julienne
U
2

I had the same problem and worked around it by using a StyledCellLabelProvider with owner draw and overriding the paint method to paint the image. The point is that you should not set the image of the viewer cell because this will give the bug. I posted example code to the Eclipse bug report.

Urogenital answered 15/3, 2013 at 12:4 Comment(0)
N
1

TableItem line:301: I see a problem with SWT code here.

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);

for the first table viewer with image, here code is 1 that why drawing text started iconRect right coordinate. for the second table viwer with no image, code is zero. so it always starts from the actual bounds.

If you are really keen on fix it at CellStyleStyledCellLabelProvider i would suggest you to override paint method there.

Nonchalant answered 28/9, 2012 at 16:54 Comment(4)
That's interesting because the bug report blames window.Dirkdirks
Yes. It is windows. override paint method and ignore ViewerCell.getTextBounds() for first column and paint your text if you want to make it work until SWT windows is fixed.Nonchalant
Painting text doesn't really work either because the background it paints around the text is white rather than transparent, which makes the highlights look terrible, much worse than having the gap.Dirkdirks
Use GC.drawText(String string, int x, int y, boolean isTransparent)Nonchalant

© 2022 - 2024 — McMap. All rights reserved.