对于 SWT(JFACE)中 FilterTree的改造,同时过滤两棵树

FilterTree处于 org.eclipse.ui.dialogs中,他的显示效果大致如下:


由于需求中要同时展示两颗Tree,并且同时具有过滤功能,如果使用两个FilterTree ,在UI上很难看,所以考虑改写FilterTree,使之同时操控两棵树,最初的方案是继承FilterTree改写他的createControl()增加一个treeviewer,但发现其中很多私有属性在改写中收到很多限制,于是直接使用了起源,直接在源码内改写,由于它与PatternFilter关系比较紧密,故同时引入,大体思想就是增加一个TreeViewer,改变treeComposite的Layout,并且为新的treeViewer克隆一份过滤处理程序,与之前默认的treeViewer大体相同,最后增加方法支持是否显示新增treeviewer动态设置。



重要代码

CCBFilterTree.java


package com.benson.ccb.favoritites.filterView.filter;

/*******************************************************************************
 * Copyright (c) 2004, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jacek Pospychala - bug 187762
 *******************************************************************************/


import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * A simple control that provides a text widget and a tree viewer. The contents
 * of the text widget are used to drive a PatternFilter that is on the viewer.
 *
 * @see org.eclipse.ui.dialogs.PatternFilter
 * @since 3.2
 */
public class CCBFilterTree extends Composite {

    /**
     * The filter text widget to be used by this tree. This value may be
     * <code>null</code> if there is no filter widget, or if the controls have
     * not yet been created.
     */
    protected Text filterText;

    /**
     * The control representing the clear button for the filter text entry. This
     * value may be <code>null</code> if no such button exists, or if the
     * controls have not yet been created.
     * <p>
     * <strong>Note:</strong> As of 3.5, this is not used if the new look is chosen.
     * </p>
     */
    protected ToolBarManager filterToolBar;

    /**
     * The control representing the clear button for the filter text entry. This
     * value may be <code>null</code> if no such button exists, or if the
     * controls have not yet been created.
     * <p>
     * <strong>Note:</strong> This is only used if the new look is chosen.
     * </p>
     *
     * @since 3.5
     */
    protected Control clearButtonControl;
    
    
    /**
     * The viewer for the filtered tree. This value should never be
     * <code>null</code> after the widget creation methods are complete.
     */
    protected TreeViewer treeViewer;
    
    
    /**
     * The viewer for the extra filtered tree. This value is possible
     * <code>null</code>.
     */
    protected TreeViewer extraTreeViewer;


    /**
     * The Composite on which the filter controls are created. This is used to
     * set the background color of the filter controls to match the surrounding
     * controls.
     */
    protected Composite filterComposite;

    /**
     * The pattern filter for the tree. This value must not be <code>null</code>.
     */
    private CCBPatternFilter patternFilter;

    /**
     * The text to initially show in the filter text control.
     */
    protected String initialText = ""; //$NON-NLS-1$

    /**
     * The job used to refresh the tree.
     */
    private Job refreshJob;
    
    private Job refreshJobExtra;

    /**
     * The parent composite of the filtered tree.
     *
     * @since 3.3
     */
    protected Composite parent;

    /**
     * Whether or not to show the filter controls (text and clear button). The
     * default is to show these controls. This can be overridden by providing a
     * setting in the product configuration file. The setting to add to not show
     * these controls is:
     *
     * org.eclipse.ui/SHOW_FILTERED_TEXTS=false
     */
    protected boolean showFilterControls;

    /**
     * @since 3.3
     */
    protected Composite treeComposite;

    /**
     * Tells whether to use the pre 3.5 or the new look.
     *
     * @since 3.5
     */
    private boolean useNewLook = false;

    /**
     * Image descriptor for enabled clear button.
     */
    private static final String CLEAR_ICON = "org.eclipse.ui.internal.dialogs.CLEAR_ICON"; //$NON-NLS-1$

    /**
     * Image descriptor for disabled clear button.
     */
    private static final String DISABLED_CLEAR_ICON= "org.eclipse.ui.internal.dialogs.DCLEAR_ICON"; //$NON-NLS-1$

    /**
     * Maximum time spent expanding the tree after the filter text has been
     * updated (this is only used if we were able to at least expand the visible
     * nodes)
     */
    private static final long SOFT_MAX_EXPAND_TIME = 200;

    /**
     * Get image descriptors for the clear button.
     */
    static {
        ImageDescriptor descriptor = AbstractUIPlugin
                .imageDescriptorFromPlugin(PlatformUI.PLUGIN_ID,
                        "$nl$/icons/full/etool16/clear_co.gif"); //$NON-NLS-1$
        if (descriptor != null) {
            JFaceResources.getImageRegistry().put(CLEAR_ICON, descriptor);
        }
        descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(
                PlatformUI.PLUGIN_ID, "$nl$/icons/full/dtool16/clear_co.gif"); //$NON-NLS-1$
        if (descriptor != null) {
            JFaceResources.getImageRegistry().put(DISABLED_CLEAR_ICON, descriptor);
        }
    }

