2012-01-23 27 views
5

Tôi phát triển ứng dụng RCP Eclipse và gặp sự cố với số Table. Chúng tôi có một số dữ liệu trong cơ sở dữ liệu ở định dạng boolean và người dùng muốn xem trường đó bằng cách sử dụng checkbox.Cách căn chỉnh hình ảnh thành tâm của ô bảng (Bảng SWT)

tôi cố gắng thực hiện nó bằng cách sử Button(SWT.CHECK) như Bảng-Editor, nhưng nó làm việc quá chậm :(

Tôi cố gắng để sử dụng 2 hình ảnh - kiểm tra và kiểm soát hộp kiểm, nó hoạt động, nhưng tôi có thể' Tôi thậm chí còn tìm cách bắt các sự kiện SWT.MeasureItemSWT.PaintItem và xử lý chúng theo cách thủ công bằng cách thay đổi trường event.x, nhưng tôi gặp vấn đề - Tôi không thể nhận được cột đo lường nào hoặc vẽ vào lúc này, vì Sự kiện không cung cấp cho tôi thông tin đó.

Đây có phải là cách duy nhất để căn chỉnh hình ảnh vào giữa bằng cách sửa đổi dữ liệu sự kiện khi vẽ lại hoặc có thể có cách khác để biểu diễn dữ liệu boolean qua các hộp kiểm không? Tôi không cần phải chỉnh sửa chúng ngay bây giờ, vì vậy chế độ chỉ đọc là đủ.

+0

Tôi sắp bị sốc khi cho phép hộp kiểm vẽ hệ điều hành chậm hơn so với việc vẽ hình ảnh của riêng bạn. –

+0

@EdwardThomson Tôi nghĩ rằng nó thực sự phụ thuộc vào việc thực hiện .. – Sorceror

Trả lời

8

Bạn có thể thêm PaintListener để bàn của bạn và khi nào nó sẽ vẽ cột được lựa chọn (cột 5 trong trường hợp của tôi), kiểm tra kích thước của hàng và căn chỉnh hình ảnh của chính mình ..

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

Dưới đây là ví dụ sử dụng OwnerDrawLabelProvider: http://bingjava.appspot.com/snippet.jsp?id=3221

tôi kết hợp nó với liên kết Tonny để TableViewers and Nativelooking Checkboxes và tạo tiện dụng lớp trừu tượng 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); 
} 
+0

Vinh quang, cảm ơn bạn rất nhiều! Tôi chỉ phải thực hiện một thay đổi nhỏ: Tôi đang sử dụng một TreeViewer, vì vậy các mục trong các sự kiện là TreeItem thay vì TableItem; Tôi chỉ sử dụng instanceof cho nó để làm việc với cả hai trường hợp. –

+0

Ouch, tôi đã nói quá sớm ... Đã có vấn đề với màu nền của tiểu bang được chọn, nó khác với tất cả các ô khác cùng hàng, và có vẻ xấu xí. Tôi đã thử nhiều thứ nhưng không thể sửa được. -_- Tôi đã kết thúc bằng cách sử dụng giải pháp của Sorceror. –

0

giải pháp phù thủy đứng vị trí thuận tiện. Tôi đã thích nghi nó vào một IStyledLabelProvider tùy chỉnh để được sử dụng trong một 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; 
    } 
    } 

} 

Lưu ý rằng tôi đang sử dụng IMarker như dữ liệu cho các yếu tố, và một TreeViewer (vì vậy tôi nhận TreeItems), nhưng dữ liệu của bạn có thể khác nhau và người xem của bạn có thể là một TableViewer; bạn chỉ cần thực hiện các điều chỉnh của riêng bạn.

Các vấn đề liên quan