Eclipse插件开发之Preference扩展点的学习

Preferences展点及其使用心得

本文学习参照文章“Preferences in the Eclipse Workbench UI”,除了实现流程外,更重要的是对例子中代码的学习

在Eclipse中,选择window->preferences后打开preferences窗口,这个窗口是Eclipse所有设置项的集中地,同时也是我们自定义的插件进行设置的窗口。

第一章:Preference概述

Preference是一种数据,它存在于工作空间中,存储的是Eclipse工作的状态,使之保持一致性。Eclipse2.0提供了两种preference:UI preferences (the same as in 1.0) and Core Preferences。Preference并不涉及到当前工作空间中的任何资源,它应该被编辑器,视图或者其它的操作资源的对象所使用。一种资源实例对应的数据最好存储成一个属性。Preference对任何插件来说都是可用的,当然,先决条件是存在插件。通常的方法是你的插件上为你觉得可能被其他插件用到的Preference提供API, Preference的值存储在工作空间的.metadata/.plugins目录下面。

每个插件都有自己的preference store(存储区),这是工作空间提供的。在下面的例子中(这个例子是在文件中查找错误的单词),我们将定义一个插件,使用它的preference store存储preference。在UI中当要使用插件的时候我们定义AbustractUIPlugin的子类。构造函数将在工作台中创建一个独立的允许容易访问的插件实例。我们实现方法initializeDefaultPreferences为preference设置默认值。首先为错误的单词定义了一个preference,另外一个是定义高量显示的颜色。每个preference的值与给定的key(键值对的存在形式)相对应。

所有的preference应该都有默认值来保证在任何时候都有值。默认值也保证了UI能够提供一种方式重置preference的值回到初始设定,这是通过“Restore”button实现的。Preference的默认值在插件中也应该进行初始化,以便它在任何UI创建之前设置。  

第二章:示例实现

            

  一个插件在工作区都会有它的参数存储区 ,在本例中,我们定义一个插件用它的参数存储区来作为我们的参数。因为要用到UI界面,我们把它实现为AbstractUIPlugin的子类---IabstractWorkbenchPlugin类, IabstractWorkbenchPlugin定义了一个方法,当preference第一次创建的时候,它会被调用。这个方法就是initializeDefaultPreferences。在这个方法中你应该把所有的值都设为默认值,才能够使用preference store。我们在PreferenceConverter中用helper方法设定默认的color,PreferenceConverter允许插件开发者设置和得到一些常见的存储类型的preference的值,例如FontData,Point等等。这个API提供是因为preference无论是存储还是读取都是String—以一种我们人可以理解的格式。这样来平衡的属性机制。我们那个稍微复杂的错误单词的preference在初始化的时候使用了预先设定的值因为在PreferenceConvertor中并没有提供API来存储和读取String数组。

public class BadWordCheckerPlugin extends AbstractUIPlugin {
        //The shared instance.
        private static BadWordCheckerPlugin plugin;
 
        //The identifiers for the preferences 
        public static final String BAD_WORDS_PREFERENCE = "badwords";
        public static final String HIGHLIGHT_PREFERENCE = "highlight";
 
        //The default values for the preferences
        public static final String DEFAULT_BAD_WORDS = "bug;bogus;hack;";
        public static final int DEFAULT_HIGHLIGHT = SWT.COLOR_BLUE;
 
        public BadWordCheckerPlugin(IPluginDescriptor descriptor) {
               super(descriptor);
               plugin = this;
        }
 
        public static BadWordCheckerPlugin getDefault() {
               return plugin;
        }
 
        /** 
         * Initializes a preference store with default preference values 
         * for this plug-in.
         */
        protected void initializeDefaultPreferences(IPreferenceStore store) {
               store.setDefault(BAD_WORDS_PREFERENCE, DEFAULT_BAD_WORDS);
               Color color= Display.getDefault().getSystemColor(DEFAULT_HIGHLIGHT);
               PreferenceConverter.setDefault(store,  HIGHLIGHT_PREFERENCE, color.getRGB());
 
        }
}

xml中配置

