提交 217d3f2c 编写于 作者: A art

6794764: Translucent windows are completely repainted on every paint event, on Windows

6719382: Printing of AWT components on windows is not working
6726866: Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
6683775: Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
Reviewed-by: anthony, tdv, alexp
上级 4d0a2aa1
...@@ -436,7 +436,7 @@ public abstract class GraphicsConfiguration { ...@@ -436,7 +436,7 @@ public abstract class GraphicsConfiguration {
} }
/** /**
* Returns whether this GraphicsConfiguration supports * Returns whether this {@code GraphicsConfiguration} supports
* the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT} kind of translucency. * PERPIXEL_TRANSLUCENT} kind of translucency.
* *
......
...@@ -246,7 +246,7 @@ public abstract class GraphicsDevice { ...@@ -246,7 +246,7 @@ public abstract class GraphicsDevice {
* Simulated full-screen mode resizes * Simulated full-screen mode resizes
* the window to the size of the screen and positions it at (0,0). * the window to the size of the screen and positions it at (0,0).
* <p> * <p>
* When entering full-screen mode, if the window to be used as the * When entering full-screen mode, if the window to be used as a
* full-screen window is not visible, this method will make it visible. * full-screen window is not visible, this method will make it visible.
* It will remain visible when returning to windowed mode. * It will remain visible when returning to windowed mode.
* <p> * <p>
...@@ -261,9 +261,9 @@ public abstract class GraphicsDevice { ...@@ -261,9 +261,9 @@ public abstract class GraphicsDevice {
* *
* @param w a window to use as the full-screen window; {@code null} * @param w a window to use as the full-screen window; {@code null}
* if returning to windowed mode. Some platforms expect the * if returning to windowed mode. Some platforms expect the
* fullscreen window to be a top-level component (i.e., a Frame); * fullscreen window to be a top-level component (i.e., a {@code Frame});
* therefore it is preferable to use a Frame here rather than a * therefore it is preferable to use a {@code Frame} here rather than a
* Window. * {@code Window}.
* *
* @see #isFullScreenSupported * @see #isFullScreenSupported
* @see #getFullScreenWindow * @see #getFullScreenWindow
......
...@@ -296,7 +296,7 @@ public class Window extends Container implements Accessible { ...@@ -296,7 +296,7 @@ public class Window extends Container implements Accessible {
transient boolean isInShow = false; transient boolean isInShow = false;
/* /*
* Opacity level of the window * The opacity level of the window
* *
* @serial * @serial
* @see #setOpacity(float) * @see #setOpacity(float)
...@@ -306,7 +306,7 @@ public class Window extends Container implements Accessible { ...@@ -306,7 +306,7 @@ public class Window extends Container implements Accessible {
private float opacity = 1.0f; private float opacity = 1.0f;
/* /*
* The shape assigned to this window. This field is set to null if * The shape assigned to this window. This field is set to {@code null} if
* no shape is set (rectangular window). * no shape is set (rectangular window).
* *
* @serial * @serial
...@@ -3592,10 +3592,10 @@ public class Window extends Container implements Accessible { ...@@ -3592,10 +3592,10 @@ public class Window extends Container implements Accessible {
@Override @Override
public void setBackground(Color bgColor) { public void setBackground(Color bgColor) {
Color oldBg = getBackground(); Color oldBg = getBackground();
super.setBackground(bgColor);
if (oldBg != null && oldBg.equals(bgColor)) { if (oldBg != null && oldBg.equals(bgColor)) {
return; return;
} }
super.setBackground(bgColor);
int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255; int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
int alpha = bgColor.getAlpha(); int alpha = bgColor.getAlpha();
if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
...@@ -3623,16 +3623,37 @@ public class Window extends Container implements Accessible { ...@@ -3623,16 +3623,37 @@ public class Window extends Container implements Accessible {
} }
} }
private void updateWindow(BufferedImage backBuffer) { private void updateWindow() {
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
WindowPeer peer = (WindowPeer)getPeer(); WindowPeer peer = (WindowPeer)getPeer();
if (peer != null) { if (peer != null) {
peer.updateWindow(backBuffer); peer.updateWindow();
} }
} }
} }
private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0); /**
* {@inheritDoc}
*
* @since 1.7
*/
@Override
public void paint(Graphics g) {
Color bgColor = getBackground();
if ((bgColor != null) && (bgColor.getAlpha() < 255)) {
Graphics gg = g.create();
try {
if (gg instanceof Graphics2D) {
gg.setColor(bgColor);
((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
gg.fillRect(0, 0, getWidth(), getHeight());
}
} finally {
gg.dispose();
}
}
super.paint(g);
}
private static void setLayersOpaque(Component component, boolean isOpaque) { private static void setLayersOpaque(Component component, boolean isOpaque) {
// Shouldn't use instanceof to avoid loading Swing classes // Shouldn't use instanceof to avoid loading Swing classes
...@@ -3644,18 +3665,10 @@ public class Window extends Container implements Accessible { ...@@ -3644,18 +3665,10 @@ public class Window extends Container implements Accessible {
Container c = root.getContentPane(); Container c = root.getContentPane();
javax.swing.JComponent content = javax.swing.JComponent content =
(c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null; (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
javax.swing.JComponent gp =
(rpc.getGlassPane() instanceof javax.swing.JComponent) ?
(javax.swing.JComponent)rpc.getGlassPane() : null;
if (gp != null) {
gp.setDoubleBuffered(isOpaque);
}
lp.setOpaque(isOpaque); lp.setOpaque(isOpaque);
root.setOpaque(isOpaque); root.setOpaque(isOpaque);
root.setDoubleBuffered(isOpaque);
if (content != null) { if (content != null) {
content.setOpaque(isOpaque); content.setOpaque(isOpaque);
content.setDoubleBuffered(isOpaque);
// Iterate down one level to see whether we have a JApplet // Iterate down one level to see whether we have a JApplet
// (which is also a RootPaneContainer) which requires processing // (which is also a RootPaneContainer) which requires processing
...@@ -3748,8 +3761,8 @@ public class Window extends Container implements Accessible { ...@@ -3748,8 +3761,8 @@ public class Window extends Container implements Accessible {
window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
opaque ? 255 : 0)); opaque ? 255 : 0));
} }
public void updateWindow(Window window, BufferedImage backBuffer) { public void updateWindow(Window window) {
window.updateWindow(backBuffer); window.updateWindow();
} }
public Dimension getSecurityWarningSize(Window window) { public Dimension getSecurityWarningSize(Window window) {
......
...@@ -110,12 +110,11 @@ public interface WindowPeer extends ContainerPeer { ...@@ -110,12 +110,11 @@ public interface WindowPeer extends ContainerPeer {
void setOpaque(boolean isOpaque); void setOpaque(boolean isOpaque);
/** /**
* Updates the native part of non-opaque window using * Updates the native part of non-opaque window.
* the given image with color+alpha values for each pixel.
* *
* @see Window#setBackground(Color) * @see Window#setBackground(Color)
*/ */
void updateWindow(BufferedImage backBuffer); void updateWindow();
/** /**
* Instructs the peer to update the position of the security warning. * Instructs the peer to update the position of the security warning.
......
...@@ -34,6 +34,9 @@ import java.awt.event.ComponentListener; ...@@ -34,6 +34,9 @@ import java.awt.event.ComponentListener;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
/** This is an implementation of the <code>DesktopManager</code>. /** This is an implementation of the <code>DesktopManager</code>.
* It currently implements the basic behaviors for managing * It currently implements the basic behaviors for managing
* <code>JInternalFrame</code>s in an arbitrary parent. * <code>JInternalFrame</code>s in an arbitrary parent.
...@@ -361,7 +364,7 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -361,7 +364,7 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
g.dispose(); g.dispose();
} }
} else if (dragMode == FASTER_DRAG_MODE) { } else if (dragMode == FASTER_DRAG_MODE) {
dragFrameFaster(f, newX, newY); dragFrameFaster(f, newX, newY);
} else { } else {
setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight()); setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
} }
...@@ -634,13 +637,8 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -634,13 +637,8 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds); boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);
// System.out.println(previousBounds);
JComponent parent = (JComponent)f.getParent(); JComponent parent = (JComponent)f.getParent();
Rectangle visBounds = previousBounds.intersection(desktopBounds); Rectangle visBounds = previousBounds.intersection(desktopBounds);
// System.out.println(previousBounds);
// System.out.println(visBounds);
RepaintManager currentManager = RepaintManager.currentManager(f); RepaintManager currentManager = RepaintManager.currentManager(f);
...@@ -682,7 +680,6 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -682,7 +680,6 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
} else { } else {
dirtyRects = new Rectangle[1]; dirtyRects = new Rectangle[1];
dirtyRects[0] = previousBounds; dirtyRects[0] = previousBounds;
// System.out.println("no intersection");
}; };
// Fix the damage // Fix the damage
...@@ -701,14 +698,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -701,14 +698,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
parent.paintImmediately(dirtyRects[i]); parent.paintImmediately(dirtyRects[i]);
((JInternalFrame)f).isDragging = true; ((JInternalFrame)f).isDragging = true;
// System.out.println(dirtyRects[i]);
} }
} }
} finally { } finally {
currentManager.endPaint(); currentManager.endPaint();
} }
// update window if it's non-opaque
Window topLevel = SwingUtilities.getWindowAncestor(f);
Toolkit tk = Toolkit.getDefaultToolkit();
if (!AWTAccessor.getWindowAccessor().isOpaque(topLevel) &&
(tk instanceof SunToolkit) &&
((SunToolkit)tk).needUpdateWindow())
{
AWTAccessor.getWindowAccessor().updateWindow(topLevel);
}
} }
private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) { private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) {
......
...@@ -1021,8 +1021,10 @@ public abstract class JComponent extends Container implements Serializable, ...@@ -1021,8 +1021,10 @@ public abstract class JComponent extends Container implements Serializable,
int bw,bh; int bw,bh;
boolean printing = getFlag(IS_PRINTING); boolean printing = getFlag(IS_PRINTING);
if(!printing && repaintManager.isDoubleBufferingEnabled() && if (!printing && repaintManager.isDoubleBufferingEnabled() &&
!getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) { !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
(getFlag(IS_REPAINTING) || repaintManager.isPainting()))
{
repaintManager.beginPaint(); repaintManager.beginPaint();
try { try {
repaintManager.paint(this, this, co, clipX, clipY, clipW, repaintManager.paint(this, this, co, clipX, clipY, clipW,
......
...@@ -43,7 +43,6 @@ import sun.security.action.GetPropertyAction; ...@@ -43,7 +43,6 @@ import sun.security.action.GetPropertyAction;
import com.sun.java.swing.SwingUtilities3; import com.sun.java.swing.SwingUtilities3;
/** /**
* This class manages repaint requests, allowing the number * This class manages repaint requests, allowing the number
* of repaints to be minimized, for example by collapsing multiple * of repaints to be minimized, for example by collapsing multiple
...@@ -717,14 +716,12 @@ public class RepaintManager ...@@ -717,14 +716,12 @@ public class RepaintManager
} }
} }
private Map<Component,Rectangle> private void updateWindows(Map<Component,Rectangle> dirtyComponents) {
updateWindows(Map<Component,Rectangle> dirtyComponents)
{
Toolkit toolkit = Toolkit.getDefaultToolkit(); Toolkit toolkit = Toolkit.getDefaultToolkit();
if (!(toolkit instanceof SunToolkit && if (!(toolkit instanceof SunToolkit &&
((SunToolkit)toolkit).needUpdateWindow())) ((SunToolkit)toolkit).needUpdateWindow()))
{ {
return dirtyComponents; return;
} }
Set<Window> windows = new HashSet<Window>(); Set<Window> windows = new HashSet<Window>();
...@@ -734,25 +731,20 @@ public class RepaintManager ...@@ -734,25 +731,20 @@ public class RepaintManager
Window window = dirty instanceof Window ? Window window = dirty instanceof Window ?
(Window)dirty : (Window)dirty :
SwingUtilities.getWindowAncestor(dirty); SwingUtilities.getWindowAncestor(dirty);
if (window != null && if (window != null &&
!AWTAccessor.getWindowAccessor().isOpaque(window)) !AWTAccessor.getWindowAccessor().isOpaque(window))
{ {
// if this component's toplevel is perpixel translucent, it will
// be repainted below
it.remove();
// add to the set of windows to update (so that we don't update
// the window many times for each component to be repainted that
// belongs to this window)
windows.add(window); windows.add(window);
} }
} }
for (Window window : windows) { for (Window window : windows) {
AWTAccessor.getWindowAccessor().updateWindow(window, null); AWTAccessor.getWindowAccessor().updateWindow(window);
} }
}
return dirtyComponents; boolean isPainting() {
return painting;
} }
/** /**
...@@ -788,10 +780,6 @@ public class RepaintManager ...@@ -788,10 +780,6 @@ public class RepaintManager
int localBoundsW; int localBoundsW;
Enumeration keys; Enumeration keys;
// the components belonging to perpixel-translucent windows will be
// removed from the list
tmpDirtyComponents = updateWindows(tmpDirtyComponents);
roots = new ArrayList<Component>(count); roots = new ArrayList<Component>(count);
for (Component dirty : tmpDirtyComponents.keySet()) { for (Component dirty : tmpDirtyComponents.keySet()) {
...@@ -799,13 +787,11 @@ public class RepaintManager ...@@ -799,13 +787,11 @@ public class RepaintManager
} }
count = roots.size(); count = roots.size();
// System.out.println("roots size is " + count);
painting = true; painting = true;
try { try {
for(i=0 ; i < count ; i++) { for(i=0 ; i < count ; i++) {
dirtyComponent = roots.get(i); dirtyComponent = roots.get(i);
rect = tmpDirtyComponents.get(dirtyComponent); rect = tmpDirtyComponents.get(dirtyComponent);
// System.out.println("Should refresh :" + rect);
localBoundsH = dirtyComponent.getHeight(); localBoundsH = dirtyComponent.getHeight();
localBoundsW = dirtyComponent.getWidth(); localBoundsW = dirtyComponent.getWidth();
...@@ -848,6 +834,9 @@ public class RepaintManager ...@@ -848,6 +834,9 @@ public class RepaintManager
} finally { } finally {
painting = false; painting = false;
} }
updateWindows(tmpDirtyComponents);
tmpDirtyComponents.clear(); tmpDirtyComponents.clear();
} }
...@@ -1004,6 +993,16 @@ public class RepaintManager ...@@ -1004,6 +993,16 @@ public class RepaintManager
return delegate.getVolatileOffscreenBuffer(c, proposedWidth, return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
proposedHeight); proposedHeight);
} }
// If the window is non-opaque, it's double-buffered at peer's level
Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
Toolkit tk = Toolkit.getDefaultToolkit();
if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
return null;
}
}
GraphicsConfiguration config = c.getGraphicsConfiguration(); GraphicsConfiguration config = c.getGraphicsConfiguration();
if (config == null) { if (config == null) {
config = GraphicsEnvironment.getLocalGraphicsEnvironment(). config = GraphicsEnvironment.getLocalGraphicsEnvironment().
...@@ -1031,6 +1030,15 @@ public class RepaintManager ...@@ -1031,6 +1030,15 @@ public class RepaintManager
DoubleBufferInfo doubleBuffer; DoubleBufferInfo doubleBuffer;
int width, height; int width, height;
// If the window is non-opaque, it's double-buffered at peer's level
Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
Toolkit tk = Toolkit.getDefaultToolkit();
if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
return null;
}
}
if (standardDoubleBuffer == null) { if (standardDoubleBuffer == null) {
standardDoubleBuffer = new DoubleBufferInfo(); standardDoubleBuffer = new DoubleBufferInfo();
} }
......
...@@ -132,7 +132,7 @@ public final class AWTAccessor { ...@@ -132,7 +132,7 @@ public final class AWTAccessor {
/* /*
* Update the image of a non-opaque (translucent) window. * Update the image of a non-opaque (translucent) window.
*/ */
void updateWindow(Window window, BufferedImage backBuffer); void updateWindow(Window window);
/** Get the size of the security warning. /** Get the size of the security warning.
*/ */
......
...@@ -592,8 +592,9 @@ public abstract class EmbeddedFrame extends Frame ...@@ -592,8 +592,9 @@ public abstract class EmbeddedFrame extends Frame
public void setOpaque(boolean isOpaque) { public void setOpaque(boolean isOpaque) {
} }
public void updateWindow(BufferedImage bi) { public void updateWindow() {
} }
public void repositionSecurityWarning() { public void repositionSecurityWarning() {
} }
} }
......
...@@ -2058,7 +2058,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, ...@@ -2058,7 +2058,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
@Override @Override
public void updateWindow(BufferedImage backBuffer) { public void updateWindow() {
// no-op // no-op
} }
} }
...@@ -105,9 +105,10 @@ public abstract class TranslucentWindowPainter { ...@@ -105,9 +105,10 @@ public abstract class TranslucentWindowPainter {
} }
/** /**
* Creates (if needed), clears and returns the buffer for this painter. * Creates (if needed), clears (if requested) and returns the buffer
* for this painter.
*/ */
protected abstract Image getBackBuffer(); protected abstract Image getBackBuffer(boolean clear);
/** /**
* Updates the the window associated with this painter with the contents * Updates the the window associated with this painter with the contents
...@@ -123,31 +124,16 @@ public abstract class TranslucentWindowPainter { ...@@ -123,31 +124,16 @@ public abstract class TranslucentWindowPainter {
public abstract void flush(); public abstract void flush();
/** /**
* Updates the window associated with the painter given the passed image. * Updates the window associated with the painter.
* If the passed image is null the painter will use its own buffer for
* rendering the contents of the window into it and updating the window.
* *
* If the passed buffer has dimensions different from the window, it is * @param repaint indicates if the window should be completely repainted
* copied into the internal buffer first and the latter is used to update * to the back buffer using {@link java.awt.Window#paintAll} before update.
* the window.
*
* @param bb the image to update the non opaque window with, or null.
* If not null, the image must be of ARGB_PRE type.
*/ */
public void updateWindow(Image bb) { public void updateWindow(boolean repaint) {
boolean done = false; boolean done = false;
if (bb != null && (window.getWidth() != bb.getWidth(null) || Image bb = getBackBuffer(repaint);
window.getHeight() != bb.getHeight(null))) while (!done) {
{ if (repaint) {
Image ourBB = getBackBuffer();
Graphics2D g = (Graphics2D)ourBB.getGraphics();
g.drawImage(bb, 0, 0, null);
g.dispose();
bb = ourBB;
}
do {
if (bb == null) {
bb = getBackBuffer();
Graphics2D g = (Graphics2D)bb.getGraphics(); Graphics2D g = (Graphics2D)bb.getGraphics();
try { try {
window.paintAll(g); window.paintAll(g);
...@@ -156,17 +142,12 @@ public abstract class TranslucentWindowPainter { ...@@ -156,17 +142,12 @@ public abstract class TranslucentWindowPainter {
} }
} }
peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
bb.getWidth(null), bb.getHeight(null));
done = update(bb); done = update(bb);
// in case they passed us a lost VI, next time around we'll use our
// own bb because we can not validate and restore the contents of
// their VI
if (!done) { if (!done) {
bb = null; repaint = true;
bb = getBackBuffer(true);
} }
} while (!done); }
} }
private static final Image clearImage(Image bb) { private static final Image clearImage(Image bb) {
...@@ -190,30 +171,24 @@ public abstract class TranslucentWindowPainter { ...@@ -190,30 +171,24 @@ public abstract class TranslucentWindowPainter {
* method (VI, BI, regular Images). * method (VI, BI, regular Images).
*/ */
private static class BIWindowPainter extends TranslucentWindowPainter { private static class BIWindowPainter extends TranslucentWindowPainter {
private WeakReference<BufferedImage> biRef; private BufferedImage backBuffer;
protected BIWindowPainter(WWindowPeer peer) { protected BIWindowPainter(WWindowPeer peer) {
super(peer); super(peer);
} }
private BufferedImage getBIBackBuffer() { @Override
protected Image getBackBuffer(boolean clear) {
int w = window.getWidth(); int w = window.getWidth();
int h = window.getHeight(); int h = window.getHeight();
BufferedImage bb = biRef == null ? null : biRef.get(); if (backBuffer == null ||
if (bb == null || bb.getWidth() != w || bb.getHeight() != h) { backBuffer.getWidth() != w ||
if (bb != null) { backBuffer.getHeight() != h)
bb.flush(); {
bb = null; flush();
} backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
biRef = new WeakReference<BufferedImage>(bb);
} }
return (BufferedImage)clearImage(bb); return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
}
@Override
protected Image getBackBuffer() {
return getBIBackBuffer();
} }
@Override @Override
...@@ -246,10 +221,7 @@ public abstract class TranslucentWindowPainter { ...@@ -246,10 +221,7 @@ public abstract class TranslucentWindowPainter {
} }
// copy the passed image into our own buffer, then upload // copy the passed image into our own buffer, then upload
BufferedImage bi = getBIBackBuffer(); BufferedImage bi = (BufferedImage)clearImage(backBuffer);
Graphics2D g = (Graphics2D)bi.getGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(bb, 0, 0, null);
int data[] = int data[] =
((DataBufferInt)bi.getRaster().getDataBuffer()).getData(); ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
...@@ -259,8 +231,9 @@ public abstract class TranslucentWindowPainter { ...@@ -259,8 +231,9 @@ public abstract class TranslucentWindowPainter {
} }
public void flush() { public void flush() {
if (biRef != null) { if (backBuffer != null) {
biRef.clear(); backBuffer.flush();
backBuffer = null;
} }
} }
} }
...@@ -271,27 +244,22 @@ public abstract class TranslucentWindowPainter { ...@@ -271,27 +244,22 @@ public abstract class TranslucentWindowPainter {
* Java heap-based buffer (which is then uploaded to the layered window) * Java heap-based buffer (which is then uploaded to the layered window)
*/ */
private static class VIWindowPainter extends BIWindowPainter { private static class VIWindowPainter extends BIWindowPainter {
private WeakReference<VolatileImage> viRef; private VolatileImage viBB;
protected VIWindowPainter(WWindowPeer peer) { protected VIWindowPainter(WWindowPeer peer) {
super(peer); super(peer);
} }
@Override @Override
protected Image getBackBuffer() { protected Image getBackBuffer(boolean clear) {
int w = window.getWidth(); int w = window.getWidth();
int h = window.getHeight(); int h = window.getHeight();
GraphicsConfiguration gc = peer.getGraphicsConfiguration(); GraphicsConfiguration gc = peer.getGraphicsConfiguration();
VolatileImage viBB = viRef == null ? null : viRef.get();
if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h || if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
viBB.validate(gc) == IMAGE_INCOMPATIBLE) viBB.validate(gc) == IMAGE_INCOMPATIBLE)
{ {
if (viBB != null) { flush();
viBB.flush();
viBB = null;
}
if (gc instanceof AccelGraphicsConfig) { if (gc instanceof AccelGraphicsConfig) {
AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc); AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
...@@ -303,21 +271,16 @@ public abstract class TranslucentWindowPainter { ...@@ -303,21 +271,16 @@ public abstract class TranslucentWindowPainter {
viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT); viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
} }
viBB.validate(gc); viBB.validate(gc);
viRef = new WeakReference<VolatileImage>(viBB);
} }
return clearImage(viBB); return clear ? clearImage(viBB) : viBB;
} }
@Override @Override
public void flush() { public void flush() {
if (viRef != null) { if (viBB != null) {
VolatileImage viBB = viRef.get(); viBB.flush();
if (viBB != null) { viBB = null;
viBB.flush();
viBB = null;
}
viRef.clear();
} }
} }
} }
......
...@@ -78,25 +78,6 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer { ...@@ -78,25 +78,6 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
super.paint(g); super.paint(g);
} }
public void print(Graphics g) {
if (!(target instanceof Window) ||
AWTAccessor.getWindowAccessor().isOpaque((Window)target))
{
Dimension d = ((Component)target).getSize();
if (g instanceof Graphics2D ||
g instanceof sun.awt.Graphics2Delegate) {
// background color is setup correctly, so just use clearRect
g.clearRect(0, 0, d.width, d.height);
} else {
// emulate clearRect
g.setColor(((Component)target).getBackground());
g.fillRect(0, 0, d.width, d.height);
g.setColor(((Component)target).getForeground());
}
}
super.print(g);
}
public boolean shouldClearRectBeforePaint() { public boolean shouldClearRectBeforePaint() {
return eraseBackground; return eraseBackground;
} }
......
...@@ -239,7 +239,8 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -239,7 +239,8 @@ public abstract class WComponentPeer extends WObjectPeer
private static final double BANDING_DIVISOR = 4.0; private static final double BANDING_DIVISOR = 4.0;
private native int[] createPrintedPixels(int srcX, int srcY, private native int[] createPrintedPixels(int srcX, int srcY,
int srcW, int srcH); int srcW, int srcH,
int alpha);
public void print(Graphics g) { public void print(Graphics g) {
Component comp = (Component)target; Component comp = (Component)target;
...@@ -261,7 +262,9 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -261,7 +262,9 @@ public abstract class WComponentPeer extends WObjectPeer
} }
int h = endY - startY + 1; int h = endY - startY + 1;
int[] pix = createPrintedPixels(0, startY, totalW, h); Color bgColor = comp.getBackground();
int[] pix = createPrintedPixels(0, startY, totalW, h,
bgColor == null ? 255 : bgColor.getAlpha());
if (pix != null) { if (pix != null) {
BufferedImage bim = new BufferedImage(totalW, h, BufferedImage bim = new BufferedImage(totalW, h,
BufferedImage.TYPE_INT_ARGB); BufferedImage.TYPE_INT_ARGB);
......
...@@ -42,6 +42,9 @@ abstract class WObjectPeer { ...@@ -42,6 +42,9 @@ abstract class WObjectPeer {
// set from JNI if any errors in creating the peer occur // set from JNI if any errors in creating the peer occur
protected Error createError = null; protected Error createError = null;
// used to synchronize the state of this peer
private final Object stateLock = new Object();
public static WObjectPeer getPeerForTarget(Object t) { public static WObjectPeer getPeerForTarget(Object t) {
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t); WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
return peer; return peer;
...@@ -55,6 +58,10 @@ abstract class WObjectPeer { ...@@ -55,6 +58,10 @@ abstract class WObjectPeer {
return target; return target;
} }
public final Object getStateLock() {
return stateLock;
}
/* /*
* Subclasses should override disposeImpl() instead of dispose(). Client * Subclasses should override disposeImpl() instead of dispose(). Client
* code should always invoke dispose(), never disposeImpl(). * code should always invoke dispose(), never disposeImpl().
......
...@@ -54,7 +54,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -54,7 +54,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
private boolean isOpaque; private boolean isOpaque;
private volatile TranslucentWindowPainter painter; private TranslucentWindowPainter painter;
/* /*
* A key used for storing a list of active windows in AppContext. The value * A key used for storing a list of active windows in AppContext. The value
...@@ -106,11 +106,13 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -106,11 +106,13 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
GraphicsConfiguration gc = getGraphicsConfiguration(); GraphicsConfiguration gc = getGraphicsConfiguration();
((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this); ((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
TranslucentWindowPainter currentPainter = painter; synchronized (getStateLock()) {
if (currentPainter != null) { TranslucentWindowPainter currentPainter = painter;
currentPainter.flush(); if (currentPainter != null) {
// don't set the current one to null here; reduces the chances of currentPainter.flush();
// MT issues (like NPEs) // don't set the current one to null here; reduces the chances of
// MT issues (like NPEs)
}
} }
super.disposeImpl(); super.disposeImpl();
...@@ -178,9 +180,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -178,9 +180,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
updateIconImages(); updateIconImages();
updateShape(); Shape shape = ((Window)target).getShape();
updateOpacity(); if (shape != null) {
updateOpaque(); applyShape(Region.getInstance(shape, null));
}
float opacity = ((Window)target).getOpacity();
if (opacity < 1.0f) {
setOpacity(opacity);
}
synchronized (getStateLock()) {
// default value of a boolean field is 'false', so set isOpaque to
// true here explicitly
this.isOpaque = true;
Color bgColor = ((Window)target).getBackground();
setOpaque((bgColor == null) || (bgColor.getAlpha() == 255));
}
} }
native void createAwtWindow(WComponentPeer parent); native void createAwtWindow(WComponentPeer parent);
...@@ -214,7 +230,11 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -214,7 +230,11 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
setAlwaysOnTop(alwaysOnTop); setAlwaysOnTop(alwaysOnTop);
} }
updateWindow(null); synchronized (getStateLock()) {
if (!isOpaque) {
updateWindow(true);
}
}
} }
// Synchronize the insets members (here & in helper) with actual window // Synchronize the insets members (here & in helper) with actual window
...@@ -334,29 +354,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -334,29 +354,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
private void updateShape() {
Shape shape = ((Window)target).getShape();
if (shape != null) {
applyShape(Region.getInstance(shape, null));
}
}
private void updateOpacity() {
float opacity = ((Window)target).getOpacity();
if (opacity < 1.0f) {
setOpacity(opacity);
}
}
private void updateOpaque() {
this.isOpaque = true;
// boolean opaque = ((Window)target).isOpaque();
boolean opaque = AWTAccessor.getWindowAccessor().isOpaque((Window)target);
if (!opaque) {
setOpaque(opaque);
}
}
native void setMinSize(int width, int height); native void setMinSize(int width, int height);
/* /*
...@@ -579,6 +576,26 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -579,6 +576,26 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
return painter.getBackBuffer(false).getGraphics();
}
}
return super.getGraphics();
}
@Override
public void setBackground(Color c) {
super.setBackground(c);
synchronized (getStateLock()) {
if (!isOpaque && ((Window)target).isVisible()) {
updateWindow(true);
}
}
}
private native void setOpacity(int iOpacity); private native void setOpacity(int iOpacity);
public void setOpacity(float opacity) { public void setOpacity(float opacity) {
...@@ -600,12 +617,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -600,12 +617,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
setOpacity(iOpacity); setOpacity(iOpacity);
updateWindow(null);
synchronized (getStateLock()) {
if (!isOpaque && ((Window)target).isVisible()) {
updateWindow(true);
}
}
} }
private native void setOpaqueImpl(boolean isOpaque); private native void setOpaqueImpl(boolean isOpaque);
public void setOpaque(boolean isOpaque) { public void setOpaque(boolean isOpaque) {
synchronized (getStateLock()) {
if (this.isOpaque == isOpaque) {
return;
}
}
Window target = (Window)getTarget(); Window target = (Window)getTarget();
if (!isOpaque) { if (!isOpaque) {
...@@ -617,20 +645,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -617,20 +645,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
boolean opaqueChanged = this.isOpaque != isOpaque;
boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS(); boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
if (opaqueChanged && !isVistaOS){ if (!isVistaOS) {
// non-Vista OS: only replace the surface data if the opacity // non-Vista OS: only replace the surface data if the opacity
// status changed (see WComponentPeer.isAccelCapable() for more) // status changed (see WComponentPeer.isAccelCapable() for more)
replaceSurfaceDataRecursively(target); replaceSurfaceDataRecursively(target);
} }
this.isOpaque = isOpaque; synchronized (getStateLock()) {
this.isOpaque = isOpaque;
setOpaqueImpl(isOpaque); setOpaqueImpl(isOpaque);
if (opaqueChanged) {
if (isOpaque) { if (isOpaque) {
TranslucentWindowPainter currentPainter = painter; TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) { if (currentPainter != null) {
...@@ -642,7 +667,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -642,7 +667,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
if (opaqueChanged && isVistaOS) { if (isVistaOS) {
// On Vista: setting the window non-opaque makes the window look // On Vista: setting the window non-opaque makes the window look
// rectangular, though still catching the mouse clicks within // rectangular, though still catching the mouse clicks within
// its shape only. To restore the correct visual appearance // its shape only. To restore the correct visual appearance
...@@ -654,42 +679,33 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, ...@@ -654,42 +679,33 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
} }
} }
updateWindow(null); if (((Window)target).isVisible()) {
updateWindow(true);
}
} }
public native void updateWindowImpl(int[] data, int width, int height); public native void updateWindowImpl(int[] data, int width, int height);
public void updateWindow(BufferedImage backBuffer) { public void updateWindow() {
if (isOpaque) { updateWindow(false);
return;
}
Component target = (Component)this.target;
if (target.getWidth() <= 0 || target.getHeight() <= 0) {
return;
}
TranslucentWindowPainter currentPainter = painter;
if (currentPainter != null) {
currentPainter.updateWindow(backBuffer);
} else if (log.isLoggable(Level.FINER)) {
log.log(Level.FINER,
"Translucent window painter is null in updateWindow");
}
} }
/** private void updateWindow(boolean repaint) {
* Paints the Applet Warning into the passed Graphics2D. This method is Window w = (Window)target;
* called by the TranslucentWindowPainter before updating the layered synchronized (getStateLock()) {
* window. if (isOpaque || !w.isVisible() ||
* (w.getWidth() <= 0) || (w.getHeight() <= 0))
* @param g Graphics context to paint the warning to {
* @param w the width of the area return;
* @param h the height of the area }
* @see TranslucentWindowPainter TranslucentWindowPainter currentPainter = painter;
*/ if (currentPainter != null) {
public void paintAppletWarning(Graphics2D g, int w, int h) { currentPainter.updateWindow(repaint);
// REMIND: the applet warning needs to be painted here } else if (log.isLoggable(Level.FINER)) {
log.log(Level.FINER,
"Translucent window painter is null in updateWindow");
}
}
} }
/* /*
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "jlong.h" #include "jlong.h"
#include "awt_AWTEvent.h" #include "awt_AWTEvent.h"
#include "awt_BitmapUtil.h"
#include "awt_Component.h" #include "awt_Component.h"
#include "awt_Cursor.h" #include "awt_Cursor.h"
#include "awt_Dimension.h" #include "awt_Dimension.h"
...@@ -127,6 +128,7 @@ struct CreatePrintedPixelsStruct { ...@@ -127,6 +128,7 @@ struct CreatePrintedPixelsStruct {
jobject component; jobject component;
int srcx, srcy; int srcx, srcy;
int srcw, srch; int srcw, srch;
jint alpha;
}; };
// Struct for _SetRectangularShape() method // Struct for _SetRectangularShape() method
struct SetRectangularShapeStruct { struct SetRectangularShapeStruct {
...@@ -361,8 +363,8 @@ AwtComponent* AwtComponent::GetComponent(HWND hWnd) { ...@@ -361,8 +363,8 @@ AwtComponent* AwtComponent::GetComponent(HWND hWnd) {
AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) { AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {
AwtComponent *component = AwtComponent *component =
(AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA); (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
DASSERT( !IsBadReadPtr(component, sizeof(AwtComponent)) ); DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
DASSERT( component->GetHWnd() == hWnd ); DASSERT(!component || component->GetHWnd() == hWnd );
return component; return component;
} }
...@@ -1918,11 +1920,14 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ...@@ -1918,11 +1920,14 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
mr = mrConsume; mr = mrConsume;
break; break;
} }
case WM_AWT_CREATE_PRINTED_PIXELS: case WM_AWT_CREATE_PRINTED_PIXELS: {
retValue = (LRESULT)CreatePrintedPixels(*((SIZE *)wParam), CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam;
*((SIZE *)lParam)); SIZE loc = { cpps->srcx, cpps->srcy };
SIZE size = { cpps->srcw, cpps->srch };
retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha);
mr = mrConsume; mr = mrConsume;
break; break;
}
case WM_UNDOCUMENTED_CLICKMENUBAR: case WM_UNDOCUMENTED_CLICKMENUBAR:
{ {
if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
...@@ -4526,18 +4531,20 @@ void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) ...@@ -4526,18 +4531,20 @@ void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)
void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
{ {
if (bitmapBits) { if (!bitmapBits) {
DWORD* dest = (DWORD*)bitmapBits; return;
//XXX: might be optimized to use one loop (cy*cx -> 0). }
for (int i = 0; i < size.cy; i++ ) {
for (int j = 0; j < size.cx; j++ ) { DWORD* dest = (DWORD*)bitmapBits;
((BYTE*)(dest++))[3] = alpha; //XXX: might be optimized to use one loop (cy*cx -> 0)
} for (int i = 0; i < size.cy; i++ ) {
for (int j = 0; j < size.cx; j++ ) {
((BYTE*)(dest++))[3] = alpha;
} }
} }
} }
jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) { jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (!::IsWindowVisible(GetHWnd())) { if (!::IsWindowVisible(GetHWnd())) {
...@@ -4549,12 +4556,12 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) { ...@@ -4549,12 +4556,12 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
return NULL; return NULL;
} }
HDC hMemoryDC = ::CreateCompatibleDC(hdc); HDC hMemoryDC = ::CreateCompatibleDC(hdc);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, size.cx, size.cy); void *bitmapBits = NULL;
HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);
SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);
RECT eraseR = { 0, 0, size.cx, size.cy }; FillBackground(hMemoryDC, size);
VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));
...@@ -4562,6 +4569,14 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) { ...@@ -4562,6 +4569,14 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
// above. // above.
SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);
// First make sure the system completed any drawing to the bitmap.
::GdiFlush();
// WM_PRINT does not fill the alpha-channel of the ARGB bitmap
// leaving it equal to zero. Hence we need to fill it manually. Otherwise
// the pixels will be considered transparent when interpreting the data.
FillAlpha(bitmapBits, size, alpha);
::SelectObject(hMemoryDC, hOldBitmap); ::SelectObject(hMemoryDC, hOldBitmap);
BITMAPINFO bmi; BITMAPINFO bmi;
...@@ -5937,10 +5952,6 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param) ...@@ -5937,10 +5952,6 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param)
CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param;
jobject self = cpps->component; jobject self = cpps->component;
jint srcx = cpps->srcx;
jint srcy = cpps->srcy;
jint srcw = cpps->srcw;
jint srch = cpps->srch;
jintArray result = NULL; jintArray result = NULL;
AwtComponent *c = NULL; AwtComponent *c = NULL;
...@@ -5950,12 +5961,7 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param) ...@@ -5950,12 +5961,7 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param)
c = (AwtComponent *)pData; c = (AwtComponent *)pData;
if (::IsWindow(c->GetHWnd())) if (::IsWindow(c->GetHWnd()))
{ {
SIZE loc = { srcx, srcy }; result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0);
SIZE size = { srcw, srch };
result = (jintArray)
c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)&loc,
(LPARAM)&size);
} }
ret: ret:
env->DeleteGlobalRef(self); env->DeleteGlobalRef(self);
...@@ -6749,7 +6755,7 @@ Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) ...@@ -6749,7 +6755,7 @@ Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis)
*/ */
JNIEXPORT jintArray JNICALL JNIEXPORT jintArray JNICALL
Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,
jobject self, jint srcX, jint srcY, jint srcW, jint srcH) jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha)
{ {
TRY; TRY;
...@@ -6761,6 +6767,7 @@ Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, ...@@ -6761,6 +6767,7 @@ Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,
cpps->srcy = srcY; cpps->srcy = srcY;
cpps->srcw = srcW; cpps->srcw = srcW;
cpps->srch = srcH; cpps->srch = srcH;
cpps->alpha = alpha;
jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall(
(void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps);
......
...@@ -596,7 +596,7 @@ public: ...@@ -596,7 +596,7 @@ public:
void UpdateColorModel(); void UpdateColorModel();
jintArray CreatePrintedPixels(SIZE &loc, SIZE &size); jintArray CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha);
/* /*
* HWND, AwtComponent and Java Peer interaction * HWND, AwtComponent and Java Peer interaction
...@@ -738,7 +738,6 @@ protected: ...@@ -738,7 +738,6 @@ protected:
virtual void SetDragCapture(UINT flags); virtual void SetDragCapture(UINT flags);
virtual void ReleaseDragCapture(UINT flags); virtual void ReleaseDragCapture(UINT flags);
//These functions are overridden in AwtWindow to handle non-opaque windows.
virtual void FillBackground(HDC hMemoryDC, SIZE &size); virtual void FillBackground(HDC hMemoryDC, SIZE &size);
virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha); virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
......
...@@ -464,7 +464,7 @@ void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title, ...@@ -464,7 +464,7 @@ void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
size_t length = env->GetStringLength(javaWarningString) + 1; size_t length = env->GetStringLength(javaWarningString) + 1;
warningString = new WCHAR[length]; warningString = new WCHAR[length];
env->GetStringRegion(javaWarningString, 0, env->GetStringRegion(javaWarningString, 0,
static_cast<jsize>(length - 1), warningString); static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString));
warningString[length-1] = L'\0'; warningString[length-1] = L'\0';
env->DeleteLocalRef(javaWarningString); env->DeleteLocalRef(javaWarningString);
...@@ -2651,20 +2651,6 @@ void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height, ...@@ -2651,20 +2651,6 @@ void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
::LeaveCriticalSection(&contentBitmapCS); ::LeaveCriticalSection(&contentBitmapCS);
} }
void AwtWindow::FillBackground(HDC hMemoryDC, SIZE &size)
{
if (isOpaque()) {
AwtCanvas::FillBackground(hMemoryDC, size);
}
}
void AwtWindow::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
{
if (isOpaque()) {
AwtCanvas::FillAlpha(bitmapBits, size, alpha);
}
}
/* /*
* Fixed 6353381: it's improved fix for 4792958 * Fixed 6353381: it's improved fix for 4792958
* which was backed-out to avoid 5059656 * which was backed-out to avoid 5059656
......
...@@ -343,11 +343,6 @@ protected: ...@@ -343,11 +343,6 @@ protected:
BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */ BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */
BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */ BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */
//These are used in AwtComponent::CreatePrintedPixels. They are overridden
//here to handle non-opaque windows.
virtual void FillBackground(HDC hMemoryDC, SIZE &size);
virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
inline BOOL IsUntrusted() { inline BOOL IsUntrusted() {
return warningString != NULL; return warningString != NULL;
} }
......
/* @test
@bug 6683775 6794764
@summary Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
@author Alexander Potochkin
@run main bug6683775
*/
import com.sun.awt.AWTUtilities;
import sun.awt.SunToolkit;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class bug6683775 {
public static void main(String[] args) throws Exception {
GraphicsConfiguration gc = getGC();
if (!AWTUtilities.isTranslucencySupported(
AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT)
|| gc == null) {
return;
}
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
final JFrame testFrame = new JFrame(gc);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame backgroundFrame = new JFrame("Background frame");
backgroundFrame.setUndecorated(true);
JPanel panel = new JPanel();
panel.setBackground(Color.RED);
backgroundFrame.add(panel);
backgroundFrame.setSize(200, 200);
backgroundFrame.setVisible(true);
testFrame.setUndecorated(true);
JPanel p = new JPanel();
p.setOpaque(false);
testFrame.add(p);
AWTUtilities.setWindowOpaque(testFrame, false);
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.setSize(400, 400);
testFrame.setLocation(0, 0);
testFrame.setVisible(true);
}
});
toolkit.realSync();
//robot.getPixelColor() didn't work right for some reason
BufferedImage capture = robot.createScreenCapture(new Rectangle(100, 100));
int redRGB = Color.RED.getRGB();
if (redRGB != capture.getRGB(10, 10)) {
throw new RuntimeException("Transparent frame is not transparent!");
}
}
private static GraphicsConfiguration getGC() {
GraphicsConfiguration transparencyCapableGC =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
if (!AWTUtilities.isTranslucencyCapable(transparencyCapableGC)) {
transparencyCapableGC = null;
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = env.getScreenDevices();
for (int i = 0; i < devices.length && transparencyCapableGC == null; i++) {
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length && transparencyCapableGC == null; j++) {
if (AWTUtilities.isTranslucencyCapable(configs[j])) {
transparencyCapableGC = configs[j];
}
}
}
}
return transparencyCapableGC;
}
}
<html>
<body>
<applet code="bug6726866.class" width=400 height=100></applet>
Drag the internal frame inside the green undecorated window,
if you can drag it the test passes, otherwise fails.
</body>
</html>
/* @test
@bug 6726866
@summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
@author Alexander Potochkin
@run applet/manual=yesno bug6726866.html
*/
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
public class bug6726866 extends JApplet {
public void init() {
JFrame frame = new JFrame("bug6726866");
frame.setUndecorated(true);
setWindowNonOpaque(frame);
JDesktopPane desktop = new JDesktopPane();
desktop.setBackground(Color.GREEN);
JInternalFrame iFrame = new JInternalFrame("Test", true, true, true, true);
iFrame.add(new JLabel("internal Frame"));
iFrame.setBounds(10, 10, 300, 200);
iFrame.setVisible(true);
desktop.add(iFrame);
frame.add(desktop);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
frame.toFront();
}
private void setWindowNonOpaque(Window w) {
try {
Class<?> c = Class.forName("com.sun.awt.AWTUtilities");
Method m = c.getMethod("setWindowOpaque", Window.class, boolean.class);
m.invoke(null, w, false);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册