diff --git a/README.md b/README.md index b848380..a639cdd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Reset Your IDE Eval Information -1. Download and install plugin from [Download Link](https://plugins.zhile.io/files/ide-eval-resetter-2.1.15-3ef56c82.zip). +1. Download and install plugin from [Download Link](https://plugins.zhile.io/files/ide-eval-resetter-2.2.0-16b45f7.zip). * Alternative installation method: * Add "Custom Plugin Repository": `https://plugins.zhile.io` manually (`Settings/Preferences` -> `Plugins`) * Search and install plugin: `IDE Eval Reset` diff --git a/build.gradle b/build.gradle index 9ec7d03..f254147 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'io.zhile.research.intellij' -version '2.1.15' +version '2.2.0' sourceCompatibility = 1.7 targetCompatibility = 1.7 @@ -29,8 +29,11 @@ intellij { patchPluginXml { changeNotes = """
+Release v2.2.0
+  1. fix the issue: "Cannot create listener"
+  2. add support for: Android Studio
 Release v2.1.15
-  1. fix welcome screen menu for 2021.1
+  1. fix welcome screen menu for 2021.2
 Release v2.1.14
   1. fix minor exceptions
 Release v2.1.13
diff --git a/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java b/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
index 6f8db28..a22ac87 100644
--- a/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
+++ b/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
@@ -12,25 +12,15 @@ import com.intellij.openapi.wm.ToolWindowAnchor;
 import com.intellij.openapi.wm.ToolWindowEP;
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
-import io.zhile.research.intellij.ier.helper.*;
-import io.zhile.research.intellij.ier.listener.AppActivationListener;
-import io.zhile.research.intellij.ier.listener.AppEventListener;
-import io.zhile.research.intellij.ier.listener.BrokenPluginsListener;
+import io.zhile.research.intellij.ier.helper.Constants;
+import io.zhile.research.intellij.ier.helper.NotificationHelper;
+import io.zhile.research.intellij.ier.helper.PluginHelper;
+import io.zhile.research.intellij.ier.listener.ListenerConnector;
 import io.zhile.research.intellij.ier.tw.MainToolWindowFactory;
 import io.zhile.research.intellij.ier.ui.dialog.MainDialog;
 import org.jetbrains.annotations.NotNull;
 
 public class ResetAction extends AnAction implements DumbAware {
-    static {
-        CustomProperties.fix();
-        BrokenPlugins.fix();
-        BrokenPluginsListener.getInstance().listen();
-
-        AppEventListener.getInstance().listen();
-        AppActivationListener.getInstance().listen();
-        CustomRepository.checkAndAdd(CustomRepository.DEFAULT_HOST);
-    }
-
     public ResetAction() {
         super(Constants.ACTION_NAME, "Reset my IDE eval information", AllIcons.General.Reset);
 
@@ -38,6 +28,8 @@ public class ResetAction extends AnAction implements DumbAware {
         if ((optionsGroup instanceof DefaultActionGroup)) {
             ((DefaultActionGroup) optionsGroup).add(this);
         }
+
+        ListenerConnector.setup();
     }
 
     @Override
diff --git a/src/main/java/io/zhile/research/intellij/ier/helper/AppHelper.java b/src/main/java/io/zhile/research/intellij/ier/helper/AppHelper.java
index d38bf8b..816ebce 100644
--- a/src/main/java/io/zhile/research/intellij/ier/helper/AppHelper.java
+++ b/src/main/java/io/zhile/research/intellij/ier/helper/AppHelper.java
@@ -1,17 +1,9 @@
 package io.zhile.research.intellij.ier.helper;
 
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.util.Disposer;
-import io.zhile.research.intellij.ier.listener.AppActivationListener;
-import io.zhile.research.intellij.ier.listener.AppEventListener;
-import io.zhile.research.intellij.ier.listener.BrokenPluginsListener;
 
 public class AppHelper {
     public static void restart() {
-        Disposer.dispose(BrokenPluginsListener.getInstance());
-        Disposer.dispose(AppActivationListener.getInstance());
-        Disposer.dispose(AppEventListener.getInstance());
-
         ApplicationManager.getApplication().invokeLater(new Runnable() {
             @Override
             public void run() {
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/AppActivationListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/AppActivationListener.java
index 0e7fd79..3c2938e 100644
--- a/src/main/java/io/zhile/research/intellij/ier/listener/AppActivationListener.java
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/AppActivationListener.java
@@ -1,66 +1,28 @@
 package io.zhile.research.intellij.ier.listener;
 
 import com.intellij.notification.NotificationType;
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.application.ApplicationActivationListener;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.util.messages.MessageBusConnection;
 import io.zhile.research.intellij.ier.common.Resetter;
+import io.zhile.research.intellij.ier.helper.BrokenPlugins;
 import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.helper.NotificationHelper;
 import io.zhile.research.intellij.ier.helper.ResetTimeHelper;
 import org.jetbrains.annotations.NotNull;
 
-public class AppActivationListener implements ApplicationActivationListener, Disposable {
-    private static final Logger LOG = Logger.getInstance(AppActivationListener.class);
-    private static AppActivationListener instance;
-    private static MessageBusConnection connection;
-
-    protected AppActivationListener() {
-
-    }
-
-    public synchronized static AppActivationListener getInstance() {
-        if (instance == null) {
-            instance = new AppActivationListener();
-        }
-
-        return instance;
-    }
-
-    public synchronized void listen() {
-        if (connection != null) {
-            return;
-        }
-
-        try {
-            connection = ApplicationManager.getApplication().getMessageBus().connect();
-            connection.subscribe(ApplicationActivationListener.TOPIC, this);
-        } catch (Exception e) {
-            LOG.warn("sub app activation failed.");
-        }
-    }
-
-    public synchronized void stop() {
-        if (connection == null) {
-            return;
-        }
-
-        connection.disconnect();
-        connection = null;
-    }
+public class AppActivationListener implements ApplicationActivationListener {
+    private boolean tipped = false;
 
     public void applicationActivated(@NotNull IdeFrame ideFrame) {
-        if (!ResetTimeHelper.overResetPeriod()) {
+        BrokenPlugins.fix();
+
+        if (tipped || !ResetTimeHelper.overResetPeriod()) {
             return;
         }
 
-        stop();
-
+        tipped = true;
         AnAction action = ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID);
         NotificationType type = NotificationType.INFORMATION;
         String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
@@ -79,10 +41,4 @@ public class AppActivationListener implements ApplicationActivationListener, Dis
     public void delayedApplicationDeactivated(@NotNull IdeFrame ideFrame) {
 
     }
-
-    @Override
-    public void dispose() {
-        stop();
-        instance = null;
-    }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/AppEventListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/AppEventListener.java
index 8d16cca..4ccc559 100644
--- a/src/main/java/io/zhile/research/intellij/ier/listener/AppEventListener.java
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/AppEventListener.java
@@ -1,57 +1,15 @@
 package io.zhile.research.intellij.ier.listener;
 
 import com.intellij.ide.AppLifecycleListener;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
-import com.intellij.util.messages.MessageBusConnection;
 import io.zhile.research.intellij.ier.common.Resetter;
 import io.zhile.research.intellij.ier.helper.BrokenPlugins;
 import io.zhile.research.intellij.ier.helper.ResetTimeHelper;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class AppEventListener implements AppLifecycleListener, Disposable {
-    private static final Logger LOG = Logger.getInstance(AppEventListener.class);
-    private static AppEventListener instance;
-    private static MessageBusConnection connection;
-
-    protected AppEventListener() {
-
-    }
-
-    public synchronized static AppEventListener getInstance() {
-        if (instance == null) {
-            instance = new AppEventListener();
-        }
-
-        return instance;
-    }
-
-    public synchronized void listen() {
-        if (connection != null) {
-            return;
-        }
-
-        try {
-            connection = ApplicationManager.getApplication().getMessageBus().connect();
-            connection.subscribe(AppLifecycleListener.TOPIC, this);
-        } catch (Exception e) {
-            LOG.warn("sub app lifecycle failed.");
-        }
-    }
-
-    public synchronized void stop() {
-        if (connection == null) {
-            return;
-        }
-
-        connection.disconnect();
-        connection = null;
-    }
-
+public class AppEventListener implements AppLifecycleListener {
     public void appFrameCreated(String[] commandLineArgs, @NotNull Ref willOpenProject) {
 
     }
@@ -73,6 +31,7 @@ public class AppEventListener implements AppLifecycleListener, Disposable {
     }
 
     public void appClosing() {
+        ListenerConnector.dispose();
         BrokenPlugins.fix();
 
         if (!Resetter.isAutoReset()) {
@@ -82,10 +41,4 @@ public class AppEventListener implements AppLifecycleListener, Disposable {
         Resetter.reset(Resetter.getEvalRecords());
         ResetTimeHelper.resetLastResetTime();
     }
-
-    @Override
-    public void dispose() {
-        stop();
-        instance = null;
-    }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/AppInitListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/AppInitListener.java
index de01538..43befed 100644
--- a/src/main/java/io/zhile/research/intellij/ier/listener/AppInitListener.java
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/AppInitListener.java
@@ -1,30 +1,20 @@
 package io.zhile.research.intellij.ier.listener;
 
 import com.intellij.ide.AppLifecycleListener;
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
 import io.zhile.research.intellij.ier.helper.Constants;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.lang.ref.WeakReference;
-
-public class AppInitListener implements AppLifecycleListener, Disposable {
-    private static final WeakReference ACTION = new WeakReference<>(ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID));
-
-    protected AppInitListener() {
-
-    }
-
+public class AppInitListener implements AppLifecycleListener {
     public void appFrameCreated(String[] commandLineArgs, @NotNull Ref willOpenProject) {
 
     }
 
     public void appStarting(@Nullable Project projectFromCommandLine) {
-
+        ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID);
     }
 
     public void projectFrameClosed() {
@@ -42,9 +32,4 @@ public class AppInitListener implements AppLifecycleListener, Disposable {
     public void appClosing() {
 
     }
-
-    @Override
-    public void dispose() {
-
-    }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/BrokenPluginsListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/BrokenPluginsListener.java
deleted file mode 100644
index eeb1462..0000000
--- a/src/main/java/io/zhile/research/intellij/ier/listener/BrokenPluginsListener.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package io.zhile.research.intellij.ier.listener;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationActivationListener;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.util.messages.MessageBusConnection;
-import io.zhile.research.intellij.ier.helper.BrokenPlugins;
-import org.jetbrains.annotations.NotNull;
-
-public class BrokenPluginsListener implements ApplicationActivationListener, Disposable {
-    private static final Logger LOG = Logger.getInstance(BrokenPluginsListener.class);
-    private static BrokenPluginsListener instance;
-    private static MessageBusConnection connection;
-
-    protected BrokenPluginsListener() {
-
-    }
-
-    public synchronized static BrokenPluginsListener getInstance() {
-        if (instance == null) {
-            instance = new BrokenPluginsListener();
-        }
-
-        return instance;
-    }
-
-    public synchronized void listen() {
-        if (connection != null) {
-            return;
-        }
-
-        try {
-            connection = ApplicationManager.getApplication().getMessageBus().connect();
-            connection.subscribe(ApplicationActivationListener.TOPIC, this);
-        } catch (Exception e) {
-            LOG.warn("sub app activation failed.");
-        }
-    }
-
-    public synchronized void stop() {
-        if (connection == null) {
-            return;
-        }
-
-        connection.disconnect();
-        connection = null;
-    }
-
-    public void applicationActivated(@NotNull IdeFrame ideFrame) {
-        BrokenPlugins.fix();
-    }
-
-    public void applicationDeactivated(@NotNull IdeFrame ideFrame) {
-        applicationActivated(ideFrame);
-    }
-
-    public void delayedApplicationDeactivated(@NotNull IdeFrame ideFrame) {
-
-    }
-
-    @Override
-    public void dispose() {
-        stop();
-        instance = null;
-    }
-}
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/ListenerConnector.java b/src/main/java/io/zhile/research/intellij/ier/listener/ListenerConnector.java
new file mode 100644
index 0000000..345b712
--- /dev/null
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/ListenerConnector.java
@@ -0,0 +1,37 @@
+package io.zhile.research.intellij.ier.listener;
+
+import com.intellij.ide.AppLifecycleListener;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationActivationListener;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.messages.MessageBusConnection;
+import io.zhile.research.intellij.ier.helper.BrokenPlugins;
+import io.zhile.research.intellij.ier.helper.CustomProperties;
+import io.zhile.research.intellij.ier.helper.CustomRepository;
+
+public class ListenerConnector {
+    private static Disposable disposable;
+
+    public static void setup() {
+        dispose();
+
+        CustomProperties.fix();
+        BrokenPlugins.fix();
+        CustomRepository.checkAndAdd(CustomRepository.DEFAULT_HOST);
+
+        disposable = Disposer.newDisposable();
+        MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(disposable);
+        connection.subscribe(AppLifecycleListener.TOPIC, new AppEventListener());
+        connection.subscribe(ApplicationActivationListener.TOPIC, new AppActivationListener());
+    }
+
+    public static void dispose() {
+        if (null == disposable || Disposer.isDisposed(disposable)) {
+            return;
+        }
+
+        Disposer.dispose(disposable);
+        disposable = null;
+    }
+}
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
index 7ad9fbc..70fc1aa 100644
--- a/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
@@ -5,7 +5,6 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.util.Disposer;
 import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.helper.NotificationHelper;
 import io.zhile.research.intellij.ier.helper.PluginHelper;
@@ -34,9 +33,7 @@ public class PluginListener implements DynamicPluginListener {
             ((DefaultActionGroup) optionsGroup).remove(ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID));
         }
 
-        Disposer.dispose(BrokenPluginsListener.getInstance());
-        Disposer.dispose(AppActivationListener.getInstance());
-        Disposer.dispose(AppEventListener.getInstance());
+        ListenerConnector.dispose();
         MainToolWindowFactory.unregisterAll();
     }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java b/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
index 38387c4..bf30433 100644
--- a/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
+++ b/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
@@ -1,8 +1,10 @@
 package io.zhile.research.intellij.ier.tw;
 
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowFactory;
 import com.intellij.openapi.wm.ToolWindowManager;
@@ -15,9 +17,11 @@ import org.jetbrains.annotations.NotNull;
 public class MainToolWindowFactory implements ToolWindowFactory, DumbAware {
     @Override
     public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
-        MainForm mainForm = new MainForm(null);
-        Content content = ContentFactory.SERVICE.getInstance().createContent(mainForm.getContent(), "", true);
-        content.setDisposer(mainForm);
+        Disposable disposable = Disposer.newDisposable();
+
+        MainForm mainForm = new MainForm(disposable);
+        Content content = ContentFactory.SERVICE.getInstance().createContent(mainForm.getContent(disposable), "", true);
+        content.setDisposer(disposable);
         toolWindow.getContentManager().addContent(content);
     }
 
diff --git a/src/main/java/io/zhile/research/intellij/ier/ui/dialog/MainDialog.java b/src/main/java/io/zhile/research/intellij/ier/ui/dialog/MainDialog.java
index f79db5f..193c20d 100644
--- a/src/main/java/io/zhile/research/intellij/ier/ui/dialog/MainDialog.java
+++ b/src/main/java/io/zhile/research/intellij/ier/ui/dialog/MainDialog.java
@@ -14,8 +14,9 @@ public class MainDialog extends DialogWrapper {
 
     @Override
     protected JComponent createCenterPanel() {
-        MainForm mainForm = new MainForm(this);
-        return mainForm.getContent();
+        MainForm mainForm = new MainForm(getDisposable(), this);
+
+        return mainForm.getContent(getDisposable());
     }
 
     @Override
diff --git a/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java b/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
index c3fd24f..2eb23a0 100644
--- a/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
+++ b/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
@@ -17,10 +17,10 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.List;
 
-public class MainForm implements Disposable {
+public class MainForm {
     private JPanel rootPanel;
     private JButton btnReset;
-    private JList lstMain;
+    private JList lstMain;
     private JLabel lblLastResetTime;
     private JButton btnReload;
     private JLabel lblFound;
@@ -28,17 +28,35 @@ public class MainForm implements Disposable {
     private JCheckBox chkResetAuto;
     private JLabel lblVersion;
 
-    private final DialogWrapper dialogWrapper;
-    private final DefaultListModel listModel = new DefaultListModel<>();
+    private DialogWrapper dialogWrapper;
+    private DefaultListModel listModel = new DefaultListModel<>();
 
-    public MainForm(DialogWrapper dialogWrapper) {
-        this.dialogWrapper = dialogWrapper;
-        if (dialogWrapper != null) {
-            Disposer.register(dialogWrapper.getDisposable(), this);
-        }
+    public MainForm(Disposable disposable) {
+        this(disposable, null);
     }
 
-    public JPanel getContent() {
+    public MainForm(Disposable disposable, DialogWrapper wrapper) {
+        this.dialogWrapper = wrapper;
+
+        Disposer.register(disposable, new Disposable() {
+            @Override
+            public void dispose() {
+                rootPanel.removeAll();
+
+                listModel = null;
+                dialogWrapper = null;
+            }
+        });
+    }
+
+    public JPanel getContent(Disposable disposable) {
+        Disposer.register(disposable, new Disposable() {
+            @Override
+            public void dispose() {
+                rootPanel.removeAll();
+            }
+        });
+
         boldFont(lblFound);
         boldFont(lblLastResetTimeLabel);
         reloadLastResetTime();
@@ -46,38 +64,38 @@ public class MainForm implements Disposable {
         lblVersion.setText("v" + PluginHelper.getPluginVersion());
 
         chkResetAuto.setSelected(Resetter.isAutoReset());
-        chkResetAuto.addActionListener(new AbstractAction() {
+        addActionEventListener(chkResetAuto, new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 Resetter.setAutoReset(chkResetAuto.isSelected());
             }
-        });
+        }, disposable);
 
         lstMain.setModel(listModel);
         reloadRecordItems();
 
         btnReload.setIcon(AllIcons.Actions.Refresh);
-        btnReload.addActionListener(new AbstractAction() {
+        addActionEventListener(btnReload, new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 reloadLastResetTime();
                 reloadRecordItems();
             }
-        });
+        }, disposable);
 
         btnReset.setIcon(AllIcons.General.Reset);
-        btnReset.addActionListener(new AbstractAction() {
+        addActionEventListener(btnReset, new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 resetEvalItems();
             }
-        });
+        }, disposable);
 
         if (null != dialogWrapper) {
             dialogWrapper.getRootPane().setDefaultButton(btnReset);
+            rootPanel.setMinimumSize(new Dimension(600, 240));
         }
 
-        rootPanel.setMinimumSize(new Dimension(600, 240));
         return rootPanel;
     }
 
@@ -115,14 +133,13 @@ public class MainForm implements Disposable {
         component.setFont(font.deriveFont(font.getStyle() | Font.BOLD));
     }
 
-    @Override
-    public void dispose() {
-        for (AbstractButton button : new AbstractButton[]{chkResetAuto, btnReload, btnReset}) {
-            for (ActionListener listener : button.getActionListeners()) {
+    private static void addActionEventListener(final AbstractButton button, final ActionListener listener, Disposable disposable) {
+        button.addActionListener(listener);
+        Disposer.register(disposable, new Disposable() {
+            @Override
+            public void dispose() {
                 button.removeActionListener(listener);
             }
-        }
-
-        rootPanel.removeAll();
+        });
     }
 }
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index cb65d7b..80f9eb2 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -11,8 +11,6 @@
     

]]> - com.intellij.modules.ultimate -