<extension point="org.eclipse.ui.preferencePages">

        <page id="BadWordsPreferencePage"

            name="Bad Words"

            class="org.eclipse.ui.articles.badwordchecker.BadWordsPreferencePage">

        </page>

       

        <page id="BadWordsColorPreferencePage"

                name="Colors"

                      class="org.eclipse.ui.articles.badwordchecker.BadWordsColorPreferencePage"

            category="BadWordsPreferencePage">

        </page>

</extension>

是在页面中显示的名字, 是参数配置页面类,这个类必须实现IWorkbenchPreferencePage接口。 是页面中显示的包含关系(不用多解释)。

第二个类:reference Page

这个页面只是一个用JFace实现的简单页面,Eclipse中有个PreferencePage类—它实现了Preference 页面需要的大多数API,当点下确定键后,参数对话框的信息就会被保存。代码如下:

package org.eclipse.ui.articles.badwordchecker;

import org.eclipse.jface.preference.ColorFieldEditor;

import org.eclipse.jface.preference.PreferencePage;

import org.eclipse.swt.SWT;

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.ui.IWorkbench;

import org.eclipse.ui.IWorkbenchPreferencePage;

/**

 * The BadWordsColorPreferencePage is a preference page that

 * handles setting the colors used by the editors.

 */

public class BadWordsColorPreferencePage

              extends PreferencePage

              implements IWorkbenchPreferencePage {

              private ColorFieldEditor colorEditor;

              /*

               * @see PreferencePage#createContents(Composite)

               */

              @SuppressWarnings("deprecation")

              protected Control createContents(Composite parent) {

                            Composite entryTable = new Composite(parent, SWT.NULL);

                            //Create a data that takes up the extra space in the dialog .

                            GridData data = new GridData(GridData.FILL_HORIZONTAL);

                            data.grabExcessHorizontalSpace = true;

                            entryTable.setLayoutData(data);

                            GridLayout layout = new GridLayout();

                            entryTable.setLayout(layout);

                           

                            Composite colorComposite = new Composite(entryTable,SWT.NONE);

                            colorComposite.setLayout(new GridLayout());

                           

                            //Create a data that takes up the extra space in the dialog.

                            colorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

                            colorEditor =

                                          new ColorFieldEditor(

                                                        BadWordCheckerPlugin.HIGHLIGHT_PREFERENCE,

                                                        "Highlight Color",

                                                        colorComposite);                                           

                                         

                           

                            //Set the editor up to use this page

                            colorEditor.setPreferencePage(this);

                            colorEditor.setPreferenceStore(getPreferenceStore());

                            colorEditor.load();

                            return entryTable;

              }

              /*

               * @see IWorkbenchPreferencePage#init(IWorkbench)

               */

              public void init(IWorkbench workbench) {

                            //Initialize the preference store we wish to use

                            setPreferenceStore(BadWordCheckerPlugin.getDefault().getPreferenceStore());

              }

              /**

               * Performs special processing when this page's Restore Defaults button has

               * been pressed.

               * Sets the contents of the color field to the default value in the preference

               * store.

               */

              protected void performDefaults() {

                            colorEditor.loadDefault();

              }

              /**

               * Method declared on IPreferencePage. Save the

               * color preference to the preference store.

               */

              public boolean performOk() {

                            colorEditor.store();

                            return super.performOk();

              }

}

运行效果如下图:

第三个类:ad Words Preference Page

下面将要用一个更复杂些的组件作为preference,并使它存储在preference store且在preference页面中可编辑。例子是:添加String数组的bad words preference。

由于PreferenceConverter没有String数组的API,我们在BadWordCheckerPlugin中来实现。添加如下代码:

/**
 * Return the bad words preference default.
 */
public String[] getDefaultBadWordsPreference(){
        return convert(getPreferenceStore().getDefaultString(BAD_WORDS_PREFERENCE));
}
 
/**
 * Returns the bad words preference.
 */
public String[] getBadWordsPreference() {
        return convert(getPreferenceStore().getString(BAD_WORDS_PREFERENCE));
}
        
/**
 * Converts PREFERENCE_DELIMITER delimited String to a String array.
 */
private String[] convert(String preferenceValue) {
        StringTokenizer tokenizer =
               new StringTokenizer(preferenceValue, PREFERENCE_DELIMITER);
        int tokenCount = tokenizer.countTokens();
        String[] elements = new String[tokenCount];
        for (int i = 0; i < tokenCount; i++) {
               elements[i] = tokenizer.nextToken();
        }
 
        return elements;
}
 
