From 36385bf0a7a804e8cc455aea63a0a56c5a5a16c5 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 16 Jul 2015 15:12:27 +0200 Subject: [PATCH] fix mem leak in debugger settings --- .../debugger/impl/DebuggerUtilsEx.java | 3 - .../debugger/impl/DebuggerUtilsImpl.java | 12 ++-- .../CompoundRendererConfigurable.java | 17 ++--- .../settings/UserRenderersConfigurable.java | 12 +++- .../debugger/ui/CompletionEditor.java | 8 +-- .../debugger/ui/DebuggerEditorImpl.java | 64 +++++++++---------- .../ui/DebuggerExpressionComboBox.java | 14 ++-- .../ui/DebuggerExpressionTextField.java | 12 ++-- .../ClassChildrenExpressionConfigurable.java | 24 ++++--- .../NamedChildrenConfigurable.java | 20 +++--- .../openapi/options/ConfigurableBase.java | 10 ++- .../openapi/options/ConfigurableUi.java | 3 + 12 files changed, 108 insertions(+), 91 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java index 87bf1bcbef92..1fe1e1e4f056 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -28,7 +28,6 @@ import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.requests.Requestor; -import com.intellij.debugger.ui.CompletionEditor; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.execution.filters.ExceptionFilters; @@ -461,8 +460,6 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { public abstract EvaluatorBuilder getEvaluatorBuilder(); - public abstract CompletionEditor createEditor(Project project, PsiElement context, @NonNls String recentsId); - @NotNull public static CodeFragmentFactory findAppropriateCodeFragmentFactory(final TextWithImports text, final PsiElement context) { CodeFragmentFactory factory = ApplicationManager.getApplication().runReadAction(new Computable() { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java index 96ec31727eaf..7eb7bf1d7f09 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java @@ -20,11 +20,12 @@ import com.intellij.debugger.apiAdapters.TransportServiceWrapper; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.StackFrameContext; -import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.evaluation.CodeFragmentKind; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder; import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl; -import com.intellij.debugger.ui.CompletionEditor; -import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression; import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.debugger.ui.tree.render.BatchEvaluator; @@ -122,11 +123,6 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{ return dialog.getSelected(); } - @Override - public CompletionEditor createEditor(Project project, PsiElement context, String recentsId) { - return new DebuggerExpressionComboBox(project, context, recentsId, DefaultCodeFragmentFactory.getInstance()); - } - @Override public String findAvailableDebugAddress(final boolean useSockets) throws ExecutionException { final TransportServiceWrapper transportService = TransportServiceWrapper.getTransportService(useSockets); diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index 1fcddb685485..56e76ab79b89 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -25,6 +25,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.DebuggerExpressionTextField; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.debugger.ui.tree.render.*; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Document; @@ -69,7 +70,7 @@ class CompoundRendererConfigurable extends JPanel { private static final int NAME_TABLE_COLUMN = 0; private static final int EXPRESSION_TABLE_COLUMN = 1; - public CompoundRendererConfigurable() { + public CompoundRendererConfigurable(@NotNull Disposable parentDisposable) { super(new CardLayout()); if (myProject == null) { @@ -90,10 +91,10 @@ class CompoundRendererConfigurable extends JPanel { childrenButtonGroup.add(myRbExpressionChildrenRenderer); childrenButtonGroup.add(myRbListChildrenRenderer); - myLabelEditor = new DebuggerExpressionTextField(myProject, null, "ClassLabelExpression"); - myChildrenEditor = new DebuggerExpressionTextField(myProject, null, "ClassChildrenExpression"); - myChildrenExpandedEditor = new DebuggerExpressionTextField(myProject, null, "ClassChildrenExpression"); - JComponent myChildrenListEditor = createChildrenListEditor(); + myLabelEditor = new DebuggerExpressionTextField(myProject, parentDisposable, null, "ClassLabelExpression"); + myChildrenEditor = new DebuggerExpressionTextField(myProject, parentDisposable, null, "ClassChildrenExpression"); + myChildrenExpandedEditor = new DebuggerExpressionTextField(myProject, parentDisposable, null, "ClassChildrenExpression"); + JComponent myChildrenListEditor = createChildrenListEditor(parentDisposable); final ItemListener updateListener = new ItemListener() { @Override @@ -226,10 +227,10 @@ class CompoundRendererConfigurable extends JPanel { myTable.setEnabled(myRbListChildrenRenderer.isSelected()); } - private JComponent createChildrenListEditor() { + private JComponent createChildrenListEditor(@NotNull Disposable parentDisposable) { final MyTableModel tableModel = new MyTableModel(); myTable = new JBTable(tableModel); - myListChildrenEditor = new DebuggerExpressionTextField(myProject, null, "NamedChildrenConfigurable"); + myListChildrenEditor = new DebuggerExpressionTextField(myProject, parentDisposable, null, "NamedChildrenConfigurable"); final TableColumn exprColumn = myTable.getColumnModel().getColumn(EXPRESSION_TABLE_COLUMN); exprColumn.setCellEditor(new AbstractTableCellEditor() { diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java index e75d198722c2..d92e24319427 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java @@ -19,7 +19,9 @@ import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.ui.tree.render.CompoundNodeRenderer; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.ide.util.ElementsChooser; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.ActionToolbarPosition; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.ConfigurableUi; import com.intellij.openapi.ui.Splitter; import com.intellij.ui.AnActionButton; @@ -38,12 +40,12 @@ import java.awt.*; import java.util.ArrayList; import java.util.List; -public final class UserRenderersConfigurable extends JPanel implements ConfigurableUi { +public final class UserRenderersConfigurable extends JPanel implements ConfigurableUi, Disposable { private final JPanel myNameFieldPanel; private final JTextField myNameField; private final ElementsChooser myRendererChooser; private NodeRenderer myCurrentRenderer = null; - private final CompoundRendererConfigurable myRendererDataConfigurable = new CompoundRendererConfigurable(); + private final CompoundRendererConfigurable myRendererDataConfigurable = new CompoundRendererConfigurable(this); public UserRenderersConfigurable() { super(new BorderLayout(4, 0)); @@ -86,6 +88,10 @@ public final class UserRenderersConfigurable extends JPanel implements Configura add(splitter, BorderLayout.CENTER); } + @Override + public void dispose() { + } + @Override @NotNull public JComponent getComponent() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/CompletionEditor.java b/java/debugger/impl/src/com/intellij/debugger/ui/CompletionEditor.java index 623d5c560e8b..dd0dd34a1259 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/CompletionEditor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/CompletionEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -21,8 +21,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; -public abstract class CompletionEditor extends JComponent{ - public abstract void setText (TextWithImports text); +public abstract class CompletionEditor extends JComponent { + public abstract void setText(TextWithImports text); public abstract TextWithImports getText(); @@ -30,7 +30,5 @@ public abstract class CompletionEditor extends JComponent{ public abstract PsiElement getContext(); - public abstract void dispose(); - public abstract String getRecentsId(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java index 4f304e1b75b6..6fb6cf8bf371 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -20,6 +20,7 @@ import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.impl.PositionUtil; import com.intellij.ide.DataManager; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; @@ -70,41 +71,40 @@ public abstract class DebuggerEditorImpl extends CompletionEditor { private final JLabel myChooseFactory = new JLabel(); private WeakReference myPopup; - private final PsiTreeChangeListener myPsiListener = new PsiTreeChangeAdapter() { - @Override - public void childRemoved(@NotNull PsiTreeChangeEvent event) { - checkContext(); - } - @Override - public void childReplaced(@NotNull PsiTreeChangeEvent event) { - checkContext(); - } - @Override - public void childMoved(@NotNull PsiTreeChangeEvent event) { - checkContext(); - } - private void checkContext() { - PsiElement contextElement = getContext(); - if (contextElement == null || !contextElement.isValid()) { - DebuggerManagerEx manager = DebuggerManagerEx.getInstanceEx(myProject); - if (manager == null) { - LOG.error("Cannot obtain debugger manager for project " + myProject); - return; - } - - PsiElement newContextElement = PositionUtil.getContextElement(manager.getContextManager().getContext()); - setContext(newContextElement != null && newContextElement.isValid() ? newContextElement : null); - } - } - }; private CodeFragmentFactory myFactory; protected boolean myInitialFactory; - public DebuggerEditorImpl(@NotNull Project project, PsiElement context, String recentsId, @NotNull CodeFragmentFactory factory) { + public DebuggerEditorImpl(@NotNull Project project, @NotNull CodeFragmentFactory factory, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId) { myProject = project; myContext = context; myRecentsId = recentsId; - PsiManager.getInstance(project).addPsiTreeChangeListener(myPsiListener); + PsiManager.getInstance(project).addPsiTreeChangeListener(new PsiTreeChangeAdapter() { + @Override + public void childRemoved(@NotNull PsiTreeChangeEvent event) { + checkContext(); + } + @Override + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + checkContext(); + } + @Override + public void childMoved(@NotNull PsiTreeChangeEvent event) { + checkContext(); + } + private void checkContext() { + PsiElement contextElement = getContext(); + if (contextElement == null || !contextElement.isValid()) { + DebuggerManagerEx manager = DebuggerManagerEx.getInstanceEx(myProject); + if (manager == null) { + LOG.error("Cannot obtain debugger manager for project " + myProject); + return; + } + + PsiElement newContextElement = PositionUtil.getContextElement(manager.getContextManager().getContext()); + setContext(newContextElement != null && newContextElement.isValid() ? newContextElement : null); + } + } + }, parentDisposable); setFactory(factory); myInitialFactory = true; @@ -287,12 +287,6 @@ public abstract class DebuggerEditorImpl extends CompletionEditor { } } - @Override - public void dispose() { - PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiListener); - myCurrentDocument = null; - } - @NotNull private static CodeFragmentFactory findAppropriateFactory(@NotNull TextWithImports text, @Nullable PsiElement context) { for (CodeFragmentFactory factory : DebuggerUtilsEx.getCodeFragmentFactories(context)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java index d3774706c971..cb855d5ba6fb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -16,6 +16,7 @@ package com.intellij.debugger.ui; import com.intellij.debugger.engine.evaluation.*; +import com.intellij.openapi.Disposable; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.event.DocumentAdapter; @@ -32,7 +33,7 @@ import com.intellij.ui.EditorComboBoxRenderer; import com.intellij.ui.EditorTextField; import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.impl.XDebuggerHistoryManager; -import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -96,12 +97,13 @@ public class DebuggerExpressionComboBox extends DebuggerEditorImpl { } }; - public DebuggerExpressionComboBox(Project project, @NonNls String recentsId) { - this(project, null, recentsId, DefaultCodeFragmentFactory.getInstance()); + public DebuggerExpressionComboBox(@NotNull Project project, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId) { + this(project, parentDisposable, context, recentsId, DefaultCodeFragmentFactory.getInstance()); } - public DebuggerExpressionComboBox(Project project, PsiElement context, @NonNls String recentsId, final CodeFragmentFactory factory) { - super(project, context, recentsId, factory); + public DebuggerExpressionComboBox(@NotNull Project project, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId, @NotNull CodeFragmentFactory factory) { + super(project, factory, parentDisposable, context, recentsId); + setLayout(new BorderLayout(0, 0)); myComboBox = new ComboBox(new MyComboboxModel(getRecents()), 100); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionTextField.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionTextField.java index 8dbdb3d39cdc..ef92b05ced1c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionTextField.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionTextField.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,15 +17,18 @@ package com.intellij.debugger.ui; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.debugger.engine.evaluation.CodeFragmentKind; +import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory; import com.intellij.debugger.engine.evaluation.TextWithImports; import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; -import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory; +import com.intellij.openapi.Disposable; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.ui.EditorTextField; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -37,8 +40,9 @@ public class DebuggerExpressionTextField extends DebuggerEditorImpl { private static final @NonNls String EDITOR = "editor"; private static final @NonNls String STUB = "stub"; - public DebuggerExpressionTextField(Project project, PsiElement context, final @NonNls String recentsId) { - super(project, context, recentsId, DefaultCodeFragmentFactory.getInstance()); + public DebuggerExpressionTextField(@NotNull Project project, @NotNull Disposable parentDisposable, @Nullable PsiElement context, @Nullable String recentsId) { + super(project, DefaultCodeFragmentFactory.getInstance(), parentDisposable, context, recentsId); + myStubField.setEnabled(false); myEditor = new EditorTextField("", project, StdFileTypes.JAVA); setLayout(new BorderLayout()); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java index 47faa68e9113..6747519784fd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -16,20 +16,23 @@ package com.intellij.debugger.ui.tree.render.configurables; import com.intellij.debugger.engine.DebuggerUtils; -import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.CompletionEditor; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.debugger.ui.tree.render.ExpressionChildrenRenderer; +import com.intellij.openapi.Disposable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.openapi.util.Disposer; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable{ +public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable, Disposable { private final ExpressionChildrenRenderer myRenderer; private JPanel myPanel; @@ -39,18 +42,18 @@ public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable{ private final CompletionEditor myChildrenEditor; private final CompletionEditor myExpandableEditor; - public ClassChildrenExpressionConfigurable(Project project, ExpressionChildrenRenderer renderer) { + public ClassChildrenExpressionConfigurable(@NotNull Project project, @NotNull ExpressionChildrenRenderer renderer) { myRenderer = renderer; PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project)); - myChildrenEditor = ((DebuggerUtilsEx)DebuggerUtils.getInstance()).createEditor(project, psiClass, "ClassChildrenExpression"); - myExpandableEditor = ((DebuggerUtilsEx)DebuggerUtils.getInstance()).createEditor(project, psiClass, "ClassChildrenExpression"); + myChildrenEditor = new DebuggerExpressionComboBox(project, this, psiClass, "ClassChildrenExpression"); + myExpandableEditor = new DebuggerExpressionComboBox(project, this, psiClass, "ClassChildrenExpression"); myChildrenPanel.getComponent().setLayout(new BorderLayout()); myChildrenPanel.getComponent().add(myChildrenEditor); myExpandablePanel.getComponent().setLayout(new BorderLayout()); - myExpandablePanel.getComponent().add(myExpandableEditor); + myExpandablePanel.getComponent().add(myExpandableEditor); } public JComponent createComponent() { @@ -72,8 +75,11 @@ public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable{ myExpandableEditor.setText(myRenderer.getChildrenExpandable()); } + @Override + public void dispose() { + } + public void disposeUIResources() { - myChildrenEditor.dispose(); - myExpandableEditor.dispose(); + Disposer.dispose(this); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java index f38f6ca4c94d..0bd464a158c7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java @@ -18,12 +18,14 @@ package com.intellij.debugger.ui.tree.render.configurables; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.evaluation.TextWithImports; -import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.CompletionEditor; +import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.debugger.ui.tree.render.EnumerationChildrenRenderer; +import com.intellij.openapi.Disposable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; @@ -31,6 +33,7 @@ import com.intellij.ui.TableUtil; import com.intellij.util.ui.AbstractTableCellEditor; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.Table; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -41,7 +44,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; -public class NamedChildrenConfigurable implements UnnamedConfigurable{ +public class NamedChildrenConfigurable implements UnnamedConfigurable, Disposable { private Table myTable; private final EnumerationChildrenRenderer myRenderer; private JPanel myPanel; @@ -52,7 +55,7 @@ public class NamedChildrenConfigurable implements UnnamedConfigurable{ private JButton myButtonDown; private CompletionEditor myCompletionEditor; - public NamedChildrenConfigurable(Project project, EnumerationChildrenRenderer renderer) { + public NamedChildrenConfigurable(@NotNull Project project, EnumerationChildrenRenderer renderer) { myRenderer = renderer; myTableLabel.setLabelFor(myTable); @@ -62,7 +65,7 @@ public class NamedChildrenConfigurable implements UnnamedConfigurable{ getModel().addColumn(expressionColumnName, (Object[])null); PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project)); - myCompletionEditor = ((DebuggerUtilsEx)DebuggerUtils.getInstance()).createEditor(project, psiClass, "NamedChildrenConfigurable"); + myCompletionEditor = new DebuggerExpressionComboBox(project, this, psiClass, "NamedChildrenConfigurable"); myTable.setDragEnabled(false); myTable.setIntercellSpacing(JBUI.emptySize()); @@ -155,12 +158,12 @@ public class NamedChildrenConfigurable implements UnnamedConfigurable{ } public void disposeUIResources() { - if (myCompletionEditor != null) { - myCompletionEditor.dispose(); - myCompletionEditor = null; - } + Disposer.dispose(this); } + @Override + public void dispose() { + } /* private class TextWithImportsTableRenderer implements TableCellRenderer{ @@ -184,5 +187,4 @@ public class NamedChildrenConfigurable implements UnnamedConfigurable{ } } */ - } diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java index c27d86aa919c..eb96e8e70562 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java @@ -15,6 +15,8 @@ */ package com.intellij.openapi.options; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -93,6 +95,12 @@ public abstract class ConfigurableBase, S> implemen @Override public void disposeUIResources() { - ui = null; + UI ui = this.ui; + if (ui != null) { + this.ui = null; + if (ui instanceof Disposable) { + Disposer.dispose((Disposable)ui); + } + } } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java index 3f0aa10a2009..47ecebacf563 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java @@ -19,6 +19,9 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; +/** + * Implement {@link com.intellij.openapi.Disposable} if you need explicit dispose logic. + */ public interface ConfigurableUi { void reset(@NotNull S settings);