Eclipse首选项开发

JAVA.SWT/JFace: JFace篇之首选项2010年08月11日 星期三 10:36《Eclipse SWT/JFACE 核心应用》 清华大学出版社 18 首选项

    在一个应用系统中,首选项是可以根据用户的喜好来设定的,一般是以键(key)/值(value)来保存的。

18.1 首选项概述
有关保存首选项设置的类有:
◆ PreferenceStore:可以将设置以key/value的形式保存为文件,也可以载入文件后方便的获取所设定的值。
◆ PreferenceConverter:保存为文件的首选项为字符串的形式,对应像颜色、字体这些对象,无法直接保存为字符串,使用该类转换,将颜色保存为字符串的样式,并且将字符串转化为颜色对象。

有关首选项的设置的类有:
◆ FieldEditor:这是一个抽象类,虽然对首选项的设置可以使用最基本的标签、按钮等SWT控件实现,但是会很麻烦,为了简化创建各种设置的选项,可以使用FieldEditor对象创建常用的控件。
◆ BooleanFieldEditor:布尔型选项的设置。
◆ IntegerFieldEditor:整型值设置。
◆ StringFieldEditor:字符串型值的设置。
◆ RadioGroupFieldEditor:分组面板型的设置。
◆ ColorFieldEditor:颜色值的设置。
◆ FontFieldEditor:字体型值的设置。
◆ DirectoryFieldEditor:选择文件目录的设置。
◆ FileFieldEditor:选择文件的设置。
◆ PathEditor:选择路径的设置。

有关显示首选项页面的类有:
◆ PreferencePage:表示一个首选项页面,类似于向导式对话框中的一个向导页面WizardPage。
◆ PreferenceNode:浏览首选项的树型菜单的一个节点,一个节点对应一个首选项页面PreferencePage。
◆ PreferenceManager:负责管理每个节点和首选项页面,包括树的结构等。
◆ PreferenceDialog:显示首选项的对话框容器。

18.2 保存首选项的设置
保存首选项的类PreferenceStore。Java中使用.properties为扩展名的文件来保存首选项的设置。

1. 首选项值的设置和获取
首选项的设置是以key和value格式来表示的,如下:
Password=123
UserName=Janet
Database=mysql

要保存这样一个格式的文件代码如下:
   PreferenceStore preferenceStore = new PreferenceStore("F:\\myPreference.properties");
   preferenceStore.setValue("Database", "mysql");
   preferenceStore.setValue("UserName", "Janet");
   preferenceStore.setValue("Password", "123");
   try {
    preferenceStore.save();
   } catch (IOException e) {
    e.printStackTrace();
   }

读取设置的值:
   PreferenceStore preferenceStore = new PreferenceStore("F:\\myPreference.properties");
   try {
    preferenceStore.load(); // 装载文件
   } catch (IOException e) {
    e.printStackTrace();
   }
   String database = preferenceStore.getString("Database");

设置默认值:
setDefaultXXX。
当通过get方法获取一个设置时,程序首先查找保存的.properties文件中是否已设置了该值,如果没有则返回该选项的默认值。


2. 保存首选项所涉及的事件
当某个选项值改变时出发PropertyChangeEvent事件,如下:
   preferenceStore.addPropertyChangeListener(new IPropertyChangeListener() {
    public void propertyChange(PropertyChangeEvent event) {
     if (event.getProperty().equals("Database")) {
      System.out.println("old value:" + event.getOldValue());
      System.out.println("new value:" + event.getNewValue());
     }
    }
   });
   preferenceStore.setValue("Database", "sqlserver"); // 触发事件

18.3 显示首选项页面

1. 创建一个首选项页面
package www.swt.com.ch18;

import org.eclipse.jface.preference.IPreferenceStore;