    /**
     * Create a new instance of the receiver.
     *
     * @param parent
     *            the parent <code>Composite</code>
     * @param treeStyle
     *            the style bits for the <code>Tree</code>
     * @param filter
     *            the filter to be used
     *
     * @deprecated As of 3.5, replaced by
     *             {@link #FilteredTree(Composite, int, PatternFilter, boolean)} where using the new
     *             look is encouraged
     */
    public CCBFilterTree(Composite parent, int treeStyle, CCBPatternFilter filter) {
        super(parent, SWT.NONE);
        this.parent = parent;
        init(treeStyle, filter);
    }
    
    /**
     * Create a new instance of the receiver.
     *
     * @param parent
     *            the parent <code>Composite</code>
     * @param treeStyle
     *            the style bits for the <code>Tree</code>
     * @param filter
     *            the filter to be used
     * @param useNewLook
     *            <code>true</code> if the new 3.5 look should be used
     * @since 3.5
     */
    public CCBFilterTree(Composite parent, int treeStyle, CCBPatternFilter filter, boolean useNewLook) {
        super(parent, SWT.NONE);
        this.parent = parent;
        this.useNewLook= useNewLook;
        init(treeStyle, filter);
    }

    /**
     * Create a new instance of the receiver. Subclasses that wish to override
     * the default creation behavior may use this constructor, but must ensure
     * that the <code>init(composite, int, PatternFilter)</code> method is
     * called in the overriding constructor.
     *
     * @param parent
     *            the parent <code>Composite</code>
     * @see #init(int, PatternFilter)
     *
     * @since 3.3
     * @deprecated As of 3.5, replaced by {@link #FilteredTree(Composite, boolean)} where using the
     *             look is encouraged
     * @wbp.parser.constructor
     */
    protected CCBFilterTree(Composite parent) {
        super(parent, SWT.NONE);
        this.parent = parent;
    }
    
    /**
     * Create a new instance of the receiver. Subclasses that wish to override
     * the default creation behavior may use this constructor, but must ensure
     * that the <code>init(composite, int, PatternFilter)</code> method is
     * called in the overriding constructor.
     *
     * @param parent
     *            the parent <code>Composite</code>
     * @param useNewLook
     *            <code>true</code> if the new 3.5 look should be used
     * @see #init(int, PatternFilter)
     *
     * @since 3.5
     */
    protected CCBFilterTree(Composite parent, boolean useNewLook) {
        super(parent, SWT.NONE);
        this.parent = parent;
        this.useNewLook = useNewLook;
    }

    /**
     * Create the filtered tree.
     *
     * @param treeStyle
     *            the style bits for the <code>Tree</code>
     * @param filter
     *            the filter to be used
     *
     * @since 3.3
     */
    protected void init(int treeStyle, CCBPatternFilter filter) {
        patternFilter = filter;
        showFilterControls = PlatformUI.getPreferenceStore().getBoolean(
                IWorkbenchPreferenceConstants.SHOW_FILTERED_TEXTS);
        createControl(parent, treeStyle);
        createRefreshJob();
        setInitialText(WorkbenchMessages.FilteredTree_FilterMessage);
        setFont(parent.getFont());

    }

    /**
     * Create the filtered tree's controls. Subclasses should override.
     *
     * @param parent
     * @param treeStyle
     */
    protected void createControl(Composite parent, int treeStyle) {
        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        setLayout(layout);
        setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        if (showFilterControls) {
            if (!useNewLook || useNativeSearchField(parent)) {
                filterComposite= new Composite(this, SWT.NONE);
            } else {
                filterComposite= new Composite(this, SWT.BORDER);
                filterComposite.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
            }
            GridLayout filterLayout= new GridLayout(2, false);
            filterLayout.marginHeight= 0;
            filterLayout.marginWidth= 0;
            filterLayout.numColumns=2;
            filterComposite.setLayout(filterLayout);
            filterComposite.setFont(parent.getFont());

            createFilterControls(filterComposite);
            filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING,
                    true, false));
        }

        treeComposite = new Composite(this, SWT.NONE);
        GridLayout treeCompositeLayout = new GridLayout();

        treeCompositeLayout.marginHeight = 0;
        treeCompositeLayout.marginWidth = 0;
        treeCompositeLayout.numColumns=2;
        treeComposite.setLayout(treeCompositeLayout);
        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        treeComposite.setLayoutData(data);
        treeViewer = createTreeViewer(treeComposite, treeStyle);
        extraTreeViewer = createTreeViewer(treeComposite, treeStyle);
        treeViewer.getControl().addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                refreshJob.cancel();
            }
        });
        extraTreeViewer.getControl().addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                refreshJobExtra.cancel();
            }
        });
    }
    
    private static Boolean useNativeSearchField;
    
    private static boolean useNativeSearchField(Composite composite) {
        if (useNativeSearchField == null) {
            useNativeSearchField = Boolean.FALSE;
            Text testText = null;
            try {
                testText = new Text(composite, SWT.SEARCH | SWT.ICON_CANCEL);
                useNativeSearchField = new Boolean((testText.getStyle() & SWT.ICON_C
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值