如何将图像与表格单元格的中心对齐(SWT表)

我开发Eclipse RCP应用程序并遇到了Table的问题。 我们在数据库中有一些布尔格式的数据,用户希望使用checkbox查看该字段。

我尝试使用Button(SWT.CHECK)作为表编辑器来实现它,但它工作得太慢了:(

我试图使用2个图像 – 选中和未选中的复选框,它可以工作,但我无法将它们对齐到中心,它们会自动对齐。

我甚至找到了如何捕获SWT.MeasureItemSWT.PaintItem事件并通过change event.x字段手动处理它们,但是我遇到了一个问题 – 我现在无法得到什么列测量或绘画,因为事件没有向我提供了这些信息。

它是通过重绘时修改事件数据来将图像对齐到中心的唯一方法,还是可以通过其他方式通过复选框表示布尔数据? 我现在不需要编辑它们,所以只读模式就足够了。

您可以将PaintListener添加到表中以及何时绘制所选列(在我的示例中为第5列),检查行的大小并PaintListener对齐图像。

 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

我将它与Tonny链接到TableViewers和Nativelooking Checkboxes并创建了方便的抽象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 Checkboxes 。

Sorceror的解决方案派上了用场。 我已将其改编为在DelegatingStyledCellLabelProvider中使用的自定义IStyledLabelProvider:

 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; 你只需要做出自己的调整。