/**
 * Sets the bad words preference.
 */
public void setBadWordsPreference(String[] elements) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < elements.length; i++) {
               buffer.append(elements[i]);
               buffer.append(PREFERENCE_DELIMITER);
        }
        getPreferenceStore().setValue(BAD_WORDS_PREFERENCE, buffer.toString());
}

BadWordsPreferencePage主要是实现界面和两个按键的响应。代码如下(可以仔细研究):

package org.eclipse.ui.articles.badwordchecker;

import org.eclipse.jface.preference.PreferencePage;

import org.eclipse.swt.SWT;

import org.eclipse.swt.events.SelectionAdapter;

import org.eclipse.swt.events.SelectionEvent;

import org.eclipse.swt.layout.GridData;

import org.eclipse.swt.layout.GridLayout;

import org.eclipse.swt.widgets.*;

import org.eclipse.ui.IWorkbench;

import org.eclipse.ui.IWorkbenchPreferencePage;

public class BadWordsPreferencePage

              extends PreferencePage

              implements IWorkbenchPreferencePage {

              //The list that displays the current bad words

              private List badWordList;

              //The newEntryText is the text where new bad words are specified

              private Text newEntryText;

              /*

               * @see PreferencePage#createContents(Composite)

               */

              protected Control createContents(Composite parent) {

                            Composite entryTable = new Composite(parent, SWT.NULL);

                            //Create a data that takes up the extra space in the dialog .

                            GridData data = new GridData(GridData.FILL_HORIZONTAL);

                            data.grabExcessHorizontalSpace = true;

                            entryTable.setLayoutData(data);

                            GridLayout layout = new GridLayout();

                            entryTable.setLayout(layout);                                   

                                                       

                            //Add in a dummy label for spacing

                            new Label(entryTable,SWT.NONE);

                            badWordList = new List(entryTable, SWT.BORDER);

                            badWordList.setItems(BadWordCheckerPlugin.getDefault().getBadWordsPreference());

                            //Create a data that takes up the extra space in the dialog and spans both columns.

                            data = new GridData(GridData.FILL_BOTH);

                            badWordList.setLayoutData(data);

                           

                            Composite buttonComposite = new Composite(entryTable,SWT.NULL);

                           

                            GridLayout buttonLayout = new GridLayout();

                            buttonLayout.numColumns = 2;

                            buttonComposite.setLayout(buttonLayout);

                            //Create a data that takes up the extra space in the dialog and spans both columns.

                            data = new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING);

                            buttonComposite.setLayoutData(data);                    

                           

                            Button addButton = new Button(buttonComposite, SWT.PUSH | SWT.CENTER);

                            addButton.setText("Add to List"); //$NON-NLS-1$

                            addButton.addSelectionListener(new SelectionAdapter() {

                                          public void widgetSelected(SelectionEvent event) {

                                                        badWordList.add(newEntryText.getText(), badWordList.getItemCount());

                                          }

                            });

                           

                            newEntryText = new Text(buttonComposite, SWT.BORDER);

                            //Create a data that takes up the extra space in the dialog .

                            data = new GridData(GridData.FILL_HORIZONTAL);

                            data.grabExcessHorizontalSpace = true;

                            newEntryText.setLayoutData(data);

                           

                           

                            Button removeButton = new Button(buttonComposite, SWT.PUSH | SWT.CENTER);

                            removeButton.setText("Remove Selection"); //$NON-NLS-1$

                            removeButton.addSelectionListener(new SelectionAdapter() {

                                          public void widgetSelected(SelectionEvent event) {

                                                        badWordList.remove(badWordList.getSelectionIndex());

                                          }

                            });

                           

                            data = new GridData();

                            data.horizontalSpan = 2;

                            removeButton.setLayoutData(data);

             

                            return entryTable;

              }

              /*

               * @see IWorkbenchPreferencePage#init(IWorkbench)

               */

              public void init(IWorkbench workbench) {

                            //Initialize the preference store we wish to use

                            setPreferenceStore(BadWordCheckerPlugin.getDefault().getPreferenceStore());

              }

              /**

               * Performs special processing when this page's Restore Defaults button has been pressed.

               * Sets the contents of the nameEntry field to

               * be the default

               */

              protected void performDefaults() {

                            badWordList.setItems(BadWordCheckerPlugin.getDefault().getDefaultBadWordsPreference());

              }

              /**

               * Method declared on IPreferencePage. Save the

               * author name to the preference store.

               */

              public boolean performOk() {

                            BadWordCheckerPlugin.getDefault().setBadWordsPreference

(badWordList.getItems());

                            return super.performOk();

              }

}

