An utility method to use a Graphics copy instead of the original one

This commit is contained in:
Denis Fokin
2018-07-26 23:21:53 +03:00
parent 6318206964
commit 521f51bf6f
7 changed files with 61 additions and 53 deletions
@@ -35,6 +35,8 @@ import java.awt.image.VolatileImage;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.util.ui.UIUtil.useSafely;
/**
* @author Pavel Fatin
*/
@@ -194,10 +196,10 @@ class ImmediatePainter {
createOrUpdateImageBuffer(myEditor.getComponent(), bounds.getSize());
final Graphics imageGraphics = myImage.getGraphics();
imageGraphics.translate(-bounds.x, -bounds.y);
painter.consume(imageGraphics);
imageGraphics.dispose();
useSafely(myImage.getGraphics(), imageGraphics -> {
imageGraphics.translate(-bounds.x, -bounds.y);
painter.consume(imageGraphics);
});
graphics.drawImage(myImage, bounds.x, bounds.y, null);
}
@@ -59,6 +59,8 @@ import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import static com.intellij.util.ui.UIUtil.useSafely;
public class ActionsTree {
private static final Logger LOG = Logger.getInstance(ActionsTree.class);
private static final Icon EMPTY_ICON = EmptyIcon.ICON_18;
@@ -658,13 +660,8 @@ public class ActionsTree {
super.doPaint(g);
}
Graphics2D textGraphics = (Graphics2D)g.create(0, 0, myLinkOffset, g.getClipBounds().height);
try {
super.doPaint(textGraphics);
}
finally {
textGraphics.dispose();
}
useSafely(g.create(0, 0, myLinkOffset, g.getClipBounds().height),
textGraphics -> super.doPaint(textGraphics));
g.translate(myLinkOffset, 0);
myLink.setHeight(getHeight());
myLink.doPaint(g);
@@ -32,6 +32,8 @@ import java.lang.ref.Reference;
import java.util.*;
import java.util.List;
import static com.intellij.util.ui.UIUtil.useSafely;
/**
* This panel contains all tool stripes and JLayeredPanle at the center area. All tool windows are
* located inside this layered pane.
@@ -875,32 +877,26 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
if (!myDirtyMode && UISettings.getInstance().getAnimateWindows() && !RemoteDesktopService.isRemoteSession()) {
// Prepare top image. This image is scrolling over bottom image.
final Image topImage = myLayeredPane.getTopImage();
final Graphics topGraphics = topImage.getGraphics();
Rectangle bounds;
Rectangle bounds = myComponent.getBounds();
try {
useSafely(topImage.getGraphics(), topGraphics -> {
myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER);
myLayeredPane.moveToFront(myComponent);
myLayeredPane.setBoundsInPaletteLayer(myComponent, myInfo.getAnchor(), myInfo.getWeight());
bounds = myComponent.getBounds();
myComponent.paint(topGraphics);
myLayeredPane.remove(myComponent);
}
finally {
topGraphics.dispose();
}
});
// Prepare bottom image.
final Image bottomImage = myLayeredPane.getBottomImage();
final Graphics bottomGraphics = bottomImage.getGraphics();
try {
useSafely(bottomImage.getGraphics(), bottomGraphics -> {
bottomGraphics.setClip(0, 0, bounds.width, bounds.height);
bottomGraphics.translate(-bounds.x, -bounds.y);
myLayeredPane.paint(bottomGraphics);
}
finally {
bottomGraphics.dispose();
}
});
// Start animation.
final Surface surface = new Surface(topImage, bottomImage, 1, myInfo.getAnchor(), UISettings.ANIMATION_DURATION);
myLayeredPane.add(surface, JLayeredPane.PALETTE_LAYER);
@@ -1094,26 +1090,21 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
// Prepare top image. This image is scrolling over bottom image. It contains
// picture of component is being removed.
final Image topImage = myLayeredPane.getTopImage();
final Graphics topGraphics = topImage.getGraphics();
try {
useSafely(topImage.getGraphics(), topGraphics -> {
myComponent.paint(topGraphics);
}
finally {
topGraphics.dispose();
}
});
// Prepare bottom image. This image contains picture of component that is located
// under the component to is being removed.
final Image bottomImage = myLayeredPane.getBottomImage();
final Graphics bottomGraphics = bottomImage.getGraphics();
try {
useSafely(bottomImage.getGraphics(), bottomGraphics -> {
myLayeredPane.remove(myComponent);
bottomGraphics.clipRect(0, 0, bounds.width, bounds.height);
bottomGraphics.translate(-bounds.x, -bounds.y);
myLayeredPane.paint(bottomGraphics);
}
finally {
bottomGraphics.dispose();
}
});
// Remove component from the layered pane and start animation.
final Surface surface = new Surface(topImage, bottomImage, -1, myInfo.getAnchor(), UISettings.ANIMATION_DURATION);
myLayeredPane.add(surface, JLayeredPane.PALETTE_LAYER);
@@ -51,6 +51,8 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import static com.intellij.util.ui.UIUtil.useSafely;
public class BalloonImpl implements Balloon, IdeTooltip.Ui {
/**
* This key is supposed to be used as client property of content component (with value Boolean.TRUE) to suppress shadow painting
@@ -1698,13 +1700,14 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
@SuppressWarnings("UndesirableClassUsage")
BufferedImage image = UIUtil.createImage(g, getWidth(), getHeight(),
BufferedImage.TYPE_INT_RGB);//new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = image.createGraphics();
//noinspection UseJBColor
imageGraphics.setColor(new Color(myFillColor.getRGB())); // create a copy to remove alpha
imageGraphics.fillRect(0, 0, getWidth(), getHeight());
useSafely(image.createGraphics(), imageGraphics -> {
//noinspection UseJBColor
imageGraphics.setColor(new Color(myFillColor.getRGB())); // create a copy to remove alpha
imageGraphics.fillRect(0, 0, getWidth(), getHeight());
super.paintChildren(imageGraphics);
});
super.paintChildren(imageGraphics);
imageGraphics.dispose();
Graphics2D g2d = (Graphics2D)g.create();
try {
if (UIUtil.isJreHiDPI(g2d)) {
@@ -1807,10 +1810,10 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
if (myImage != null) return;
myImage = UIUtil.createImage(myComp, getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D imageGraphics = (Graphics2D)myImage.getGraphics();
myBalloon.myPosition.paintComponent(myBalloon, shapeBounds, imageGraphics, pointTarget);
paintChildrenImpl(imageGraphics);
imageGraphics.dispose();
useSafely(myImage.getGraphics(), imageGraphics -> {
myBalloon.myPosition.paintComponent(myBalloon, shapeBounds, imageGraphics, pointTarget);
paintChildrenImpl(imageGraphics);
});
}
@@ -4590,4 +4590,19 @@ public class UIUtil {
public static boolean isRetina(@NotNull GraphicsDevice device) {
return UIUtil.DetectRetinaKit.isOracleMacRetinaDevice(device);
}
/** Employs a common pattern to use {@code Graphics}. This is a non-distractive approach
* all modifications on {@code Graphics} are metter only inside the {@code Consumer} block
*
* @param originGraphics graphics to work with
* @param drawingConsumer you can use the Graphics2D object here safely
*/
public static void useSafely(Graphics originGraphics, Consumer<? super Graphics2D> drawingConsumer) {
Graphics2D graphics = ((Graphics2D)originGraphics.create());
try {
drawingConsumer.consume(graphics);
} finally {
graphics.dispose();
}
}
}
@@ -24,6 +24,8 @@ import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;
import static com.intellij.util.ui.UIUtil.useSafely;
/**
* @author nik
*/
@@ -25,6 +25,8 @@ import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;
import static com.intellij.util.ui.UIUtil.useSafely;
/**
* @author Vitaliy.Bibaev
*/
@@ -129,13 +131,9 @@ public class TraceTreeCellRenderer extends ColoredTreeCellRenderer {
@Override
protected void doPaint(Graphics2D g) {
if (myHaveLink) {
Graphics2D textGraphics = (Graphics2D)g.create(0, 0, myLinkOffset, g.getClipBounds().height);
try {
useSafely(g.create(0, 0, myLinkOffset, g.getClipBounds().height), textGraphics -> {
super.doPaint(textGraphics);
}
finally {
textGraphics.dispose();
}
});
g.translate(myLinkOffset, 0);
myLink.setHeight(getHeight());
myLink.doPaint(g);