mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-11 08:23:26 +00:00
7124525: [macosx] No animation on certain Swing components in Aqua LaF
Reviewed-by: alexsch, swingler
This commit is contained in:
parent
97013ba028
commit
08f29b04df
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,7 +37,6 @@ import sun.awt.image.*;
|
||||
import sun.java2d.*;
|
||||
import sun.print.*;
|
||||
import apple.laf.*;
|
||||
import apple.laf.JRSUIConstants.Widget;
|
||||
import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
|
||||
|
||||
abstract class AquaPainter <T extends JRSUIState> {
|
||||
@ -63,7 +62,7 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
}
|
||||
|
||||
static <T extends JRSUIState> AquaPainter<T> create(final T state, final NineSliceMetricsProvider metricsProvider) {
|
||||
return new AquaNineSlicingImagePainter<T>(state, metricsProvider);
|
||||
return new AquaNineSlicingImagePainter<>(state, metricsProvider);
|
||||
}
|
||||
|
||||
abstract void paint(final Graphics2D g, final T stateToPaint, final Component c);
|
||||
@ -71,7 +70,7 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
final Rectangle boundsRect = new Rectangle();
|
||||
final JRSUIControl control;
|
||||
T state;
|
||||
public AquaPainter(final JRSUIControl control, final T state) {
|
||||
AquaPainter(final JRSUIControl control, final T state) {
|
||||
this.control = control;
|
||||
this.state = state;
|
||||
}
|
||||
@ -94,14 +93,14 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
protected final HashMap<T, RecyclableJRSUISlicedImageControl> slicedControlImages;
|
||||
protected final NineSliceMetricsProvider metricsProvider;
|
||||
|
||||
public AquaNineSlicingImagePainter(final T state) {
|
||||
AquaNineSlicingImagePainter(final T state) {
|
||||
this(state, null);
|
||||
}
|
||||
|
||||
public AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) {
|
||||
AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) {
|
||||
super(new JRSUIControl(false), state);
|
||||
this.metricsProvider = metricsProvider;
|
||||
slicedControlImages = new HashMap<T, RecyclableJRSUISlicedImageControl>();
|
||||
slicedControlImages = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,7 +126,7 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
}
|
||||
|
||||
static class AquaSingleImagePainter<T extends JRSUIState> extends AquaPainter<T> {
|
||||
public AquaSingleImagePainter(final T state) {
|
||||
AquaSingleImagePainter(final T state) {
|
||||
super(new JRSUIControl(false), state);
|
||||
}
|
||||
|
||||
@ -137,12 +136,12 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
}
|
||||
|
||||
static void paintFromSingleCachedImage(final Graphics2D g, final JRSUIControl control, final JRSUIState controlState, final Component c, final Rectangle boundsRect) {
|
||||
Rectangle clipRect = g.getClipBounds();
|
||||
Rectangle intersection = boundsRect.intersection(clipRect);
|
||||
final Rectangle clipRect = g.getClipBounds();
|
||||
final Rectangle intersection = boundsRect.intersection(clipRect);
|
||||
if (intersection.width <= 0 || intersection.height <= 0) return;
|
||||
|
||||
int imgX1 = intersection.x - boundsRect.x;
|
||||
int imgY1 = intersection.y - boundsRect.y;
|
||||
final int imgX1 = intersection.x - boundsRect.x;
|
||||
final int imgY1 = intersection.y - boundsRect.y;
|
||||
|
||||
final GraphicsConfiguration config = g.getDeviceConfiguration();
|
||||
final ImageCache cache = ImageCache.getInstance();
|
||||
@ -150,20 +149,15 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
if (image == null) {
|
||||
image = new BufferedImage(boundsRect.width, boundsRect.height, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
cache.setImage(image, config, boundsRect.width, boundsRect.height, controlState);
|
||||
} else {
|
||||
g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height,
|
||||
imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null);
|
||||
return;
|
||||
final WritableRaster raster = image.getRaster();
|
||||
final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
|
||||
|
||||
control.set(controlState);
|
||||
control.paint(SunWritableRaster.stealData(buffer, 0),
|
||||
image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height);
|
||||
SunWritableRaster.markDirty(buffer);
|
||||
}
|
||||
|
||||
final WritableRaster raster = image.getRaster();
|
||||
final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
|
||||
|
||||
control.set(controlState);
|
||||
control.paint(SunWritableRaster.stealData(buffer, 0),
|
||||
image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height);
|
||||
SunWritableRaster.markDirty(buffer);
|
||||
|
||||
g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height,
|
||||
imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null);
|
||||
}
|
||||
@ -173,7 +167,7 @@ abstract class AquaPainter <T extends JRSUIState> {
|
||||
final JRSUIControl control;
|
||||
final JRSUIState state;
|
||||
|
||||
public RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
|
||||
RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
|
||||
super(metrics);
|
||||
this.control = control;
|
||||
this.state = state;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,6 +30,7 @@ import java.lang.ref.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.*;
|
||||
|
||||
import apple.laf.JRSUIConstants;
|
||||
import apple.laf.JRSUIState;
|
||||
import com.apple.laf.AquaUtils.RecyclableSingleton;
|
||||
|
||||
@ -38,9 +39,9 @@ import com.apple.laf.AquaUtils.RecyclableSingleton;
|
||||
* SoftReferences so they will be dropped by the GC if heap memory gets tight. When our size hits max pixel count least
|
||||
* recently requested images are removed first.
|
||||
*/
|
||||
class ImageCache {
|
||||
final class ImageCache {
|
||||
// Ordered Map keyed by args hash, ordered by most recent accessed entry.
|
||||
private final LinkedHashMap<Integer, PixelCountSoftReference> map = new LinkedHashMap<Integer, PixelCountSoftReference>(16, 0.75f, true);
|
||||
private final LinkedHashMap<Integer, PixelCountSoftReference> map = new LinkedHashMap<>(16, 0.75f, true);
|
||||
|
||||
// Maximum number of pixels to cache, this is used if maxCount
|
||||
private final int maxPixelCount;
|
||||
@ -50,7 +51,7 @@ class ImageCache {
|
||||
// Lock for concurrent access to map
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
// Reference queue for tracking lost softreferences to images in the cache
|
||||
private final ReferenceQueue<Image> referenceQueue = new ReferenceQueue<Image>();
|
||||
private final ReferenceQueue<Image> referenceQueue = new ReferenceQueue<>();
|
||||
|
||||
// Singleton Instance
|
||||
private static final RecyclableSingleton<ImageCache> instance = new RecyclableSingleton<ImageCache>() {
|
||||
@ -63,11 +64,11 @@ class ImageCache {
|
||||
return instance.get();
|
||||
}
|
||||
|
||||
public ImageCache(final int maxPixelCount) {
|
||||
ImageCache(final int maxPixelCount) {
|
||||
this.maxPixelCount = maxPixelCount;
|
||||
}
|
||||
|
||||
public ImageCache() {
|
||||
ImageCache() {
|
||||
this((8 * 1024 * 1024) / 4); // 8Mb of pixels
|
||||
}
|
||||
|
||||
@ -99,10 +100,13 @@ class ImageCache {
|
||||
* @param config The graphics configuration, needed if cached image is a Volatile Image. Used as part of cache key
|
||||
* @param w The image width, used as part of cache key
|
||||
* @param h The image height, used as part of cache key
|
||||
* @param args Other arguments to use as part of the cache key
|
||||
* @return true if the image could be cached or false if the image is too big
|
||||
* @return true if the image could be cached, false otherwise.
|
||||
*/
|
||||
public boolean setImage(final Image image, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
|
||||
if (state.is(JRSUIConstants.Animating.YES)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int hash = hash(config, w, h, state);
|
||||
|
||||
lock.writeLock().lock();
|
||||
@ -167,7 +171,7 @@ class ImageCache {
|
||||
private final int h;
|
||||
private final JRSUIState state;
|
||||
|
||||
public PixelCountSoftReference(final Image referent, final ReferenceQueue<? super Image> q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
|
||||
PixelCountSoftReference(final Image referent, final ReferenceQueue<? super Image> q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) {
|
||||
super(referent, q);
|
||||
this.pixelCount = pixelCount;
|
||||
this.hash = hash;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user