mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
repaint file tab icon after dumb mode fixed, evaluate icons in app pool instead of dedicated thread
This commit is contained in:
@@ -28,12 +28,13 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.tabs.impl.TabLabel;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.concurrency.BoundedTaskExecutor;
|
||||
import com.intellij.util.containers.TransferToEDTQueue;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.ide.PooledThreadExecutor;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.TreeUI;
|
||||
@@ -41,7 +42,7 @@ import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import java.awt.*;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private static final int MIN_AUTO_UPDATE_MILLIS = 950;
|
||||
@@ -58,10 +59,13 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private long myLastCalcTime;
|
||||
private long myLastTimeSpent;
|
||||
|
||||
private static final ThreadPoolExecutor ourIconsCalculatingExecutor = ConcurrencyUtil.newSingleThreadExecutor("Icons");
|
||||
private static final Executor ourIconsCalculatingExecutor = new BoundedTaskExecutor(PooledThreadExecutor.INSTANCE, 1);
|
||||
|
||||
private final IconListener<T> myEvalListener;
|
||||
private static final TransferToEDTQueue<Runnable> ourLaterInvocator = TransferToEDTQueue.createRunnableMerger("Deferred icon later invocator", 200);
|
||||
private static class Holder {
|
||||
private static final boolean CHECK_CONSISTENCY = ApplicationManager.getApplication().isUnitTestMode();
|
||||
}
|
||||
|
||||
public DeferredIconImpl(Icon baseIcon, T param, @NotNull Function<T, Icon> evaluator, @NotNull IconListener<T> listener, boolean autoUpdatable) {
|
||||
this(baseIcon, param, true, evaluator, listener, autoUpdatable);
|
||||
@@ -99,7 +103,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
final Component target = getTarget(c);
|
||||
final Component paintingParent = SwingUtilities.getAncestorOfClass(PaintingParent.class, c);
|
||||
final Rectangle paintingParentRec = paintingParent == null ? null : ((PaintingParent)paintingParent).getChildRec(c);
|
||||
ourIconsCalculatingExecutor.submit(new Runnable() {
|
||||
ourIconsCalculatingExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int oldWidth = myDelegateIcon.getIconWidth();
|
||||
@@ -113,12 +117,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
IconDeferrerImpl.evaluateDeferred(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
evaluated[0] = nonNull(myEvaluator.fun(myParam));
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
evaluated[0] = EMPTY_ICON;
|
||||
}
|
||||
evaluated[0] = evaluate();
|
||||
}
|
||||
});
|
||||
if (myAutoUpdatable) {
|
||||
@@ -136,7 +135,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
IconDeferrerImpl.evaluateDeferred(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
evaluated[0] = nonNull(myEvaluator.fun(myParam));
|
||||
evaluated[0] = evaluate();
|
||||
}
|
||||
});
|
||||
if (myAutoUpdatable) {
|
||||
@@ -246,7 +245,9 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
result = EMPTY_ICON;
|
||||
}
|
||||
|
||||
checkDoesntReferenceThis(result);
|
||||
if (Holder.CHECK_CONSISTENCY) {
|
||||
checkDoesntReferenceThis(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -341,13 +342,19 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
void evalDone(DeferredIconImpl<T> source, T key, @NotNull Icon result);
|
||||
}
|
||||
|
||||
public static boolean equalIcons(Icon icon1, Icon icon2) {
|
||||
static boolean equalIcons(Icon icon1, Icon icon2) {
|
||||
if (icon1 instanceof DeferredIconImpl) {
|
||||
icon1 = ((DeferredIconImpl)icon1).myDelegateIcon;
|
||||
return ((DeferredIconImpl)icon1).isDeferredAndEqual(icon2);
|
||||
}
|
||||
if (icon2 instanceof DeferredIconImpl) {
|
||||
icon2 = ((DeferredIconImpl)icon2).myDelegateIcon;
|
||||
return ((DeferredIconImpl)icon2).isDeferredAndEqual(icon1);
|
||||
}
|
||||
return Comparing.equal(icon1, icon2);
|
||||
}
|
||||
|
||||
private boolean isDeferredAndEqual(Icon icon) {
|
||||
return icon instanceof DeferredIconImpl &&
|
||||
Comparing.equal(myParam, ((DeferredIconImpl)icon).myParam) &&
|
||||
equalIcons(myDelegateIcon, ((DeferredIconImpl)icon).myDelegateIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import com.intellij.ui.DeferredIcon;
|
||||
import com.intellij.util.FileContentUtilCore;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.TimeoutUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.io.IOException;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
|
||||
public class IconUtilTest extends PlatformTestCase {
|
||||
public void testIconDeferrerDoesNotDeferIconsAdInfinitum() throws IOException {
|
||||
VirtualFile file = createTempFile("txt", null, "hkjh", CharsetToolkit.UTF8_CHARSET);
|
||||
|
||||
Icon icon = IconUtil.getIcon(file, Iconable.ICON_FLAG_VISIBILITY, getProject());
|
||||
assertTrue(icon instanceof DeferredIcon);
|
||||
|
||||
Graphics g = new Graphics() {
|
||||
@Override
|
||||
public Graphics create() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(int x, int y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Color c) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaintMode() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXORMode(Color c1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getFont() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(Font font) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(Font f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getClipBounds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipRect(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getClip() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(Shape clip) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRect(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOval(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillOval(int x, int y, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, int x, int y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img,
|
||||
int dx1,
|
||||
int dy1,
|
||||
int dx2,
|
||||
int dy2,
|
||||
int sx1,
|
||||
int sy1,
|
||||
int sx2,
|
||||
int sy2,
|
||||
Color bgcolor,
|
||||
ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
};
|
||||
icon.paintIcon(new JLabel(), g, 0, 0); // force to eval
|
||||
TimeoutUtil.sleep(1000); // give chance to evaluate
|
||||
|
||||
Icon icon2 = IconUtil.getIcon(file, Iconable.ICON_FLAG_VISIBILITY, getProject());
|
||||
assertSame(icon, icon2);
|
||||
|
||||
FileContentUtilCore.reparseFiles(file);
|
||||
Icon icon3 = IconUtil.getIcon(file, Iconable.ICON_FLAG_VISIBILITY, getProject());
|
||||
assertNotSame(icon2, icon3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRunInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user