IDEA-183788 UI is very slow if many frames appears in the debugger stack - fixed bulk add

This commit is contained in:
Egor Ushakov
2017-12-14 13:02:48 +03:00
parent 09ea271807
commit 0d244aa77a
4 changed files with 28 additions and 61 deletions
@@ -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;
}
}
@@ -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<T> extends AbstractListModel<T> 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);
}
@@ -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() {
@@ -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();
}