微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 swt tableviewer 中过滤超链接单元格

如何解决如何在 swt tableviewer 中过滤超链接单元格

我有一个无法解决的问题,我花了很多时间。我有一张桌子,我有一列带有超链接。我在表中添加了一些过滤器,当我激活其中一个过滤器时,超链接列无法正确刷新。我实现的代码如上所示。这是一个您可以复制和粘贴、运行和重现错误的示例:

表类:

package borrar;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
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.custom.TableEditor;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;

public class Example {

    private static TableViewer tViewer = null;
    private static Table tblTrades = null;
    private static Text txtTicker;
    public static TickerFilter2 tickerFilter = new TickerFilter2();

    public static void main(String[] args) {

        display display = new display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        Composite parent = new Composite(shell,SWT.NONE);
        parent.setLayout(new FillLayout());
        parent.setLayout(new GridLayout(1,true));
        Label lblTicker = new Label(parent,SWT.NONE);
        lblTicker.setText("Search: ");
        txtTicker = new Text(parent,SWT.NONE);
        txtTicker.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false,1,1));
        txtTicker.addKeyListener(new KeyAdapter() {
            public void keyreleased(KeyEvent ke) {
                tickerFilter.setSearchText(txtTicker.getText());
                tViewer.refresh();
            }
        });
        tViewer = new TableViewer(parent,SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.CENTER);
        String[] titles = { "Ticker","Hyperlinks" };
        createColumns(titles);
        tblTrades = tViewer.getTable();
        tViewer.setContentProvider(new ArrayContentProvider());
        List<DataTable> dt = Arrays.asList(new DataTable("AAA","ImagePath"),new DataTable("ABBBBBB",new DataTable("BBBBBBB","ImagePath"));
        tViewer.setInput(dt);
        tblTrades.setHeaderVisible(true);
        tViewer.addFilter(tickerFilter);

        shell.open();
        shell.pack();
        while (!shell.isdisposed()) {
            if (!display.readAnddispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

    private static void createColumns(String[] titles) {
        TableViewerColumn col = createTableViewerColumn(titles[0],70);
        col.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                DataTable op = (DataTable) element;
                if (op.getTicker() != null) {
                    return op.getTicker();
                } else {
                    return "";
                }
            }
        });
        col = createTableViewerColumn(titles[1],80);
        col.setLabelProvider(new ColumnLabelProvider() {
            Map<Object,Hyperlink> hyperlinks = new HashMap<Object,Hyperlink>();

            @Override
            public void update(ViewerCell cell) {
                TableItem item = (TableItem) cell.getItem();
                final Hyperlink hyperlink;
                if (hyperlinks.containsKey(cell.getElement()) && !hyperlinks.get(cell.getElement()).isdisposed()) {
                    hyperlink = hyperlinks.get(cell.getElement());
                } else {
                    hyperlink = new Hyperlink((Composite) (cell.getViewerRow().getControl()),SWT.NONE);
                    if (cell.getElement() instanceof DataTable) {
                        DataTable Trade = (DataTable) cell.getElement();
                        if (Trade.getPath() != null && !Trade.getPath().equals("")) {
                            hyperlink.setText(Trade.getPath() + "-" + Trade.getTicker());
                            hyperlink.setHref(Trade.getPath());
                        }
                    }
                    hyperlink.addHyperlinkListener(new HyperlinkAdapter() {
                        public void linkActivated(HyperlinkEvent e) {
                            org.eclipse.swt.program.Program.launch(hyperlink.getHref().toString());
                        }
                    });
                    hyperlinks.put(cell.getElement(),hyperlink);
                }
                TableEditor editor = new TableEditor(item.getParent());
                editor.grabHorizontal = true;
                editor.grabVertical = true;
                editor.setEditor(hyperlink,item,cell.getColumnIndex());
                editor.layout();
            }
        });
    }

    private static TableViewerColumn createTableViewerColumn(String title,int bound) {
        final TableViewerColumn viewerColumn = new TableViewerColumn(tViewer,SWT.CENTER);
        final TableColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        return viewerColumn;
    }

    public void refreshTable() {
        tViewer.refresh();
    }
}