public class SystemSettingPage extends PreferencePage {
public SystemSettingPage() {
}

private Text userName;
private Text password;
//该方法为必须实现的方法,在此方法中创建页面上的各种控件
protected Control createContents(Composite parent) {
   Composite composite = new Composite(parent, SWT.NONE);
   composite.setLayout(new GridLayout(2, false));
   //获取保存此页面的PreferenceStore对象
   IPreferenceStore preferenceStore = getPreferenceStore();

   new Label(composite, SWT.LEFT).setText("登录用户名:");
   userName = new Text(composite, SWT.BORDER);
   userName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
   //设置用户名为保存在文件中的值
   userName.setText(preferenceStore.getString(Constants.USER_NAME));

   new Label(composite, SWT.LEFT).setText("登录密码:");
   password = new Text(composite, SWT.BORDER);
   password.setEchoChar('*');
   password.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
   //设置密码为保存在文件中的值
   password.setText(preferenceStore.getString(Constants.PASSWORD));
   return composite;
}

/*
* (非 Javadoc)
*
* @see org.eclipse.jface.preference.PreferencePage#performDefaults()
* 覆盖父类中的方法,但单击“恢复默认值”按钮时调用该方法
*/
protected void performDefaults() {
   IPreferenceStore preferenceStore = getPreferenceStore();
   userName.setText( preferenceStore.getDefaultString(Constants.USER_NAME));
   password.setText( preferenceStore.getDefaultString(Constants.PASSWORD));
}

/*
* (非 Javadoc)
*
* @see org.eclipse.jface.preference.PreferencePage#performOk()
* 覆盖父类中的方法,但单击“应用”按钮时调用该方法
*/
public boolean performOk() {
   IPreferenceStore preferenceStore = getPreferenceStore();
   if (userName != null)
    preferenceStore.setValue(Constants.USER_NAME, userName.getText());
   if (password != null)
    preferenceStore.setValue(Constants.PASSWORD, password.getText());
   return true;
}
/*
* (非 Javadoc)
*
* @see org.eclipse.jface.preference.PreferencePage#contributeButtons(org.eclipse.swt.widgets.Composite)
*/
protected void contributeButtons(Composite parent) {
   // super.contributeButtons(parent);
   Button bt1 = new Button(parent, SWT.NONE);
   bt1.setText("按钮一");
   ((GridLayout) parent.getLayout()).numColumns++;
   Button bt2 = new Button(parent, SWT.NONE);
   bt2.setText("按钮二");
   ((GridLayout) parent.getLayout()).numColumns++;

}
}
从以上代码中可以总结出,创建一个首选项页面时需要注意以下问题:
◆ 每个首选项页面都要继承自PreferencePage类,而且必须实现createContents的抽象方法。
◆ 在createContents方法中可以创建页面的各种控件。
◆ 覆盖父类的performDefaults方法可以添加“恢复缺省值”按钮的操作,覆盖父类中的performOk方法,可以添加“应用”按钮的操作。

2. 创建首选项页面所对应的节点
节点所对应的类为PreferenceNode类。该类的构造方法有3个,如下:
◆ PreferenceNode(String id):id为标识该节点的字符,使用该构造函数需要使用setPage方法将一个节点对象与一个页面对象关联起来,如下:
SystemSettingPage system = new SystemSettingPage();
   PreferenceNode node = new PreferenceNode("System");
node.setPage(system);
◆ PreferenceNode(String id, IPreferencePage preferencePage):id为该节点的唯一标识符,PreferencePage为该节点对应的页面。
SystemSettingPage system = new SystemSettingPage();
   PreferenceNode node = new PreferenceNode("System", system);
◆ PreferenceNode(String id, String label, ImageDescriptor image, String className):id为该节点的唯一标识符,label为节点显示的名称,image为节点的图标,className为该节点所对应页面对象类的名称,注意是全称,包括所在的包名。还可以另一种方式获得类的全称:SystemSettingPage.class.getName(),也可以动态的获得该类的全称。
   PreferenceNode nodeOne = new PreferenceNode("System", "系统设置",
    ImageDescriptor.createFromFile(Constants.class, "tree_mode.gif"), // 节点的图标
     SystemSettingPage.class.getName()); // 所对应的页面类的全称

    一个PreferenceNode节点对象不仅保存了该节点所关联的首选项页面,还保存了该节点的其他信息,包括子节点等。

3. 显示首选项对话框
    PreferenceManager负责管理所有的节点。该类有两个构造方法:
◆ PreferenceManager():无参的构造函数。使用默认的“.”字符作为分隔符使用该构造方法:
PreferenceManager manager = new PreferenceManager();
◆ PreferenceManager(char separatorChar):separatorChar为路径分隔符。将一个节点添加到PreferenceManager对象使用以下两种方法:
    ◇ addToRoot(IPreferenceNode node):添加到根节点中。
   //创建一个PreferenceManager对象
   PreferenceManager manager = new PreferenceManager();
   //创建一个节点对象
   PreferenceNode nodeOne = new PreferenceNode("System", "系统设置", null, SystemSettingPage.class.getName());
   //将该节点添加到根节点中
   manager.addToRoot(nodeOne);
    ◇ addTo(String path, IPreferenceNode node):将一个节点添加到指定路径的节点上,其中path为指定的路径,node为要添加的节点。

最后,使用PreferenceDialog创建将树型导航栏和选项页面显示出来:
package www.swt.com.ch18;

import java.io.IOException;

