LightToolWindowManager — use Disposable, use projectOpened via message bus to ensure proper order of listeners registration (e.g. ToolWindowManagerImpl uses message bus, so, clients should use message bus also)

This commit is contained in:
Vladimir Krivosheev
2017-05-09 18:31:15 +02:00
parent 72daf670f4
commit 9354592142
6 changed files with 60 additions and 75 deletions
@@ -16,16 +16,18 @@
package com.intellij.designer;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
@@ -43,14 +45,13 @@ import java.util.function.Consumer;
/**
* @author Alexander Lobas
*/
public abstract class LightToolWindowManager implements ProjectComponent {
public abstract class LightToolWindowManager implements Disposable {
public static final String EDITOR_MODE = "UI_DESIGNER_EDITOR_MODE.";
private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null);
private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null, this);
protected final Project myProject;
protected final FileEditorManager myFileEditorManager;
protected volatile ToolWindow myToolWindow;
private volatile boolean myToolWindowDisposed;
private final PropertiesComponent myPropertiesComponent;
public final String myEditorModeKey;
@@ -58,38 +59,26 @@ public abstract class LightToolWindowManager implements ProjectComponent {
private ToggleEditorModeAction myRightEditorModeAction;
private MessageBusConnection myConnection;
private final FileEditorManagerListener myListener = new FileEditorManagerListener() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
bindToDesigner(getActiveDesigner());
}
@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
ApplicationManager.getApplication().invokeLater(() -> bindToDesigner(getActiveDesigner()));
}
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
bindToDesigner(getDesigner(event.getNewEditor()));
}
};
//////////////////////////////////////////////////////////////////////////////////////////
//
// ToolWindow
//
//////////////////////////////////////////////////////////////////////////////////////////
protected LightToolWindowManager(Project project, FileEditorManager fileEditorManager) {
myProject = project;
myFileEditorManager = fileEditorManager;
myPropertiesComponent = PropertiesComponent.getInstance(myProject);
myEditorModeKey = EDITOR_MODE + getComponentName() + ".STATE";
myConnection = myProject.getMessageBus().connect();
myConnection.subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
@Override
public void projectOpened(Project project) {
if (myProject == project) {
LightToolWindowManager.this.projectOpened();
}
}
});
}
@Override
public void projectOpened() {
protected void projectOpened() {
initToolWindow();
StartupManager.getInstance(myProject).runWhenProjectIsInitialized((DumbAwareRunnable)() -> {
@@ -100,18 +89,23 @@ public abstract class LightToolWindowManager implements ProjectComponent {
});
}
@Override
public void projectClosed() {
if (!myToolWindowDisposed) {
disposeComponent();
myToolWindowDisposed = true;
myToolWindow = null;
}
}
private void initListeners() {
myConnection = myProject.getMessageBus().connect();
myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, myListener);
myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerListener() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
bindToDesigner(getActiveDesigner());
}
@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
ApplicationManager.getApplication().invokeLater(() -> bindToDesigner(getActiveDesigner()));
}
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
bindToDesigner(getDesigner(event.getNewEditor()));
}
});
}
private void removeListeners() {
@@ -139,9 +133,6 @@ public abstract class LightToolWindowManager implements ProjectComponent {
myWindowQueue.queue(new Update("update") {
@Override
public void run() {
if (myToolWindowDisposed) {
return;
}
if (myToolWindow == null) {
if (designer == null) {
return;
@@ -292,4 +283,14 @@ public abstract class LightToolWindowManager implements ProjectComponent {
final ToolWindow getToolWindow() {
return myToolWindow;
}
@Override
public void dispose() {
myToolWindow = null;
}
@NotNull
protected String getComponentName() {
return getClass().getName();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.ToolWindowEx;
@@ -68,6 +69,7 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager {
protected void initToolWindow() {
if (myToolWindowContent == null) {
myToolWindowContent = new DesignerToolWindow(myProject, true);
Disposer.register(this, () -> myToolWindowContent.dispose());
}
myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(DesignerBundle.message("designer.toolwindow.name"),
@@ -111,13 +113,6 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager {
}
}
@Override
public void disposeComponent() {
if (myToolWindowContent != null) {
myToolWindowContent.dispose();
}
}
@NotNull
@Override
public String getComponentName() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
@@ -68,6 +69,7 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
protected void initToolWindow() {
if (myToolWindowPanel == null) {
myToolWindowPanel = new PalettePanel();
Disposer.register(this, () -> myToolWindowPanel.dispose());
}
myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow("Palette\t", false, getAnchor(), myProject, true);
@@ -102,13 +104,6 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
}
}
@Override
public void disposeComponent() {
if (myToolWindowPanel != null) {
myToolWindowPanel.dispose();
}
}
@NotNull
@Override
public String getComponentName() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
@@ -40,6 +41,9 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
public PaletteToolWindowManager(Project project, FileEditorManager fileEditorManager) {
super(project, fileEditorManager);
myToolWindowPanel = ApplicationManager.getApplication().isHeadlessEnvironment() ? null : new PaletteWindow(project);
if (myToolWindowPanel != null) {
Disposer.register(this, () -> myToolWindowPanel.dispose());
}
}
public static PaletteWindow getInstance(GuiEditor designer) {
@@ -103,13 +107,6 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
null);
}
@Override
public void disposeComponent() {
if (myToolWindowPanel != null) {
myToolWindowPanel.dispose();
}
}
@NotNull
@Override
public String getComponentName() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ public abstract class AbstractToolWindowManager extends LightToolWindowManager {
}
@Override
public void projectOpened() {
protected void projectOpened() {
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
super.projectOpened();
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
@@ -42,6 +43,9 @@ public class DesignerToolWindowManager extends AbstractToolWindowManager impleme
public DesignerToolWindowManager(Project project, FileEditorManager fileEditorManager) {
super(project, fileEditorManager);
myToolWindowPanel = ApplicationManager.getApplication().isHeadlessEnvironment() ? null : new DesignerToolWindow(project);
if (myToolWindowPanel != null) {
Disposer.register(this, () -> myToolWindowPanel.dispose());
}
}
public static DesignerToolWindow getInstance(GuiEditor designer) {
@@ -117,13 +121,6 @@ public class DesignerToolWindowManager extends AbstractToolWindowManager impleme
null);
}
@Override
public void dispose() {
if (myToolWindowPanel != null) {
myToolWindowPanel.dispose();
}
}
@NotNull
@Override
public String getComponentName() {