From 0d244aa77add6d4be64980843fbfe30dc9b023b7 Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Thu, 14 Dec 2017 12:57:45 +0300 Subject: [PATCH] IDEA-183788 UI is very slow if many frames appears in the debugger stack - fixed bulk add --- .../debugger/memory/ui/StackFrameList.java | 16 ++-------- .../com/intellij/ui/CollectionListModel.java | 19 +++--------- .../impl/frame/DebuggerFramesList.java | 23 ++++---------- .../xdebugger/impl/frame/XFramesView.java | 31 +++++++++---------- 4 files changed, 28 insertions(+), 61 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/ui/StackFrameList.java b/java/debugger/impl/src/com/intellij/debugger/memory/ui/StackFrameList.java index 983ea8eb96a1..d7df58df5151 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/ui/StackFrameList.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/ui/StackFrameList.java @@ -1,17 +1,5 @@ /* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.memory.ui; @@ -62,7 +50,7 @@ class StackFrameList extends XDebuggerFramesList { else { StackFrameItem.CapturedStackFrame frame = frameInfo.createFrame(myDebugProcess); frame.setWithSeparator(separator); - DebuggerUIUtil.invokeLater(() -> getModel().addElement(frame)); + DebuggerUIUtil.invokeLater(() -> getModel().add(frame)); separator = false; } } diff --git a/platform/platform-api/src/com/intellij/ui/CollectionListModel.java b/platform/platform-api/src/com/intellij/ui/CollectionListModel.java index c0b111105bb3..13e49f2f2e95 100644 --- a/platform/platform-api/src/com/intellij/ui/CollectionListModel.java +++ b/platform/platform-api/src/com/intellij/ui/CollectionListModel.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2016 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ui; @@ -103,7 +91,10 @@ public class CollectionListModel extends AbstractListModel implements Edit } public void remove(final int index) { - itemReplaced(myItems.remove(index), null); + T item = myItems.remove(index); + if (item != null) { + itemReplaced(item, null); + } fireIntervalRemoved(this, index, index); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java index 28eff24ce0e7..c0519e428d72 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/DebuggerFramesList.java @@ -1,21 +1,10 @@ /* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.xdebugger.impl.frame; import com.intellij.ide.OccurenceNavigator; +import com.intellij.ui.CollectionListModel; import com.intellij.ui.components.JBList; import com.intellij.xdebugger.XDebuggerBundle; @@ -28,7 +17,7 @@ import javax.swing.event.ListSelectionListener; */ public abstract class DebuggerFramesList extends JBList implements OccurenceNavigator { public DebuggerFramesList() { - super(new DefaultListModel()); + super(new CollectionListModel()); } protected void doInit() { @@ -52,12 +41,12 @@ public abstract class DebuggerFramesList extends JBList implements OccurenceNavi } @Override - public DefaultListModel getModel() { - return (DefaultListModel)super.getModel(); + public CollectionListModel getModel() { + return (CollectionListModel)super.getModel(); } public void clear() { - getModel().clear(); + getModel().removeAll(); } public int getElementCount() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java index a6fd18f38cea..be9ba54ece00 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.xdebugger.impl.frame; import com.intellij.ide.CommonActionsManager; @@ -428,24 +430,22 @@ public class XFramesView extends XDebugView { private void addFrameListElements(final List values, final boolean last) { if (myExecutionStack != null && myExecutionStack == mySelectedStack) { - DefaultListModel model = myFramesList.getModel(); - int insertIndex = model.size(); - boolean loadingPresent = !model.isEmpty() && model.getElementAt(model.getSize() - 1) == null; + CollectionListModel model = myFramesList.getModel(); + int insertIndex = model.getSize(); + boolean loadingPresent = insertIndex > 0 && model.getElementAt(insertIndex - 1) == null; if (loadingPresent) { insertIndex--; } - for (Object value : values) { - //noinspection unchecked - model.add(insertIndex++, value); - } + //noinspection unchecked + model.addAll(insertIndex, values); if (last) { if (loadingPresent) { - model.removeElementAt(model.getSize() - 1); + model.remove(model.getSize() - 1); } } else if (!loadingPresent) { //noinspection unchecked - model.addElement(null); + model.add((Object)null); } myFramesList.repaint(); } @@ -490,7 +490,7 @@ public class XFramesView extends XDebugView { int selectedFrameIndex = (int)myToSelect; if (myFramesList.getSelectedIndex() != selectedFrameIndex && myFramesList.getElementCount() > selectedFrameIndex && - myFramesList.getModel().get(selectedFrameIndex) != null) { + myFramesList.getModel().getElementAt(selectedFrameIndex) != null) { myFramesList.setSelectedIndex(selectedFrameIndex); processFrameSelection(mySession, false); myListenersEnabled = true; @@ -501,14 +501,13 @@ public class XFramesView extends XDebugView { } @SuppressWarnings("unchecked") - public boolean initModel(final DefaultListModel model) { - model.removeAllElements(); - myStackFrames.forEach(model::addElement); + public boolean initModel(final CollectionListModel model) { + model.replaceAll(myStackFrames); if (myErrorMessage != null) { - model.addElement(myErrorMessage); + model.add(myErrorMessage); } else if (!myAllFramesLoaded) { - model.addElement(null); + model.add((Object)null); } return selectCurrentFrame(); }