public class PreferenceTest {

public static void main(String[] args) {
   Display display = new Display();
   //创建一个PreferenceManager对象
   PreferenceManager manager = new PreferenceManager();
   //创建一个节点对象
   PreferenceNode nodeOne = new PreferenceNode("System", "系统设置", null, SystemSettingPage.class.getName());
   //将该节点添加到根节点中
   manager.addToRoot(nodeOne);
   //创建两个节点对象
   PreferenceNode one = new PreferenceNode("one", "第一页", null, PageOne.class.getName());
   PreferenceNode two = new PreferenceNode("two", "第二页", null, PageTwo.class.getName());
   //将第一页节点附加到System路径下
   manager.addTo("System",one);
   //将第二页节点附加到System.one路径下
   manager.addTo("System.one",two);
   PreferenceNode editorOne = new PreferenceNode("one", "编辑字段", null, FieldEditorPage.class.getName());
   manager.addToRoot(editorOne);
   /*********************
   //第二页节点为第一页节点的子节点
   one.add( two );
   //第一页节点为系统设置节点的子节点
   nodeOne.add(one);
   **********************/
   //manager.addTo("System",one);
   //manager.addTo("System.one",two);
   //定义一个首选项对话框,并将manager作为参数传入
   PreferenceDialog dlg = new PreferenceDialog(null, manager);
   //注册页面切换事件
   dlg.addPageChangedListener( new IPageChangedListener(){
    //当页面切换时
    public void pageChanged(PageChangedEvent event) {
     //获得当前页面
     IPreferencePage page = (IPreferencePage)event.getSelectedPage();
     //输出当前页面的标题
     System.out.println(page.getTitle());
    }  
   });
   //创建保存选项设置值对象
   PreferenceStore preferenceStore = new PreferenceStore("F:\\myPreference.properties");
   try {
    //装载该文件中的设置值
    preferenceStore.load();
    //将该设置赋值给该对话框
    dlg.setPreferenceStore(preferenceStore);
    //打开对话框
    dlg.open();
    //最后关闭对话框后,保存当前设置
    preferenceStore.save();
   } catch (IOException e) {
    e.printStackTrace();
   }
   display.dispose();
}
}

18.4 创建树型的导航菜单
    要创建树型菜单,有两种方法,一种是在创建节点时就创建了该节点的子节点,这种情况下使用PreferenceNode对象的add方法为节点添加子节点。另一种方法是通过PreferenceManager对象的addTo方法为指定路径下添加节点。

两个选项页的代码如下:
package www.swt.com.ch18;

import org.eclipse.jface.preference.PreferencePage;

public class PageOne extends PreferencePage {
protected Control createContents(Composite parent) {
   return parent;
}

/*
* (非 Javadoc)
*
* @see org.eclipse.jface.preference.PreferencePage#contributeButtons(org.eclipse.swt.widgets.Composite)
*/
protected void contributeButtons(Composite parent) {
   // super.contributeButtons(parent);
   Button bt1 = new Button(parent, SWT.NONE);
   bt1.setText("按钮一");
   ((GridLayout) parent.getLayout()).numColumns++;
   Button bt2 = new Button(parent, SWT.NONE);
   bt2.setText("按钮二");
   ((GridLayout) parent.getLayout()).numColumns++;

}
}
另外一个选项页:
package www.swt.com.ch18;

import org.eclipse.jface.preference.PreferencePage;

public class PageTwo extends PreferencePage{

protected Control createContents(Composite parent) {
   return parent;
}
}

第一种方法创建树型菜单:
   // 创建一个PreferenceManager对象
   PreferenceManager manager = new PreferenceManager();
   // 创建一个节点对象
   PreferenceNode nodeOne = new PreferenceNode("System", "系统设置", null, SystemSettingPage.class.getName());
   // 将该节点添加到根节点
   manager.addToRoot(nodeOne);
   // 创建两个节点对象
   PreferenceNode one = new PreferenceNode("one", "第一页", null, PageOne.class.getName());
   PreferenceNode two = new PreferenceNode("two", "第二页", null, PageTwo.class.getName());
   // 第二页节点为第一页节点的子节点
   one.add(two);
   // 第一页节点为系统设置节点的子节点
   nodeOne.add(one);

第二种方法创建树型菜单:
   // 创建一个PreferenceManager对象
   PreferenceManager manager = new PreferenceManager();
   // 创建一个节点对象
   PreferenceNode nodeOne = new PreferenceNode("System", "系统设置", null, SystemSettingPage.class.getName());
   // 将该节点添加到根节点
   manager.addToRoot(nodeOne);
   // 创建两个节点对象
   PreferenceNode one = new PreferenceNode("one", "第一页", null, PageOne.class.getName());
   PreferenceNode two = new PreferenceNode("two", "第二页", null, PageTwo.class.getName());
   // 将第一页节点附加到System路径下
   manager.addTo("System", one);
   // 将第二页节点附加到System.one路径下
   manager.addTo("System.one", two);

