Как выровнять изображение по центру ячейки таблицы (таблица SWT)

Я разрабатываю приложение Eclipse RCP и получил проблему с Table. У нас есть некоторые данные в базе данных в логическом формате, и пользователи хотят видеть это поле с помощью checkbox.

Я попытался реализовать его с помощью Button(SWT.CHECK) as Стол-Редактор, но он работал слишком медленно :(

Я попытался использовать 2 изображения - отмеченные и непроверенные флажки, он работает, но я не могу выровнять их по центру, они выровнены слева автоматически.

Я даже нашел как лови SWT.MeasureItem и SWT.PaintItem события и обрабатывать их вручную, путем изменения event.x поле, но у меня проблема - я не могу получить, какой столбец измерения или живописи в данный момент, потому что событие не предоставляет мне эту информацию.

это единственный способ выровнять изображения по центру путем изменения данных событий при перерисовке или могут быть другие способы представления логических данных через флажки? Мне не нужно редактировать их сейчас, поэтому режим только для чтения должен быть достаточным.

4 ответов


Вы можете добавить PaintListener к вашей таблице и когда она будет рисовать выбранный столбец (столбец 5 в моем случае), проверьте размер строки и выровняйте изображение самостоятельно..

testTable.addListener(SWT.PaintItem, new Listener() {

    @Override
    public void handleEvent(Event event) {
        // Am I on collumn I need..?
        if(event.index == 5) {
            Image tmpImage = IMAGE_TEST_PASS;
            int tmpWidth = 0;
            int tmpHeight = 0;
            int tmpX = 0;
            int tmpY = 0;

            tmpWidth = testTable.getColumn(event.index).getWidth();
            tmpHeight = ((TableItem)event.item).getBounds().height;

            tmpX = tmpImage.getBounds().width;
            tmpX = (tmpWidth / 2 - tmpX / 2);
            tmpY = tmpImage.getBounds().height;
            tmpY = (tmpHeight / 2 - tmpY / 2);
            if(tmpX <= 0) tmpX = event.x;
            else tmpX += event.x;
            if(tmpY <= 0) tmpY = event.y;
            else tmpY += event.y;
            event.gc.drawImage(tmpImage, tmpX, tmpY);
        }
    }
});

вот пример использования OwnerDrawLabelProvider:http://bingjava.appspot.com/snippet.jsp?id=3221

Я объединил его со ссылкой Тонни на TableViewers и Nativelooking флажки и создал удобный абстрактный класс CenteredCheckboxLabelProvider

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;

public abstract class CenteredCheckboxLabelProvider extends OwnerDrawLabelProvider {
    private static final String CHECKED_KEY = "CHECKED";
    private static final String UNCHECK_KEY = "UNCHECKED";

    public CenteredCheckboxLabelProvider(ColumnViewer viewer) {
        if (JFaceResources.getImageRegistry().getDescriptor(CHECKED_KEY) == null) {
            JFaceResources.getImageRegistry().put(UNCHECK_KEY, makeShot(viewer.getControl().getShell(), false));
            JFaceResources.getImageRegistry().put(CHECKED_KEY, makeShot(viewer.getControl().getShell(), true));
        }
    }

    private Image makeShot(Shell shell, boolean type) {
        Shell s = new Shell(shell, SWT.NO_TRIM);
        Button b = new Button(s, SWT.CHECK);
        b.setSelection(type);
        Point bsize = b.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        b.setSize(bsize);
        b.setLocation(0, 0);
        s.setSize(bsize);
        s.open();

        GC gc = new GC(b);
        Image image = new Image(shell.getDisplay(), bsize.x, bsize.y);
        gc.copyArea(image, 0, 0);
        gc.dispose();

        s.close();

        return image;
    }

    public Image getImage(Object element) {
        if (isChecked(element)) {
            return JFaceResources.getImageRegistry().get(CHECKED_KEY);
        } else {
            return JFaceResources.getImageRegistry().get(UNCHECK_KEY);
        }
    }

    @Override
    protected void measure(Event event, Object element) {
    }

    @Override
    protected void paint(Event event, Object element) {
        Image img = getImage(element);

        if (img != null) {
            Rectangle bounds = ((TableItem) event.item).getBounds(event.index);
            Rectangle imgBounds = img.getBounds();
            bounds.width /= 2;
            bounds.width -= imgBounds.width / 2;
            bounds.height /= 2;
            bounds.height -= imgBounds.height / 2;

            int x = bounds.width > 0 ? bounds.x + bounds.width : bounds.x;
            int y = bounds.height > 0 ? bounds.y + bounds.height : bounds.y;

            event.gc.drawImage(img, x, y);
        }
    }

    protected abstract boolean isChecked(Object element);
}

вы также можете посмотреть на эту запись в блоге:TableViewers и Nativelooking флажки.


решение колдуна пригодилось. Я адаптировал его к пользовательскому IStyledLabelProvider для использования в DelegatingStyledCellLabelProvider:

public class MutedLabelProvider extends LabelProvider implements IStyledLabelProvider {

  public MutedLabelProvider(Tree containerTree, int columnIndex) {
    registerIconListener(containerTree, columnIndex);
  }

  @Override
  public StyledString getStyledText(Object element) {
    return new StyledString();
  }

  private void registerIconListener(Tree containerTree, int columnIndex) {
    containerTree.addListener(SWT.PaintItem, new Listener() {
      @Override
      public void handleEvent(Event event) {
        if (event.index == columnIndex) {
          TreeItem treeItem = (TreeItem) event.item;
          Object data = treeItem.getData();
          Image tmpImage = getImageFromData(data);
          if (tmpImage != null) {
            int tmpWidth = 0;
            int tmpHeight = 0;
            int tmpX = 0;
            int tmpY = 0;
            tmpWidth = containerTree.getColumn(event.index).getWidth();
            tmpHeight = treeItem.getBounds().height;
            tmpX = tmpImage.getBounds().width;
            tmpX = (tmpWidth / 2 - tmpX / 2);
            tmpY = tmpImage.getBounds().height;
            tmpY = (tmpHeight / 2 - tmpY / 2);
            if (tmpX <= 0) tmpX = event.x;
            else tmpX += event.x;
            if (tmpY <= 0) tmpY = event.y;
            else tmpY += event.y;
            event.gc.drawImage(tmpImage, tmpX, tmpY);
          }
        }
      }
    });
  }

  private Image getImageFromData(Object element) {
    if (element != null && element instanceof IMarker) {
      IMarker marker = (IMarker) element;
      boolean isItTrue = marker.getAttribute("MyBooleanAttr", false);
      if (isItTrue) {
        // TODO return here the image you want for true state
        return JFaceResources.getImageRegistry().get("MyImageForTrue");
      } else {
        // TODO return here the image you want for false state
        // Alternatively, you can return null for no image
        return null;
      }
    } else {
      return null;
    }
  }

}

обратите внимание, что я использую IMarker как данные для элементов и TreeViewer (поэтому я получаю TreeItems), но ваши данные могут отличаться, и ваш зритель может быть TableViewer; вам просто нужно сделать свои собственные настройки.