最大的网站源码资源下载站,
以前我有一个微型的便携式电子地址薄。我一直认为它很不错,直到有一天它停止运行了。销售该产品的人员无法找回我的联系地址名册,却提议更换一台。这时候我才知道数据的重要性。这个闪亮的小发明与存储在它里面的数据相比根本就不值一提。public class invokatrondocument
extends properties
{
public static final string package = "package";
public static final string superclass = "superclass";
public static final string interfaces = "interfaces";
}
string package =document.getproperty(invokatrondocument.package);
它只有一个页面,右上角没有图片。我们想输入更多的信息,并提供一个很好的图片。换句话说,我们希望定制这个向导。
我们来分析一下这个向导。请打开invokatronwizard.java文件。请注意这个类是如何扩展wizard并实现inewwizard接口的。你应该理解它里面的很多方法。为了定制向导,我们简单地调用或重载其中的某些方法。下面是一些重要的方法:
生命周期方法
我们应该重载这些方法,把初始化和析构(destruction)代码插入向导中:
· constructor(构造函数):向导实例化的时候、在eclipse给它传递信息之前调用。向导的一般初始化实现。通常你希望调用"美化方法"(后面有描述)并设置对话框的默认值。
· init(iworkbench workbench, istructuredselection editorselection): eclipse调用它为向导提供工作台的信息。请重载它,保存iworkbench和对象的句柄供以后使用。如果它是一个编辑器向导而不是新向导,我们最好把当前的编辑器选项作为第二个参数。
· dispose():eclipse调用它执行清理工作。重载它来清除向导使用的资源。
· finalize():清除代码,可能使用dispose()代替。
美化方法
这些方法都是用于装饰向导窗体的。
· setwindowtitle(string title):设置窗体的标题行字符串。
· setdefaultpageimagedescriptor(imagedescriptor image):用于提供显示在向导的所有页面右上方的图片。
· settitlebarcolor(rgb color):指定标题栏用什么颜色。
按钮方法
这些方法控制着向导按钮的实用性和行为。
· boolean canfinish():重载它用于指定finish(完成)按钮是否激活(根据向导的状态)。
· boolean performfinish():重载它来实现向导的根本的业务逻辑。如果向导没有完成(错误的条件),就返回false。
· boolean performcancel():重载它,在用户点击cancel(取消)按钮的时候进行清除操作。如果向导不能终止,则返回false。
· boolean ishelpavailable():重载它用于指定help(帮助)按钮是否可视。
· boolean needspreviousandnextbuttons():重载它来指定previous(前一步)和next(后一步)按钮是否可视。
· boolean needsprogressmonitor():重载它来指定进度条部件是否可视。当点击finish按钮调用performfinish()方法的时候,它就会出现。
页面方法
这些方法控制着页面的外观。
· addpages():向导显示的时候调用。重载它给向导插入新页面。
· createpagecontrols(composite pagecontainer):eclipse调用它来实例化所有的向导页面(用前面的addpages()方法已经添加的页面)。重载它给向导添加持续可视的窗体小部件(除页面之外的部件)。
· iwizardpage getstartingpage():重载它来检测哪个页面是向导的第一个页面。
· iwizardpage getnextpage(iwizardpage nextpage):在默认情况下,点击next按钮将进入addpages()所提供的数组中的下一个页面。你可能希望根据用户选择进入不同的页面。重载它来计算后一个页面。
· iwizardpage getpreviouspage(iwizardpage previouspage):与getnextpage()类似,用于计算前一个页面。
· int getpagecount():检索addpages()添加的页面的数量。在典型情况下,你不必重载它,除非你希望显示页面的数量和形式。
其它有用的方法
这些都是有用的辅助方法:
· setdialogsettings(idialogsettings settings):你可以载入对话框的状态,并通过在init()中调用这个方法来设置这些值。在典型情况下,这些设置可以作为向导字段的默认值。请查看dialogsettings类了解更详细的信息。
· idialogsettings getdialogsettings():当我们需要数据的时候,就调用这个方法来检索它。在performfinish()的对话框的末尾,你再次可以把数据保存到文件中。
· iwizardcontainer getcontainer():对于检索shell、运行的后台线程、刷新窗口等非常有用。
向导页面方法
你已经看到了,向导是由一个或多个页面组成的。这些页面扩展了wizardpage类,并实现了iwizardpage接口。为了定制单独的页面,你必须了解很多方法。下面是一些重要的方法:
· constructor:用于实例化页面。
· dispose():重载它用于实现清除代码。
· createcontrol(composite parent):重载它来给页面添加控件。
· iwizard getwizard():用于获取父向导对象。对于调用getdialogsettings()是有用处的。
· settitle(string title):调用它来设置显示在向导标题区域中的字符串。
· setdescription(string description):调用它来提供标题下面显示的文本内容。
· setimagedescriptor(imagedescriptor image):调用它来提供页面右上方出现的图片(用于代替默认的图片)。
· setmessage(string message):调用它来显示描述字符串下方的消息文本。这些文本是用于警告或提示用户的。
· seterrormessage(string error):调用它来高亮度显示描述字符串下方的消息文本。它一般意味着向导不能继续,除非错误被修正。
· setpagecomplete(boolean complete):如果为true,next按钮就可视。
· performhelp():重载它来提供内容敏感的帮助信息。当点击help按钮的时候向导会调用它。
编写向导的代码
有了这些方法之后,我们就能够开发出具有极大的灵活性的向导了。我们现在修改以前建立的invokatron向导,给它添加一个页面来请求用户输入初始的文档数据。我们还给向导添加了一个图片。新代码是粗体的:
public class invokatronwizard extends wizard
implements inewwizard {
private invokatronwizardpage page;
private invokatronwizardpage2 page2;
private iselection selection;
public invokatronwizard() {
super();
setneedsprogressmonitor(true);
imagedescriptor image =abstractuiplugin.imagedescriptorfromplugin("invokatron", "icons/invokatronicon32.gif");
setdefaultpageimagedescriptor(image);
}
public void init(iworkbench workbench,istructuredselection selection) {
this.selection = selection;
}
public void addpages() {
page=new invokatronwizardpage(selection);
addpage(page);
page2 = new invokatronwizardpage2(selection);
addpage(page2);
}
public boolean performfinish() {
//首先把所有的页面数据保存在变量中
final string containername = page.getcontainername();
final string filename =page.getfilename();
final invokatrondocument properties = new invokatrondocument();
properties.setproperty(invokatrondocument.package,page2.getpackage());
properties.setproperty(invokatrondocument.superclass,page2.getsuperclass());
properties.setproperty(invokatrondocument.interfaces,page2.getinterfaces());
//现在调用完成(finish)方法
irunnablewithprogress op =new irunnablewithprogress() {
public void run(iprogressmonitor monitor)
throws invocationtargetexception {
try {
dofinish(containername, filename,properties,monitor);
} catch (coreexception e) {
throw new invocationtargetexception(e);
} finally {
monitor.done();
}
}
};
try {
getcontainer().run(true, false, op);
} catch (interruptedexception e) {
return false;
} catch (invocationtargetexception e) {
throwable realexception =e.gettargetexception();
messagedialog.openerror(getshell(),"error",realexception.getmessage());
return false;
}
return true;
}
private void dofinish(string containername,string filename, properties properties,
iprogressmonitor monitor)
throws coreexception {
// 建立一个示例文件
monitor.begintask("creating " + filename, 2);
iworkspaceroot root = resourcesplugin.getworkspace().getroot();
iresource resource = root.findmember(new path(containername));
if (!resource.exists() || !(resource instanceof icontainer)) {
throwcoreexception("container /"" + containername + "/" does not exist.");
}
icontainer container =(icontainer)resource;
final ifile ifile = container.getfile(new path(filename));
final file file =ifile.getlocation().tofile();
try {
outputstream os = new fileoutputstream(file, false);
properties.store(os, null);
os.close();
} catch (ioexception e) {
e.printstacktrace();
throwcoreexception("error writing to file " + file.tostring());
}
//确保项目已经刷新了,该文件在eclipse api 之外建立
container.refreshlocal(iresource.depth_infinite, monitor);
monitor.worked(1);
monitor.settaskname("opening file for editing...");
getshell().getdisplay().asyncexec(new runnable() {
public void run() {
iworkbenchpage page =platformui.getworkbench().getactiveworkbenchwindow().getactivepage();
try {
ide.openeditor(page,ifile,true);
} catch (partinitexception e) {
}
}
});
monitor.worked(1);
}
private void throwcoreexception(string message) throws coreexception {
istatus status =new status(istatus.error,"invokatron",istatus.ok,message,null);
throw new coreexception(status);
}
}
编写新的向导页面的代码
下一步,我们编写invokatronwizardpage2。它的整个类都是全新的:
public class invokatronwizardpage2 extends wizardpage {
private text packagetext;
private text superclasstext;
private text interfacestext;
private iselection selection;
public invokatronwizardpage2(iselection selection) {
super("wizardpage2");
settitle("invokatron wizard");
setdescription("this wizard creates a new"+" file with *.invokatron extension.");
this.selection = selection;
}
private void updatestatus(string message) {
seterrormessage(message);
setpagecomplete(message == null);
}
public string getpackage() {
return packagetext.gettext();
}
public string getsuperclass() {
return superclasstext.gettext();
}
public string getinterfaces() {
return interfacestext.gettext();
}
public void createcontrol(composite parent) {
composite controls =new composite(parent, swt.null);
gridlayout layout = new gridlayout();
controls.setlayout(layout);
layout.numcolumns = 3;
layout.verticalspacing = 9;
label label =new label(controls, swt.null);
label.settext("&package:");
packagetext = new text(controls,swt.border | swt.single);
griddata gd = new griddata(griddata.fill_horizontal);
packagetext.setlayoutdata(gd);
packagetext.addmodifylistener(
new modifylistener() {
public void modifytext(modifyevent e) {
dialogchanged();
}
});
label = new label(controls, swt.null);
label.settext("blank = default package");
label = new label(controls, swt.null);
label.settext("&superclass:");
superclasstext = new text(controls,swt.border | swt.single);
gd = new griddata(griddata.fill_horizontal);
superclasstext.setlayoutdata(gd);
superclasstext.addmodifylistener(new modifylistener() {
public void modifytext(modifyevent e) {
dialogchanged();
}
});
label = new label(controls, swt.null);
label.settext("blank = object");
label = new label(controls, swt.null);
label.settext("&interfaces:");
interfacestext = new text(controls,swt.border | swt.single);
gd = new griddata(griddata.fill_horizontal);
interfacestext.setlayoutdata(gd);
interfacestext.addmodifylistener(
new modifylistener() {
public void modifytext(modifyevent e) {
dialogchanged();
}
});
label = new label(controls, swt.null);
label.settext("separated by ','");
dialogchanged();
setcontrol(controls);
}
private void dialogchanged() {
string apackage = getpackage();
string asuperclass = getsuperclass();
string interfaces = getinterfaces();
string status = new packagevalidator().isvalid(apackage);
if(status != null) {updatestatus(status);
return;
}
status = new superclassvalidator().isvalid(asuperclass);
if(status != null) {updatestatus(status);
return;
}
status = new interfacesvalidator().isvalid(interfaces);
if(status != null) {updatestatus(status);
return;
}
updatestatus(null);
}
}
验证类
验证可以在插件的用户输入数据的任何部分中进行。因此,把验证代码放入可重复使用的类中是有意义的,这样就不用把它复制到多个位置。下面是一个验证类的例子。
public class interfacesvalidator implements icelleditorvalidator
{
public string isvalid(object value)
{
if( !( value instanceof string) )
return null;
string interfaces = ((string)value).trim();
if( interfaces.equals(""))
return null;
string[] interfacearray = interfaces.split(",");
for (int i = 0; i < interfacearray.length; i++)
{
istatus status = javaconventions.validatejavatypename(interfacearray[i]);
if (status.getcode() != istatus.ok)
return "validation of interface " + interfacearray[i] + ": " + status.getmessage();
}
return null;
}
}
新闻热点
疑难解答