运行结果如下:

第四:对参数值的应用

通常,一个preference是向一个打开的editor或者view进行传值。这时,就需要通过IPropertyChangeListener对变化添加监听。IPropertyChangeListener类是对IProperyStore添加监听,当用户点击OK或者Apply时,监听会被触发。

在这个例子中,我们实现了一个视图,用选定的颜色显示存在的bad words,这个视图通过IPropertyChangeListener更新显示的颜色。

   
   new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
               if (event.getProperty().equals(BadWordCheckerPlugin.HIGHLIGHT_PREFERENCE)) {
                       //Update the colors by clearing the current color,
                       //updating the view and then disposing the old color.
                       Color oldForeground = foreground;
                       foreground = null;
                       setBadWordHighlights(text.getText());
                       oldForeground.dispose();
               }
               if (event.getProperty().equals(BadWordCheckerPlugin.BAD_WORDS_PREFERENCE))
                       //Only update the text if only the words have changed
                       setBadWordHighlights(text.getText());
        }
};
   
   public void init(IViewSite site) throws PartInitException {
        super.init(site);
        site.getPage().addSelectionListener(...);
        BadWordCheckerPlugin
               .getDefault()
               .getPreferenceStore()
               .addPropertyChangeListener(preferenceListener);}
   
   public void dispose() {
        getSite().getPage().removeSelectionListener(...);
        BadWordCheckerPlugin
               .getDefault()
               .getPreferenceStore()
               .removePropertyChangeListener(preferenceListener);
        if (foreground != null)
               foreground.dispose();
        super.dispose();
}

实现效果如下:

 

具体类实现代码如下(好多代码还不懂,有待于学习):

package org.eclipse.ui.articles.badwordchecker;

import java.io.IOException;

import java.io.InputStream;

import org.eclipse.core.resources.IFile;

import org.eclipse.core.resources.IResource;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.core.runtime.IAdaptable;

import org.eclipse.jface.preference.PreferenceConverter;

import org.eclipse.jface.util.IPropertyChangeListener;

import org.eclipse.jface.util.PropertyChangeEvent;

import org.eclipse.jface.viewers.ISelection;

import org.eclipse.jface.viewers.IStructuredSelection;

import org.eclipse.swt.SWT;

import org.eclipse.swt.custom.StyleRange;

import org.eclipse.swt.custom.StyledText;

import org.eclipse.swt.graphics.Color;

import org.eclipse.swt.layout.GridData;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.ui.ISelectionListener;

import org.eclipse.ui.IViewSite;

import org.eclipse.ui.IWorkbenchPart;

import org.eclipse.ui.PartInitException;

import org.eclipse.ui.part.ViewPart;

/**

 * The BadWordsView is a simple view that creates a StyledText'

 * that highlights the bad words.

 */

public class BadWordsView extends ViewPart {

              private Color foreground;

              private StyledText text;

              ISelectionListener selectionListener = new ISelectionListener() {

                            /**

                             * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)

                             */

                            public void selectionChanged(

                                          IWorkbenchPart part,

                                          ISelection selection) {

                                          setText(selection);

                            }

              };

              IPropertyChangeListener preferenceListener =

                            new IPropertyChangeListener() {

                            /*

                             * @see IPropertyChangeListener.propertyChange()

                             */

                            public void propertyChange(PropertyChangeEvent event) {

                                          if (event

                                                        .getProperty()

                                                        .equals(BadWordCheckerPlugin.HIGHLIGHT_PREFERENCE)) {

                                                        //Update the colors by clearing the current color,

                                                        //updating the view and then disposing the old color.

                                                        Color oldForeground = foreground;

                                                        foreground = null;

                                                        setBadWordHighlights(text.getText());

                                                        oldForeground.dispose();

                                          }

                                          if (event

                                                        .getProperty()

                                                        .equals(BadWordCheckerPlugin.BAD_WORDS_PREFERENCE))

                                                        //Only update the text if only the words have changed

                                                        setBadWordHighlights(text.getText());

                            }

              };

