src/share/classes/sun/swing/JLightweightFrame.java
Print this page
*** 39,48 ****
--- 39,49 ----
import java.awt.Window;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
+ import java.awt.peer.FramePeer;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.security.AccessController;
import javax.swing.JComponent;
*** 53,62 ****
--- 54,64 ----
import javax.swing.RepaintManager;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
import sun.awt.LightweightFrame;
+ import sun.awt.image.OffScreenImage;
import sun.security.action.GetPropertyAction;
import sun.swing.SwingUtilities2.RepaintListener;
/**
* The frame serves as a lightweight container which paints its content
*** 76,86 ****
private LightweightContent content;
private Component component;
private JPanel contentPane;
! private BufferedImage bbImage;
/**
* {@code copyBufferEnabled}, true by default, defines the following strategy.
* A duplicating (copy) buffer is created for the original pixel buffer.
* The copy buffer is synchronized with the original buffer every time the
--- 78,90 ----
private LightweightContent content;
private Component component;
private JPanel contentPane;
! private OffScreenImage bbImage;
!
! private volatile int scaleFactor = 1;
/**
* {@code copyBufferEnabled}, true by default, defines the following strategy.
* A duplicating (copy) buffer is created for the original pixel buffer.
* The copy buffer is synchronized with the original buffer every time the
*** 88,98 ****
* to the {@link LightweightContent#imageBufferReset} method. The code spot
* which synchronizes two buffers becomes the only critical section guarded
* by the lock (managed with the {@link LightweightContent#paintLock()},
* {@link LightweightContent#paintUnlock()} methods).
*/
! private boolean copyBufferEnabled;
private int[] copyBuffer;
private PropertyChangeListener layoutSizeListener;
private RepaintListener repaintListener;
--- 92,102 ----
* to the {@link LightweightContent#imageBufferReset} method. The code spot
* which synchronizes two buffers becomes the only critical section guarded
* by the lock (managed with the {@link LightweightContent#paintLock()},
* {@link LightweightContent#paintUnlock()} methods).
*/
! private static boolean copyBufferEnabled;
private int[] copyBuffer;
private PropertyChangeListener layoutSizeListener;
private RepaintListener repaintListener;
*** 101,120 ****
@Override
public void updateCursor(JLightweightFrame frame) {
frame.updateClientCursor();
}
});
}
/**
* Constructs a new, initially invisible {@code JLightweightFrame}
* instance.
*/
public JLightweightFrame() {
super();
- copyBufferEnabled = "true".equals(AccessController.
- doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true")));
add(rootPane, BorderLayout.CENTER);
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
if (getGraphicsConfiguration().isTranslucencyCapable()) {
setBackground(new Color(0, 0, 0, 0));
--- 105,124 ----
@Override
public void updateCursor(JLightweightFrame frame) {
frame.updateClientCursor();
}
});
+ copyBufferEnabled = "true".equals(AccessController.
+ doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true")));
}
/**
* Constructs a new, initially invisible {@code JLightweightFrame}
* instance.
*/
public JLightweightFrame() {
super();
add(rootPane, BorderLayout.CENTER);
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
if (getGraphicsConfiguration().isTranslucencyCapable()) {
setBackground(new Color(0, 0, 0, 0));
*** 219,236 ****
@Override
public void ungrabFocus() {
if (content != null) content.focusUngrabbed();
}
! private void syncCopyBuffer(boolean reset, int x, int y, int w, int h) {
content.paintLock();
try {
int[] srcBuffer = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
if (reset) {
copyBuffer = new int[srcBuffer.length];
}
! int linestride = bbImage.getWidth();
for (int i=0; i<h; i++) {
int from = (y + i) * linestride + x;
System.arraycopy(srcBuffer, from, copyBuffer, from, w);
}
--- 223,275 ----
@Override
public void ungrabFocus() {
if (content != null) content.focusUngrabbed();
}
! @Override
! public void setScaleFactor(int scaleFactor) {
! if (scaleFactor != this.scaleFactor) {
! if (!copyBufferEnabled) content.paintLock();
! try {
! if (bbImage != null) {
! resizeBuffer(getWidth(), getHeight(), scaleFactor);
! }
! } finally {
! if (!copyBufferEnabled) content.paintUnlock();
! }
! this.scaleFactor = scaleFactor;
! if (getPeer() != null) {
! ((FramePeer)getPeer()).notifyScaleFactorChanged();
! }
! repaint();
! }
! }
!
! @Override
! public void addNotify() {
! super.addNotify();
! ((FramePeer)getPeer()).notifyScaleFactorChanged();
! }
!
! @Override
! public int getScaleFactor() {
! return scaleFactor;
! }
!
! private void syncCopyBuffer(boolean reset, int x, int y, int w, int h, int scale) {
content.paintLock();
try {
int[] srcBuffer = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
if (reset) {
copyBuffer = new int[srcBuffer.length];
}
! int linestride = bbImage.getWidth() * scale;
!
! x *= scale;
! y *= scale;
! w *= scale;
! h *= scale;
for (int i=0; i<h; i++) {
int from = (y + i) * linestride + x;
System.arraycopy(srcBuffer, from, copyBuffer, from, w);
}
*** 239,249 ****
}
}
private void notifyImageUpdated(int x, int y, int width, int height) {
if (copyBufferEnabled) {
! syncCopyBuffer(false, x, y, width, height);
}
content.imageUpdated(x, y, width, height);
}
@SuppressWarnings("serial") // anonymous class inside
--- 278,288 ----
}
}
private void notifyImageUpdated(int x, int y, int width, int height) {
if (copyBufferEnabled) {
! syncCopyBuffer(false, x, y, width, height, scaleFactor);
}
content.imageUpdated(x, y, width, height);
}
@SuppressWarnings("serial") // anonymous class inside
*** 267,277 ****
clip.height = Math.min(contentPane.getHeight(), clip.height);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
! notifyImageUpdated(clip.x, clip.y, clip.width, clip.height);
}
});
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
--- 306,317 ----
clip.height = Math.min(contentPane.getHeight(), clip.height);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
! Rectangle c = contentPane.getBounds().intersection(clip);
! notifyImageUpdated(c.x, c.y, c.width, c.height);
}
});
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
*** 321,337 ****
}
if (!copyBufferEnabled) {
content.paintLock();
}
try {
! if ((bbImage == null) || (width != bbImage.getWidth()) || (height != bbImage.getHeight())) {
! boolean createBB = true;
int newW = width;
int newH = height;
if (bbImage != null) {
! int oldW = bbImage.getWidth();
! int oldH = bbImage.getHeight();
if ((oldW >= newW) && (oldH >= newH)) {
createBB = false;
} else {
if (oldW >= newW) {
newW = oldW;
--- 361,381 ----
}
if (!copyBufferEnabled) {
content.paintLock();
}
try {
! boolean createBB = (bbImage == null);
int newW = width;
int newH = height;
if (bbImage != null) {
! int imgWidth = bbImage.getWidth();
! int imgHeight = bbImage.getHeight();
! if (width != imgWidth || height != imgHeight) {
! createBB = true;
! if (bbImage != null) {
! int oldW = imgWidth;
! int oldH = imgHeight;
if ((oldW >= newW) && (oldH >= newH)) {
createBB = false;
} else {
if (oldW >= newW) {
newW = oldW;
*** 343,382 ****
} else {
newH = Math.max((int)(oldH * 1.2), height);
}
}
}
- if (createBB) {
- BufferedImage oldBB = bbImage;
- bbImage = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB_PRE);
- if (oldBB != null) {
- Graphics g = bbImage.getGraphics();
- try {
- g.drawImage(oldBB, 0, 0, newW, newH, null);
- } finally {
- g.dispose();
- oldBB.flush();
}
}
! int[] pixels = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
! if (copyBufferEnabled) {
! syncCopyBuffer(true, 0, 0, width, height);
! pixels = copyBuffer;
! }
! content.imageBufferReset(pixels, 0, 0, width, height, bbImage.getWidth());
return;
}
- }
content.imageReshaped(0, 0, width, height);
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
}
}
}
@Override
public JRootPane getRootPane() {
return rootPane;
}
--- 387,426 ----
} else {
newH = Math.max((int)(oldH * 1.2), height);
}
}
}
}
}
! if (createBB) {
! resizeBuffer(newW, newH, scaleFactor);
return;
}
content.imageReshaped(0, 0, width, height);
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
}
}
}
+ private void resizeBuffer(int width, int height, int newScaleFactor) {
+ bbImage = new OffScreenImage(this, width, height,
+ BufferedImage.TYPE_INT_ARGB_PRE,
+ newScaleFactor);
+ bbImage.setReturnLayoutSize(true);
+
+ int[] pixels = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
+ if (copyBufferEnabled) {
+ syncCopyBuffer(true, 0, 0, width, height, newScaleFactor);
+ pixels = copyBuffer;
+ }
+ content.imageBufferReset(pixels, 0, 0, width, height,
+ width * newScaleFactor, newScaleFactor);
+ }
+
@Override
public JRootPane getRootPane() {
return rootPane;
}
*** 408,417 ****
--- 452,473 ----
@Override
public Component getGlassPane() {
return getRootPane().getGlassPane();
}
+ /**
+ * Creates an {@link OffScreenImage} with a scale factor
+ * matching the {@link #getScaleFactor()} value.
+ *
+ * @param width the layout width of the image
+ * @param height the layout height of the image
+ * @return the HiDPI image
+ */
+ public OffScreenImage createHiDPIImage(int width, int height) {
+ if (getPeer() == null) return null;
+ return ((FramePeer)getPeer()).createHiDPIImage(width, height);
+ }
/*
* Notifies client toolkit that it should change a cursor.
*
* Called from the peer via SwingAccessor, because the