与问题“Custom message when closing a part in Eclipse RCP 4”相关 我还有一个带有多个编辑器部分的Eclipse RCP 4应用程序(实现MDirtyable和@Persist)。
部件可以关闭。当用户关闭零件时,应该有一个自定义弹出窗口,询问用户是否确实要保存零件。
此外,当用户关闭应用程序时,弹出窗口应提示用户关闭/保存脏部分。 基本上它旨在删除默认的关闭eclipse e4对话框。
我已经在生命周期类中实现了自定义ISaveHandler和IWindowCloseHandler订阅应用程序启动完成事件UIEvents.UILifeCycle.APP_STARTUP_COMPLETE。
自定义IWindowCloseHandler工作正常(就对话而言),但自定义ISaveHandler不是。
ISaveHandler.save在定义如下时返回stackoverflow错误:
@Override
public boolean save(MPart dirtyPart, boolean confirm) {
EPartService partService = dirtyPart.getContext().get(EPartService.class);
//Try to close the part and save the document to disc by
//calling the @Persist method
return partService.savePart(dirtyPart, confirm);
}
我附上了完整的LifeCycleManager类:
public class LifeCycleManager {
@Inject IEventBroker eventBroker;
@ProcessAdditions
public void processAdditions(MApplication application, EModelService modelService){
MWindow window =(MWindow)modelService.find("application-trimmedwindow", application);
eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE,
new AppStartupCompleteEventHandler(window, modelService, application));
}
public class AppStartupCompleteEventHandler implements EventHandler {
private MWindow theWindow;
private MApplication app;
private ISaveHandler saveHandler;
AppStartupCompleteEventHandler(MWindow window, EModelService modelService, MApplication application){
theWindow = window;
app = application;
}
@Override
public void handleEvent(Event event) {
theWindow.getContext().set(ISaveHandler.class, new ISaveHandler() {
@Override
public boolean save(MPart dirtyPart, boolean confirm) {
System.out.println("PARTE PARA SALVAR..." + dirtyPart.getLabel());
EPartService partService = dirtyPart.getContext().get(EPartService.class);
//partService.hidePart(dirtyPart,true);
return partService.savePart(dirtyPart, confirm);
//return true;
}
@Override
public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm) {
return false;
}
@Override
public Save promptToSave(MPart dirtyPart) {
return promptToSaveDialog(dirtyPart);
}
@Override
public Save[] promptToSave(Collection<MPart> dirtyParts) {
return null;
}
});
saveHandler = (ISaveHandler)theWindow.getContext().get(ISaveHandler.class);
theWindow.getContext().set(IWindowCloseHandler.class, new IWindowCloseHandler() {
@Override
public boolean close(MWindow window) {
List<MHandler> listHandlers = window.getHandlers();
System.out.println(listHandlers.size());
Shell shell = (Shell) window.getWidget();
if (MessageDialog.openConfirm(shell, "Close Nastran Editor", "Do you really want to close the entire application?")) {
Collection<EPartService> allPartServices = getAllPartServices(app);
if (containsDirtyParts(allPartServices)) {
return iterateOverDirtyParts( allPartServices);
}
else {
return true;
}
}
return false;
}});
}
private Collection<EPartService> getAllPartServices(MApplication application) {
List<EPartService> partServices = new ArrayList<EPartService>();
EModelService modelService = application.getContext().get(EModelService.class);
List<MWindow> elements = modelService.findElements(application, MWindow.class, EModelService.IN_ACTIVE_PERSPECTIVE,
new ElementMatcher(null, MWindow.class, (List<String>) null));
for (MWindow w : elements) {
if (w.isVisible() && w.isToBeRendered()) {
EPartService partService = w.getContext().get(EPartService.class);
if (partService != null) {
partServices.add(partService);
}
}
}
return partServices;
}
private boolean containsDirtyParts(Collection<EPartService> partServices) {
for (EPartService partService : partServices) {
if (!partService.getDirtyParts().isEmpty()) return true;
}
return false;
}
private boolean iterateOverDirtyParts(Collection<EPartService> allPartServices) {
for (EPartService partService : allPartServices) {
Collection<MPart> dirtyParts = partService.getDirtyParts();
for(MPart dirtyPart : dirtyParts) {
switch(saveHandler.promptToSave(dirtyPart)) {
case NO: break;
case YES:
saveHandler.save(dirtyPart, false);
break;
case CANCEL:return false;
}
}
}
return true;
}
private Save promptToSaveDialog(MPart dirtyPart) {
MessageDialog dialog = new MessageDialog( (Shell)theWindow.getWidget(), "Save file", null,
"'"+dirtyPart.getLabel()+"' has been modified. Save changes?", MessageDialog.QUESTION, new String[] { "YES", "NO", "CANCEL" }, 0);
switch (dialog.open()){
case 0: return Save.YES;
case 1: return Save.NO;
case 2: return Save.CANCEL;
default:return Save.CANCEL;
}
}
}
}///END of LifeCycleManager
答案 0 :(得分:1)
从save
ISaveHandler
方法调用EPartService
savePart
方法,因此您无法再次致电savePart
。
相反,您应该只调用部件的@Persist
方法。如下所示:
@Override
public boolean save(final MPart dirtyPart, final boolean confirm)
{
if (confirm)
{
switch (promptToSave(dirtyPart))
{
default:
case NO:
return true;
case CANCEL:
return false;
case YES:
break;
}
}
try
{
ContextInjectionFactory.invoke(dirtyPart.getObject(), Persist.class, dirtyPart.getContext());
}
catch (final InjectionException ex)
{
// TODO ignore or log error
}
return true;
}