              /**

               * @see org.eclipse.ui.IWorkbenchPart#createPartControl(Composite)

               */

              public void createPartControl(Composite parent) {

                            text = new StyledText(parent, SWT.NULL);

                            GridData data = new GridData(GridData.FILL_BOTH);

                            text.setLayoutData(data);

                            setText(

                                          getSite()

                                                        .getWorkbenchWindow()

                                                        .getSelectionService()

                                                        .getSelection());

              }

              /**

               * Set the text value in the widget passed on the supplied

               * selection

               */

              private void setText(ISelection selection) {

                            if (selection instanceof IStructuredSelection) {

                                          Object firstObject =

                                                        ((IStructuredSelection) selection).getFirstElement();

                                          if (firstObject != null && firstObject instanceof IAdaptable) {

                                                        Object resource =

                                                                      ((IAdaptable) firstObject).getAdapter(IResource.class);

                                                        if (resource != null && resource instanceof IFile) {

                                                                      try {

                                                                                    InputStream contents = ((IFile) resource).getContents();

                                                                                    byte[] data = new byte[contents.available()];

                                                                                    contents.read(data);

                                                                                    setBadWordHighlights(new String(data));

                                                                      } catch (CoreException exception) {

                                                                                    //Do nothing

                                                                      } catch (IOException exception) {

                                                                                    //Do nothing

                                                                      }

                                                        }

                                          }

                            }

              }

              /**

               * Set the highlights for the bad words using the passed in

               * text

               */

              private void setBadWordHighlights(String fileContents) {

                            Color foregroundColor = getForegroundColor();

                            text.setText(fileContents);

                            String[] badStrings =

                                          BadWordCheckerPlugin.getDefault().getBadWordsPreference();

                            Color background = text.getBackground();

                            for (int i = 0; i < badStrings.length; i++) {

                                          String badWord = badStrings[i];

                                          int length = badWord.length();

                                          int nextIndex = 0;

                                          while (nextIndex > -1) {

                                                        nextIndex = fileContents.indexOf(badWord, nextIndex);

                                                        if (nextIndex > -1) {

                                                                      StyleRange range =

                                                                                    new StyleRange(

                                                                                                  nextIndex,

                                                                                                  length,

                                                                                                  foregroundColor,

                                                                                                  background);

                                                                      text.setStyleRange(range);

                                                                      nextIndex += length;

                                                        }

                                          }

                            }

              }

              /**

               * Get the current value of the foreground color.

               * Create it if it does not exist yet.

               */

              private Color getForegroundColor() {

                            if (foreground == null)

                                          foreground =

                                                        new Color(

                                                                      text.getDisplay(),

                                                                      PreferenceConverter.getColor(

                                                                                    BadWordCheckerPlugin.getDefault().getPreferenceStore(),

                                                                                    BadWordCheckerPlugin.HIGHLIGHT_PREFERENCE));

                            return foreground;

              }

              /**

               * @see org.eclipse.ui.IWorkbenchPart#setFocus()

               */

              public void setFocus() {

              }

              /* (non-Javadoc)

              * Method declared on IViewPart.

              */

              public void init(IViewSite site) throws PartInitException {

                            super.init(site);

                            site.getPage().addSelectionListener(selectionListener);

                            BadWordCheckerPlugin

                                          .getDefault()

                                          .getPreferenceStore()

                                          .addPropertyChangeListener(preferenceListener);

              }

              /* (non-Javadoc)

              * Method declared on IWorkbenchPart.

              */

              public void dispose() {

                            // remove ourselves as a selection listener

                            getSite().getPage().removeSelectionListener(selectionListener);

                            //and no longer listen to the preference store

                            BadWordCheckerPlugin

                                          .getDefault()

                                          .getPreferenceStore()

                                          .removePropertyChangeListener(preferenceListener);

                            if (foreground != null)

                                          foreground.dispose();

                            // run super.

                            super.dispose();

              }

}

原文地址:https://www.cnblogs.com/drawwindows/p/2109191.html