Eclipse RCP: การเรียกเปอร์สเปคทีฟที่เปลี่ยนแปลงนำไปสู่สแต็กโอเวอร์โฟลว์

ฉันมีแอปพลิเคชัน Eclipse RCP ซึ่งฉันกำลังย้ายจาก Eclipse 3.0 เป็น 4.4 ซึ่งทำงานได้ดีจนถึงตอนนี้ เนื่องจากการย้ายข้อมูล จึงมีการเพิ่มรายการเมนูบางรายการ (เช่น ไฟล์เปิดทั่วไป) ซึ่งฉันต้องการลบออก จนถึงขณะนี้วิธีนี้ใช้ได้ เพราะฉันกำลังเรียก hideActionset(...) ในวิธีการ perspectiveActivated() ของฉัน

รายการเมนูหายไป แต่เมื่อฉันรีเซ็ตเปอร์สเปคทีฟแล้วเปลี่ยนเปอร์สเปคทีฟ รายการเมนูจะปรากฏขึ้นอีกครั้ง ฉันพยายามแก้ไขปัญหานี้ด้วยการเรียก hideActionSet(...) ในวิธีการ perspectiveChanged(...) ของฉัน แต่มันถูกเรียกบ่อยมากจนฉันได้รับ stackoverflow

    /**
     * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
     */
    public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) 
    {
        if( perspective.getId().equals(m_PerspektivenID) || m_PerspektivenID.equals(STANDARDAKTION))
        {
            setEnabled( true );
        }
        else
        {
            setEnabled( false );
        }

        if(page != null)
        {
            page.hideActionSet("org.eclipse.ui.actionSet.keyBindings");
            page.hideActionSet("org.eclipse.ui.actionSet.openFiles");
        }
    }

    /**
     * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
     */
    public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) 
    {
        if(page != null)
        {
            page.hideActionSet("org.eclipse.ui.actionSet.keyBindings");
            page.hideActionSet("org.eclipse.ui.actionSet.openFiles");
        }
    }

นี่คือไฟล์บันทึกหนึ่งในสองไฟล์ที่ถูกสร้างขึ้น:

!ENTRY org.eclipse.equinox.event 4 0 2016-01-12 14:37:00.768
!MESSAGE Exception while dispatching event org.osgi.service.event.Event [topic=org/eclipse/e4/ui/model/ui/UIElement/widget/SET] to handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@faec277
!STACK 0
java.lang.StackOverflowError
    at java.util.HashMap.hash(HashMap.java:338)
    at java.util.HashMap.containsKey(HashMap.java:595)
    at java.util.Collections$SynchronizedMap.containsKey(Collections.java:2578)
    at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:347)
    at org.eclipse.e4.ui.internal.services.ContextContextService.setEventCaching(ContextContextService.java:129)
    at org.eclipse.e4.ui.internal.services.ContextContextService.deferUpdates(ContextContextService.java:86)
    at org.eclipse.ui.internal.contexts.ContextService.deferUpdates(ContextService.java:92)
    at org.eclipse.ui.internal.Perspective.removeActionSet(Perspective.java:362)
    at org.eclipse.ui.internal.WorkbenchPage.hideActionSet(WorkbenchPage.java:2593)
    at packagenane.classname.perspectiveChanged(BaseAction.java:146)
    at org.eclipse.ui.internal.PerspectiveListenerList$4.run(PerspectiveListenerList.java:134)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.runtime.Platform.run(Platform.java:867)
    at org.eclipse.ui.internal.PerspectiveListenerList.fireEvent(PerspectiveListenerList.java:58)
    at org.eclipse.ui.internal.PerspectiveListenerList.firePerspectiveChanged(PerspectiveListenerList.java:131)
    at org.eclipse.ui.internal.WorkbenchWindow.firePerspectiveChanged(WorkbenchWindow.java:1721)
    at org.eclipse.ui.internal.WorkbenchPage.hideActionSet(WorkbenchPage.java:2596)
    at packagenane.classname.perspectiveChanged(BaseAction.java:146)
    at org.eclipse.ui.internal.PerspectiveListenerList$4.run(PerspectiveListenerList.java:134)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.runtime.Platform.run(Platform.java:867)
    at org.eclipse.ui.internal.PerspectiveListenerList.fireEvent(PerspectiveListenerList.java:58)
    at org.eclipse.ui.internal.PerspectiveListenerList.firePerspectiveChanged(PerspectiveListenerList.java:131)
    at org.eclipse.ui.internal.WorkbenchWindow.firePerspectiveChanged(WorkbenchWindow.java:1721)
    at org.eclipse.ui.internal.WorkbenchPage.hideActionSet(WorkbenchPage.java:2596)
    at packagenane.classname.perspectiveChanged(BaseAction.java:146)
    at org.eclipse.ui.internal.PerspectiveListenerList$4.run(PerspectiveListenerList.java:134)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.runtime.Platform.run(Platform.java:867)
    at org.eclipse.ui.internal.PerspectiveListenerList.fireEvent(PerspectiveListenerList.java:58)
    at org.eclipse.ui.internal.PerspectiveListenerList.firePerspectiveChanged(PerspectiveListenerList.java:131)
    at org.eclipse.ui.internal.WorkbenchWindow.firePerspectiveChanged(WorkbenchWindow.java:1721)
    at org.eclipse.ui.internal.WorkbenchPage.hideActionSet(WorkbenchPage.java:2596)
    at packagenane.classname.perspectiveChanged(BaseAction.java:146)
    at org.eclipse.ui.internal.PerspectiveListenerList$4.run(PerspectiveListenerList.java:134)

person Pascal Petruch    schedule 12.01.2016    source แหล่งที่มา


คำตอบ (1)


หากคุณดูที่การติดตามสแต็ก คุณจะเห็นได้ชัดเจนว่าเมื่อคุณเรียก WorkbenchPage.hideActionSet เหตุการณ์ที่เปลี่ยนมุมมองใหม่กำลังเกิดขึ้น และ perspectiveChanged จะถูกเรียกอีกครั้งในขณะที่คุณยังอยู่ในการเรียก perspectiveChanged ครั้งแรก

วิธีหนึ่งที่จะหยุดสิ่งนี้ได้คือการมีแฟล็กในเมธอด perspectiveChanged ของคุณเพื่อตรวจสอบว่าคุณกำลังเผชิญกับการเปลี่ยนแปลงอยู่แล้ว

สิ่งที่ต้องการ:

private boolean changeActive;

public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) 
{
  if (changeActive) {   // Don't do anything if already handling change
    return;
  }

  changeActive = true;

  if (page != null)
    {
        page.hideActionSet("org.eclipse.ui.actionSet.keyBindings");
        page.hideActionSet("org.eclipse.ui.actionSet.openFiles");
    }

  changeActive = false;
}
person greg-449    schedule 12.01.2016