From 373206dbd8d06ff5a3d35dd9a8f19e5396afcdef Mon Sep 17 00:00:00 2001 From: JohnHake Date: Sun, 1 Mar 2020 17:37:12 -0800 Subject: [PATCH] Still leaks - can't find Project with focus when 4th project closed. --- .../maxOpenPrj/ProjectCountingService.java | 34 ++++++---- .../maxOpenPrj/ProjectOpenCloseListener.java | 3 +- .../intellij/sdk/utils/SdkBalloonHelper.java | 67 +++++++++++++++---- 3 files changed, 78 insertions(+), 26 deletions(-) diff --git a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectCountingService.java b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectCountingService.java index 61a83f084..936ab146b 100644 --- a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectCountingService.java +++ b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectCountingService.java @@ -8,26 +8,36 @@ package org.intellij.sdk.maxOpenPrj; */ public class ProjectCountingService { // Sets the maximum allowed number of opened projects. - private final int MAX_OPEN_PRJ_LIMIT = 3; + private final static int MAX_OPEN_PRJ_LIMIT = 3; // The count of open projects must always be >= 0 - private int openProjectCount = 0; + private int myOpenProjectCount = 0; - public void incrProjectCount() { - if (openProjectCount < 0) { - openProjectCount = 0; - } - openProjectCount++; + public void incrProjectCount() { + myOpenProjectCount = verifyProjectCount(myOpenProjectCount); + myOpenProjectCount++; } public void decrProjectCount() { - openProjectCount--; - if (openProjectCount < 0) { - openProjectCount = 0; - } + myOpenProjectCount--; + myOpenProjectCount = verifyProjectCount(myOpenProjectCount); } public boolean projectLimitExceeded() { - return openProjectCount > MAX_OPEN_PRJ_LIMIT; + return myOpenProjectCount > MAX_OPEN_PRJ_LIMIT; + } + + public int getProjectCount() { + return myOpenProjectCount; + } + + /** + * Anti-bugging to ensure the count of open projects never goes below zero. + * @param openProjectCount The count of currently open projects + * @return 0 if openProjectCount<0 + * openProjectCount otherwise + */ + private int verifyProjectCount(int openProjectCount) { + return openProjectCount<0 ? 0 : openProjectCount; } } diff --git a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectOpenCloseListener.java b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectOpenCloseListener.java index 5e3dad8b5..27264c71b 100644 --- a/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectOpenCloseListener.java +++ b/max_opened_projects/src/main/java/org/intellij/sdk/maxOpenPrj/ProjectOpenCloseListener.java @@ -6,6 +6,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.ui.Messages; import org.intellij.sdk.utils.SdkBalloonHelper; import org.jetbrains.annotations.NotNull; @@ -15,7 +16,7 @@ import org.jetbrains.annotations.NotNull; * Depends on org.intellij.sdk.utils.SdkBalloonHelper */ public class ProjectOpenCloseListener implements ProjectManagerListener { - private static final String MAX_OPEN_PROJ_DISCLAIM = "This is an IntelliJ Platform SDK demo.

"; + private static final String MAX_OPEN_PROJ_DISCLAIM = "\nThis is an IntelliJ Platform SDK demo message.\n\n"; /** * Invoked on project open. diff --git a/max_opened_projects/src/main/java/org/intellij/sdk/utils/SdkBalloonHelper.java b/max_opened_projects/src/main/java/org/intellij/sdk/utils/SdkBalloonHelper.java index 1fdb423c0..407dd281a 100644 --- a/max_opened_projects/src/main/java/org/intellij/sdk/utils/SdkBalloonHelper.java +++ b/max_opened_projects/src/main/java/org/intellij/sdk/utils/SdkBalloonHelper.java @@ -7,12 +7,17 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.WindowManagerImpl; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; /** * This is just a utility class to help communicate the state of this plugin using Popups @@ -27,23 +32,17 @@ public class SdkBalloonHelper { /** * This method constructs a Balloon-type popup and displays it in the middle of a Project window. - * Adds the Balloon to the Project's Disposer * * @param project The Project to host the Balloon. * @param title A short description of what the Balloon conveys - * @param message Detailed information + * @param message Detailed information to display in HTML format */ public void showBalloon(@Nullable Project project, @NotNull String title, @NotNull String message) { - // Ensure the project is open. If not, use the next youngest one to show the balloon - Project displayProject = findValidProject(project); - if (displayProject == null) return; - // Verify the place to put the balloon - JRootPane pane = getProjectRootPane(displayProject); - if (pane == null) return; - - // Construct the balloon + // Create a component to hold the message in HTML format JLabel component = new JLabel("" + message + ""); + + // Construct the balloon using the component final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(component) .setShadow(true) .setHideOnClickOutside(true) @@ -53,8 +52,18 @@ public class SdkBalloonHelper { .setFadeoutTime(6000) .createBalloon(); - // Register it for disposal with the project that will display it - Disposer.register(displayProject, balloon); + // Ensure the project is open. If not, find a visible Project to display the balloon. + Project displayProject = findValidProject(project); + if (displayProject == null) return; + + // Get the UI element to display the balloon + JRootPane pane = getProjectRootPane(displayProject); + if (pane == null) return; + + // This is a special case for the message when closing a project. + // The closed project is no longer visible, so the next... + // Consequently register it for disposal with the project that will display it +// Disposer.register(displayProject, balloon); // Show the balloon in the middle of the project's window - it will disappear per the animation balloon.showInCenterOf(pane); @@ -73,11 +82,43 @@ public class SdkBalloonHelper { @Nullable private Project findValidProject(@Nullable Project dodgyProject) { Project validProject = dodgyProject; - if ((validProject == null) || !validProject.isOpen()) { + if ((dodgyProject == null) || !dodgyProject.isOpen()) { // Find the next most-recently opened Project that is still open. + IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance(); + IdeFrame ideFrameFromFocusMgr = focusManager.getLastFocusedFrame(); + Project focusMgrProject = ideFrameFromFocusMgr.getProject(); + System.out.println("\n\nFocus Mgr last focused frame -> project: " + focusMgrProject.toString() + "\n"); + + + final WindowManager windowManager = WindowManagerImpl.getInstance(); + IdeFrame[] allIdeFrames = windowManager.getAllProjectFrames(); + for (int i=0; i project: %s", i, allIdeFrames[i].getProject().toString())); + } + + String outcome = String.format("\n\nUsing Win Mgr getIdeFrame(null): "); + String focusProject; + IdeFrame focusFrame = windowManager.getIdeFrame(null); + if (focusFrame != null) { + focusProject = String.format("%s", focusFrame.getProject().toString()); + } else { + focusProject = String.format("No focused project found"); + } + System.out.println(outcome + focusProject); + + outcome = String.format("\n\nUsing Win Mgr findFrameFor(null): "); + focusFrame = ((WindowManagerImpl) windowManager).findFrameFor(null); + if (focusFrame != null) { + focusProject = String.format("%s", focusFrame.getProject().toString()); + } else { + focusProject = String.format("No focused project found"); + } + System.out.println(outcome + focusProject); + ProjectManager projectManager = ProjectManager.getInstance(); Project[] allProjects = projectManager.getOpenProjects(); validProject = allProjects.length > 0 ? allProjects[allProjects.length - 1] : null; + System.out.println("\n\nProjMgr allProjects[last]: " + validProject.toString()); } return validProject; }