我的过滤器类:

package borrar;

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;

public class TickerFilter2 extends ViewerFilter {
    private String searchString;

    public void setSearchText(String s) {
        // ensure that the value can be used for matching
        this.searchString = ".*" + s + ".*";
    }

    @Override
    public boolean select(Viewer viewer,Object parentElement,Object element) {
        if (searchString == null || searchString.length() == 0) {
            return true;
        }
        DataTable Trade = (DataTable) element;
        if (Trade.getTicker().matches(searchString)) {
            return true;
        }
        return false;
    }

}

数据表对象:

package borrar;

public class DataTable {

    String ticker;
    String path;

    public DataTable(String ticker,String path) {
        super();
        this.ticker = ticker;
        this.path = path;
    }

    public String getTicker() {
        return ticker;
    }

    public void setTicker(String ticker) {
        this.ticker = ticker;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }
}

例如,如果您在搜索字段中输入“z”或“l”,您可以看到超链接列未过滤。

过滤器类正确过滤数据,但超链接列过滤不正常。

这里有一个结果不好的图像:

Here you have an image with the bad result

解决方法

TableViewer 并不真正了解 TableEditor 代码,因此在过滤时不会处理它们。

您或许可以使用 EditingSupport 代码。以下代码定义了一个单元格编辑器,它会在您单击列单元格时立即执行操作。

对于列定义,将您的代码替换为:

   col.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(final Object element) {
          // Whatever you want for the cell text here
          final DataTable op = (DataTable) element;
          return op.getPath();
       }
    });

    col.setEditingSupport(new HyperlinkEditingSupport(tViewer));

编辑支持类:

public class HyperlinkEditingSupport extends EditingSupport
{
  private final HyperlinkCellEditor _editor;

  public HyperlinkEditingSupport(final TableViewer viewer)
  {
    super(viewer);

    _editor = new HyperlinkCellEditor(viewer.getTable());
  }

  @Override
  protected CellEditor getCellEditor(final Object element)
  {
    return _editor;
  }

  @Override
  protected boolean canEdit(final Object element)
  {
    return true;
  }

  @Override
  protected Object getValue(final Object element)
  {
    // Return the value you want launched
    return ((DataTable)element).getPath();
  }

  @Override
  protected void setValue(final Object element,final Object value)
  {
    // no action
  }
}

还有CellEditor。这有点奇怪,因为我们将在调用编辑器后立即启动,因此我们实际上并不需要单独的编辑器:

public class HyperlinkCellEditor extends CellEditor
{
  public HyperlinkCellEditor(final Composite parent)
  {
    super(parent);
  }

  @Override
  protected Control createControl(final Composite parent)
  {
    return new Composite(parent,SWT.None);
  }

  @Override
  protected Object doGetValue()
  {
    return new Object[0];
  }

  @Override
  protected void doSetFocus()
  {
    // no action
  }

  @Override
  protected void doSetValue(final Object value)
  {
    final String path = (String)value;

    // TODO Open the link
  }
}
,

我修改了@greg-449 解决方案以在单元格中显示链接外观,仅修改 LabelProvider:

col.setLabelProvider(new StyledCellLabelProvider() {
        @Override
        public void update(ViewerCell cell) {
            DataTable op = (DataTable) cell.getItem().getData();
            StyledString ss = new StyledString();
            StyleRange sr = new StyleRange(0,80,Display.getCurrent().getSystemColor(SWT.COLOR_BLUE),null);
            sr.underline = true;
            ss.append(op.getPath(),StyledString.DECORATIONS_STYLER);
            cell.setText("Open Image");
            StyleRange[] range = { sr };
            cell.setStyleRanges(range);
        }
    });
    col.setEditingSupport(new HyperlinkEditingSupport(tViewer));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。