Eclipse RCP: Memanggil perspectiveChanged mengarah ke stackoverflow

Saya memiliki aplikasi Eclipse RCP yang saya migrasikan dari Eclipse 3.0 ke 4.4, yang sejauh ini berfungsi dengan baik. Karena migrasi, beberapa entri menu (misalnya file terbuka umum) ditambahkan, yang ingin saya hapus. Sejauh ini berhasil, karena saya memanggil hideActionset(...) dalam metode perspectiveActivated() saya.

Entri menu hilang. Namun ketika saya mengatur ulang perspektif dan kemudian mengubah perspektif, entri menu muncul lagi. Saya mencoba memperbaikinya dengan memanggil hideActionSet(...) dalam metode perspectiveChanged(...) saya, tetapi metode tersebut sering dipanggil sehingga saya mendapatkan 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");
        }
    }

Berikut cuplikan salah satu dari dua file log yang sedang dibuat:

!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 sumber


Jawaban (1)


Jika Anda melihat jejak tumpukan, Anda dapat melihat dengan jelas bahwa saat Anda memanggil WorkbenchPage.hideActionSet, peristiwa perubahan perspektif baru diaktifkan dan perspectiveChanged dipanggil lagi saat Anda masih dalam panggilan perspectiveChanged pertama.

Salah satu cara untuk menghentikannya adalah dengan memberi tanda pada metode perspectiveChanged Anda untuk mendeteksi bahwa Anda sedang menghadapi perubahan.

Sesuatu seperti:

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