18.5 首选项的选项设置
    对于首选项的设置,可以使用SWT基本的控件就可以实现,但为了方便创建设置的选项,JFace提供了常用的一些设置选项值的字段对象。

1. 字段编辑器概述
    字段编辑器类FieldEditor类是一个抽象类,创建字段编辑器要实现其方法的子类。使用字段编辑器的好处是,不必考虑对选项的保存,只需要创建使用的编辑器对象即可。

2. 使用字段编辑器基本步骤
package www.swt.com.ch18;

import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ColorFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.FontFieldEditor;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PathEditor;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.preference.ScaleFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;

public class FieldEditorPage extends FieldEditorPreferencePage {

public FieldEditorPage() {
   super(GRID);//页面的样式,还可以使用FLAT常量
}
//该方法为实现父类中的抽象方法,在该方法中添加所需的编辑器对象
protected void createFieldEditors() {

   //创建一个字符型编辑器对象
   StringFieldEditor userName = new StringFieldEditor(
     Constants.USER_NAME, //选项的key值
     "登录用户名:", //显示的标签名
     getFieldEditorParent());//该字段编辑器的父类面板
   //调用父类方法,将该方法添加到该页中
   addField(userName);
   // /*
   BooleanFieldEditor bfe = new BooleanFieldEditor("show","Boolean",getFieldEditorParent());
   addField(bfe);
   ColorFieldEditor cfe = new ColorFieldEditor("color","Color",getFieldEditorParent());
   addField(cfe);
   FontFieldEditor ffe = new FontFieldEditor("font","Font",getFieldEditorParent());
   addField(ffe);
   PathEditor pfe = new PathEditor("path","Path","请选择所选的路径",getFieldEditorParent());
   addField(pfe);
   RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(
     "group", //选项的key
     "RadioGroup",//分组框显示的文本
     2,//一行显示的单选按钮个数
     new String[][] { { "Radio one", "one"}, {"Radio two", "two"},{"Radio three", "three"} },//单选按钮的标签和值
     getFieldEditorParent(),//父类的面板
     true);//true表示使用分组面板,false将使用普通的面板
   addField(rgfe);
   ScaleFieldEditor sfe = new ScaleFieldEditor("scale","Scale",getFieldEditorParent(),0,100,5,10);
   addField(sfe);

   IntegerFieldEditor ife = new IntegerFieldEditor("int","Int",getFieldEditorParent());
   ife.setLabelText("这是int");
   addField(ife);
   DirectoryFieldEditor dfe = new DirectoryFieldEditor("dirctory","Directory",getFieldEditorParent());
   addField(dfe);
   FileFieldEditor filefe = new FileFieldEditor("file","File",getFieldEditorParent());
   addField(filefe);
   // */
}
}
显示效果:


使用字段编辑器应注意以下方面:
◆ 要使用字段编辑器,创建首选项页面时要继承自FieldEditorPreferencePage类,而不是继承自PreferencePage类,而且要实现createFieldEditors抽象方法。在该方法中创建各种编辑器对象。
◆ 创建编辑器对象时,至少要有3个参数,选项的key值、显示的标签名和该字段编辑器的父类面板。其中选项的key值,即为保存为文件中的key值,编辑对象会自动显示文件中所设置的值。
◆ 创建完编辑器对象后,调用父类的addField方法,将该编辑器对象添加到页面中。
◆ 使用编辑器时,不需要编写单击“恢复缺省值”和“应用”按钮的操作,这是因为FieldEditorPreferencePage是PreferencePage的子类,在该类中覆盖了PreferencePage类中的performOk方法,并且循环所有的字段编辑器对象,保存到存储设置的对象中。如下图所示,对界面上的内容修改后,点击“确定”关闭,重新打开程序时,显示的是上次设定的内容。如果点击“取消”关闭窗口,则重新打开程序时,上次修改的内容不会生效。


当输入的值不合法时,提示如下:


18.6 自定义首选项页面
    每个首选项页面都有一个“恢复缺省值”按钮和“应用”按钮。若想自定义首选项页面上的按钮,需要覆盖父类的contributeButtons方法。

参考本文中的SystemSettingPage。

在创建完一个按钮后,要调用((GridLayout) parent.getLayout()).numColumns++;方法,将父类面板中的列数加1。

18.7 首选项的事件处理
    当切换首选项页面时会触发PageChangedEvent事件。
   PreferenceDialog dlg = new PreferenceDialog(null, manager);
   //注册页面切换事件
   dlg.addPageChangedListener( new IPageChangedListener(){
    //当页面切换时
    public void pageChanged(PageChangedEvent event) {
     //获得当前页面
     IPreferencePage page = (IPreferencePage)event.getSelectedPage();
     //输出当前页面的标题
     System.out.println(page.getTitle());
    }
   });

你可能感兴趣的:(eclipse)