mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-14 04:15:04 +00:00
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
This commit is contained in:
parent
c403935e34
commit
55c50f50d0
@ -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
|
||||
* PERPIXEL_TRANSLUCENT} kind of translucency.
|
||||
*
|
||||
|
||||
@ -246,7 +246,7 @@ public abstract class GraphicsDevice {
|
||||
* Simulated full-screen mode resizes
|
||||
* the window to the size of the screen and positions it at (0,0).
|
||||
* <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.
|
||||
* It will remain visible when returning to windowed mode.
|
||||
* <p>
|
||||
@ -261,9 +261,9 @@ public abstract class GraphicsDevice {
|
||||
*
|
||||
* @param w a window to use as the full-screen window; {@code null}
|
||||
* if returning to windowed mode. Some platforms expect the
|
||||
* fullscreen window to be a top-level component (i.e., a Frame);
|
||||
* therefore it is preferable to use a Frame here rather than a
|
||||
* Window.
|
||||
* fullscreen window to be a top-level component (i.e., a {@code Frame});
|
||||
* therefore it is preferable to use a {@code Frame} here rather than a
|
||||
* {@code Window}.
|
||||
*
|
||||
* @see #isFullScreenSupported
|
||||
* @see #getFullScreenWindow
|
||||
|
||||
@ -296,7 +296,7 @@ public class Window extends Container implements Accessible {
|
||||
transient boolean isInShow = false;
|
||||
|
||||
/*
|
||||
* Opacity level of the window
|
||||
* The opacity level of the window
|
||||
*
|
||||
* @serial
|
||||
* @see #setOpacity(float)
|
||||
@ -306,7 +306,7 @@ public class Window extends Container implements Accessible {
|
||||
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).
|
||||
*
|
||||
* @serial
|
||||
@ -3592,10 +3592,10 @@ public class Window extends Container implements Accessible {
|
||||
@Override
|
||||
public void setBackground(Color bgColor) {
|
||||
Color oldBg = getBackground();
|
||||
super.setBackground(bgColor);
|
||||
if (oldBg != null && oldBg.equals(bgColor)) {
|
||||
return;
|
||||
}
|
||||
super.setBackground(bgColor);
|
||||
int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
|
||||
int alpha = bgColor.getAlpha();
|
||||
if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
|
||||
@ -3623,16 +3623,37 @@ public class Window extends Container implements Accessible {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWindow(BufferedImage backBuffer) {
|
||||
private void updateWindow() {
|
||||
synchronized (getTreeLock()) {
|
||||
WindowPeer peer = (WindowPeer)getPeer();
|
||||
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) {
|
||||
// Shouldn't use instanceof to avoid loading Swing classes
|
||||
@ -3644,18 +3665,10 @@ public class Window extends Container implements Accessible {
|
||||
Container c = root.getContentPane();
|
||||
javax.swing.JComponent content =
|
||||
(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);
|
||||
root.setOpaque(isOpaque);
|
||||
root.setDoubleBuffered(isOpaque);
|
||||
if (content != null) {
|
||||
content.setOpaque(isOpaque);
|
||||
content.setDoubleBuffered(isOpaque);
|
||||
|
||||
// Iterate down one level to see whether we have a JApplet
|
||||
// (which is also a RootPaneContainer) which requires processing
|
||||
@ -3748,8 +3761,8 @@ public class Window extends Container implements Accessible {
|
||||
window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
|
||||
opaque ? 255 : 0));
|
||||
}
|
||||
public void updateWindow(Window window, BufferedImage backBuffer) {
|
||||
window.updateWindow(backBuffer);
|
||||
public void updateWindow(Window window) {
|
||||
window.updateWindow();
|
||||
}
|
||||
|
||||
public Dimension getSecurityWarningSize(Window window) {
|
||||
|
||||
@ -110,12 +110,11 @@ public interface WindowPeer extends ContainerPeer {
|
||||
void setOpaque(boolean isOpaque);
|
||||
|
||||
/**
|
||||
* Updates the native part of non-opaque window using
|
||||
* the given image with color+alpha values for each pixel.
|
||||
* Updates the native part of non-opaque window.
|
||||
*
|
||||
* @see Window#setBackground(Color)
|
||||
*/
|
||||
void updateWindow(BufferedImage backBuffer);
|
||||
void updateWindow();
|
||||
|
||||
/**
|
||||
* Instructs the peer to update the position of the security warning.
|
||||
|
||||
@ -34,6 +34,9 @@ import java.awt.event.ComponentListener;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
/** This is an implementation of the <code>DesktopManager</code>.
|
||||
* It currently implements the basic behaviors for managing
|
||||
* <code>JInternalFrame</code>s in an arbitrary parent.
|
||||
@ -361,7 +364,7 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
|
||||
g.dispose();
|
||||
}
|
||||
} else if (dragMode == FASTER_DRAG_MODE) {
|
||||
dragFrameFaster(f, newX, newY);
|
||||
dragFrameFaster(f, newX, newY);
|
||||
} else {
|
||||
setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
|
||||
}
|
||||
@ -634,13 +637,8 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
|
||||
|
||||
boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);
|
||||
|
||||
// System.out.println(previousBounds);
|
||||
JComponent parent = (JComponent)f.getParent();
|
||||
Rectangle visBounds = previousBounds.intersection(desktopBounds);
|
||||
// System.out.println(previousBounds);
|
||||
|
||||
|
||||
// System.out.println(visBounds);
|
||||
|
||||
RepaintManager currentManager = RepaintManager.currentManager(f);
|
||||
|
||||
@ -682,7 +680,6 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
|
||||
} else {
|
||||
dirtyRects = new Rectangle[1];
|
||||
dirtyRects[0] = previousBounds;
|
||||
// System.out.println("no intersection");
|
||||
};
|
||||
|
||||
// Fix the damage
|
||||
@ -701,14 +698,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
|
||||
|
||||
parent.paintImmediately(dirtyRects[i]);
|
||||
((JInternalFrame)f).isDragging = true;
|
||||
|
||||
// System.out.println(dirtyRects[i]);
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
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) {
|
||||
|
||||
@ -1021,8 +1021,10 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
|
||||
int bw,bh;
|
||||
boolean printing = getFlag(IS_PRINTING);
|
||||
if(!printing && repaintManager.isDoubleBufferingEnabled() &&
|
||||
!getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
|
||||
if (!printing && repaintManager.isDoubleBufferingEnabled() &&
|
||||
!getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
|
||||
(getFlag(IS_REPAINTING) || repaintManager.isPainting()))
|
||||
{
|
||||
repaintManager.beginPaint();
|
||||
try {
|
||||
repaintManager.paint(this, this, co, clipX, clipY, clipW,
|
||||
|
||||
@ -43,7 +43,6 @@ import sun.security.action.GetPropertyAction;
|
||||
|
||||
import com.sun.java.swing.SwingUtilities3;
|
||||
|
||||
|
||||
/**
|
||||
* This class manages repaint requests, allowing the number
|
||||
* of repaints to be minimized, for example by collapsing multiple
|
||||
@ -717,14 +716,12 @@ public class RepaintManager
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Component,Rectangle>
|
||||
updateWindows(Map<Component,Rectangle> dirtyComponents)
|
||||
{
|
||||
private void updateWindows(Map<Component,Rectangle> dirtyComponents) {
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
if (!(toolkit instanceof SunToolkit &&
|
||||
((SunToolkit)toolkit).needUpdateWindow()))
|
||||
{
|
||||
return dirtyComponents;
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Window> windows = new HashSet<Window>();
|
||||
@ -734,25 +731,20 @@ public class RepaintManager
|
||||
Window window = dirty instanceof Window ?
|
||||
(Window)dirty :
|
||||
SwingUtilities.getWindowAncestor(dirty);
|
||||
|
||||
if (window != null &&
|
||||
!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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
int localBoundsW;
|
||||
Enumeration keys;
|
||||
|
||||
// the components belonging to perpixel-translucent windows will be
|
||||
// removed from the list
|
||||
tmpDirtyComponents = updateWindows(tmpDirtyComponents);
|
||||
|
||||
roots = new ArrayList<Component>(count);
|
||||
|
||||
for (Component dirty : tmpDirtyComponents.keySet()) {
|
||||
@ -799,13 +787,11 @@ public class RepaintManager
|
||||
}
|
||||
|
||||
count = roots.size();
|
||||
// System.out.println("roots size is " + count);
|
||||
painting = true;
|
||||
try {
|
||||
for(i=0 ; i < count ; i++) {
|
||||
dirtyComponent = roots.get(i);
|
||||
rect = tmpDirtyComponents.get(dirtyComponent);
|
||||
// System.out.println("Should refresh :" + rect);
|
||||
localBoundsH = dirtyComponent.getHeight();
|
||||
localBoundsW = dirtyComponent.getWidth();
|
||||
|
||||
@ -848,6 +834,9 @@ public class RepaintManager
|
||||
} finally {
|
||||
painting = false;
|
||||
}
|
||||
|
||||
updateWindows(tmpDirtyComponents);
|
||||
|
||||
tmpDirtyComponents.clear();
|
||||
}
|
||||
|
||||
@ -1004,6 +993,16 @@ public class RepaintManager
|
||||
return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
|
||||
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();
|
||||
if (config == null) {
|
||||
config = GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||
@ -1031,6 +1030,15 @@ public class RepaintManager
|
||||
DoubleBufferInfo doubleBuffer;
|
||||
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) {
|
||||
standardDoubleBuffer = new DoubleBufferInfo();
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ public final class AWTAccessor {
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@ -592,8 +592,9 @@ public abstract class EmbeddedFrame extends Frame
|
||||
public void setOpaque(boolean isOpaque) {
|
||||
}
|
||||
|
||||
public void updateWindow(BufferedImage bi) {
|
||||
public void updateWindow() {
|
||||
}
|
||||
|
||||
public void repositionSecurityWarning() {
|
||||
}
|
||||
}
|
||||
|
||||
@ -2058,7 +2058,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateWindow(BufferedImage backBuffer) {
|
||||
public void updateWindow() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -123,31 +124,16 @@ public abstract class TranslucentWindowPainter {
|
||||
public abstract void flush();
|
||||
|
||||
/**
|
||||
* Updates the window associated with the painter given the passed image.
|
||||
* 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.
|
||||
* Updates the window associated with the painter.
|
||||
*
|
||||
* If the passed buffer has dimensions different from the window, it is
|
||||
* copied into the internal buffer first and the latter is used to 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.
|
||||
* @param repaint indicates if the window should be completely repainted
|
||||
* to the back buffer using {@link java.awt.Window#paintAll} before update.
|
||||
*/
|
||||
public void updateWindow(Image bb) {
|
||||
public void updateWindow(boolean repaint) {
|
||||
boolean done = false;
|
||||
if (bb != null && (window.getWidth() != bb.getWidth(null) ||
|
||||
window.getHeight() != bb.getHeight(null)))
|
||||
{
|
||||
Image ourBB = getBackBuffer();
|
||||
Graphics2D g = (Graphics2D)ourBB.getGraphics();
|
||||
g.drawImage(bb, 0, 0, null);
|
||||
g.dispose();
|
||||
bb = ourBB;
|
||||
}
|
||||
do {
|
||||
if (bb == null) {
|
||||
bb = getBackBuffer();
|
||||
Image bb = getBackBuffer(repaint);
|
||||
while (!done) {
|
||||
if (repaint) {
|
||||
Graphics2D g = (Graphics2D)bb.getGraphics();
|
||||
try {
|
||||
window.paintAll(g);
|
||||
@ -156,17 +142,12 @@ public abstract class TranslucentWindowPainter {
|
||||
}
|
||||
}
|
||||
|
||||
peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
|
||||
bb.getWidth(null), bb.getHeight(null));
|
||||
|
||||
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) {
|
||||
bb = null;
|
||||
repaint = true;
|
||||
bb = getBackBuffer(true);
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Image clearImage(Image bb) {
|
||||
@ -190,30 +171,24 @@ public abstract class TranslucentWindowPainter {
|
||||
* method (VI, BI, regular Images).
|
||||
*/
|
||||
private static class BIWindowPainter extends TranslucentWindowPainter {
|
||||
private WeakReference<BufferedImage> biRef;
|
||||
private BufferedImage backBuffer;
|
||||
|
||||
protected BIWindowPainter(WWindowPeer peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
private BufferedImage getBIBackBuffer() {
|
||||
@Override
|
||||
protected Image getBackBuffer(boolean clear) {
|
||||
int w = window.getWidth();
|
||||
int h = window.getHeight();
|
||||
BufferedImage bb = biRef == null ? null : biRef.get();
|
||||
if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
|
||||
if (bb != null) {
|
||||
bb.flush();
|
||||
bb = null;
|
||||
}
|
||||
bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
biRef = new WeakReference<BufferedImage>(bb);
|
||||
if (backBuffer == null ||
|
||||
backBuffer.getWidth() != w ||
|
||||
backBuffer.getHeight() != h)
|
||||
{
|
||||
flush();
|
||||
backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
}
|
||||
return (BufferedImage)clearImage(bb);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Image getBackBuffer() {
|
||||
return getBIBackBuffer();
|
||||
return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,10 +221,7 @@ public abstract class TranslucentWindowPainter {
|
||||
}
|
||||
|
||||
// copy the passed image into our own buffer, then upload
|
||||
BufferedImage bi = getBIBackBuffer();
|
||||
Graphics2D g = (Graphics2D)bi.getGraphics();
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.drawImage(bb, 0, 0, null);
|
||||
BufferedImage bi = (BufferedImage)clearImage(backBuffer);
|
||||
|
||||
int data[] =
|
||||
((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
|
||||
@ -259,8 +231,9 @@ public abstract class TranslucentWindowPainter {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
if (biRef != null) {
|
||||
biRef.clear();
|
||||
if (backBuffer != null) {
|
||||
backBuffer.flush();
|
||||
backBuffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,27 +244,22 @@ public abstract class TranslucentWindowPainter {
|
||||
* Java heap-based buffer (which is then uploaded to the layered window)
|
||||
*/
|
||||
private static class VIWindowPainter extends BIWindowPainter {
|
||||
private WeakReference<VolatileImage> viRef;
|
||||
private VolatileImage viBB;
|
||||
|
||||
protected VIWindowPainter(WWindowPeer peer) {
|
||||
super(peer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Image getBackBuffer() {
|
||||
protected Image getBackBuffer(boolean clear) {
|
||||
int w = window.getWidth();
|
||||
int h = window.getHeight();
|
||||
GraphicsConfiguration gc = peer.getGraphicsConfiguration();
|
||||
|
||||
VolatileImage viBB = viRef == null ? null : viRef.get();
|
||||
|
||||
if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
|
||||
viBB.validate(gc) == IMAGE_INCOMPATIBLE)
|
||||
{
|
||||
if (viBB != null) {
|
||||
viBB.flush();
|
||||
viBB = null;
|
||||
}
|
||||
flush();
|
||||
|
||||
if (gc instanceof AccelGraphicsConfig) {
|
||||
AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
|
||||
@ -303,21 +271,16 @@ public abstract class TranslucentWindowPainter {
|
||||
viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
|
||||
}
|
||||
viBB.validate(gc);
|
||||
viRef = new WeakReference<VolatileImage>(viBB);
|
||||
}
|
||||
|
||||
return clearImage(viBB);
|
||||
return clear ? clearImage(viBB) : viBB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
if (viRef != null) {
|
||||
VolatileImage viBB = viRef.get();
|
||||
if (viBB != null) {
|
||||
viBB.flush();
|
||||
viBB = null;
|
||||
}
|
||||
viRef.clear();
|
||||
if (viBB != null) {
|
||||
viBB.flush();
|
||||
viBB = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,25 +78,6 @@ class WCanvasPeer extends WComponentPeer implements CanvasPeer {
|
||||
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() {
|
||||
return eraseBackground;
|
||||
}
|
||||
|
||||
@ -239,7 +239,8 @@ public abstract class WComponentPeer extends WObjectPeer
|
||||
|
||||
private static final double BANDING_DIVISOR = 4.0;
|
||||
private native int[] createPrintedPixels(int srcX, int srcY,
|
||||
int srcW, int srcH);
|
||||
int srcW, int srcH,
|
||||
int alpha);
|
||||
public void print(Graphics g) {
|
||||
|
||||
Component comp = (Component)target;
|
||||
@ -261,7 +262,9 @@ public abstract class WComponentPeer extends WObjectPeer
|
||||
}
|
||||
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) {
|
||||
BufferedImage bim = new BufferedImage(totalW, h,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
@ -42,6 +42,9 @@ abstract class WObjectPeer {
|
||||
// set from JNI if any errors in creating the peer occur
|
||||
protected Error createError = null;
|
||||
|
||||
// used to synchronize the state of this peer
|
||||
private final Object stateLock = new Object();
|
||||
|
||||
public static WObjectPeer getPeerForTarget(Object t) {
|
||||
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
|
||||
return peer;
|
||||
@ -55,6 +58,10 @@ abstract class WObjectPeer {
|
||||
return target;
|
||||
}
|
||||
|
||||
public final Object getStateLock() {
|
||||
return stateLock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subclasses should override disposeImpl() instead of dispose(). Client
|
||||
* code should always invoke dispose(), never disposeImpl().
|
||||
|
||||
@ -54,7 +54,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
|
||||
private boolean isOpaque;
|
||||
|
||||
private volatile TranslucentWindowPainter painter;
|
||||
private TranslucentWindowPainter painter;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||
((Win32GraphicsDevice)gc.getDevice()).removeDisplayChangedListener(this);
|
||||
|
||||
TranslucentWindowPainter currentPainter = painter;
|
||||
if (currentPainter != null) {
|
||||
currentPainter.flush();
|
||||
// don't set the current one to null here; reduces the chances of
|
||||
// MT issues (like NPEs)
|
||||
synchronized (getStateLock()) {
|
||||
TranslucentWindowPainter currentPainter = painter;
|
||||
if (currentPainter != null) {
|
||||
currentPainter.flush();
|
||||
// don't set the current one to null here; reduces the chances of
|
||||
// MT issues (like NPEs)
|
||||
}
|
||||
}
|
||||
|
||||
super.disposeImpl();
|
||||
@ -178,9 +180,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
|
||||
updateIconImages();
|
||||
|
||||
updateShape();
|
||||
updateOpacity();
|
||||
updateOpaque();
|
||||
Shape shape = ((Window)target).getShape();
|
||||
if (shape != null) {
|
||||
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);
|
||||
@ -214,7 +230,11 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
setAlwaysOnTop(alwaysOnTop);
|
||||
}
|
||||
|
||||
updateWindow(null);
|
||||
synchronized (getStateLock()) {
|
||||
if (!isOpaque) {
|
||||
updateWindow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronize the insets members (here & in helper) with actual window
|
||||
@ -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);
|
||||
|
||||
/*
|
||||
@ -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);
|
||||
|
||||
public void setOpacity(float opacity) {
|
||||
@ -600,12 +617,23 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
}
|
||||
|
||||
setOpacity(iOpacity);
|
||||
updateWindow(null);
|
||||
|
||||
synchronized (getStateLock()) {
|
||||
if (!isOpaque && ((Window)target).isVisible()) {
|
||||
updateWindow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private native void setOpaqueImpl(boolean isOpaque);
|
||||
|
||||
public void setOpaque(boolean isOpaque) {
|
||||
synchronized (getStateLock()) {
|
||||
if (this.isOpaque == isOpaque) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Window target = (Window)getTarget();
|
||||
|
||||
if (!isOpaque) {
|
||||
@ -617,20 +645,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
}
|
||||
}
|
||||
|
||||
boolean opaqueChanged = this.isOpaque != isOpaque;
|
||||
boolean isVistaOS = Win32GraphicsEnvironment.isVistaOS();
|
||||
|
||||
if (opaqueChanged && !isVistaOS){
|
||||
if (!isVistaOS) {
|
||||
// non-Vista OS: only replace the surface data if the opacity
|
||||
// status changed (see WComponentPeer.isAccelCapable() for more)
|
||||
replaceSurfaceDataRecursively(target);
|
||||
}
|
||||
|
||||
this.isOpaque = isOpaque;
|
||||
|
||||
setOpaqueImpl(isOpaque);
|
||||
|
||||
if (opaqueChanged) {
|
||||
synchronized (getStateLock()) {
|
||||
this.isOpaque = isOpaque;
|
||||
setOpaqueImpl(isOpaque);
|
||||
if (isOpaque) {
|
||||
TranslucentWindowPainter currentPainter = painter;
|
||||
if (currentPainter != null) {
|
||||
@ -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
|
||||
// rectangular, though still catching the mouse clicks within
|
||||
// its shape only. To restore the correct visual appearance
|
||||
@ -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 void updateWindow(BufferedImage backBuffer) {
|
||||
if (isOpaque) {
|
||||
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");
|
||||
}
|
||||
public void updateWindow() {
|
||||
updateWindow(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the Applet Warning into the passed Graphics2D. This method is
|
||||
* called by the TranslucentWindowPainter before updating the layered
|
||||
* window.
|
||||
*
|
||||
* @param g Graphics context to paint the warning to
|
||||
* @param w the width of the area
|
||||
* @param h the height of the area
|
||||
* @see TranslucentWindowPainter
|
||||
*/
|
||||
public void paintAppletWarning(Graphics2D g, int w, int h) {
|
||||
// REMIND: the applet warning needs to be painted here
|
||||
private void updateWindow(boolean repaint) {
|
||||
Window w = (Window)target;
|
||||
synchronized (getStateLock()) {
|
||||
if (isOpaque || !w.isVisible() ||
|
||||
(w.getWidth() <= 0) || (w.getHeight() <= 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
TranslucentWindowPainter currentPainter = painter;
|
||||
if (currentPainter != null) {
|
||||
currentPainter.updateWindow(repaint);
|
||||
} else if (log.isLoggable(Level.FINER)) {
|
||||
log.log(Level.FINER,
|
||||
"Translucent window painter is null in updateWindow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include "jlong.h"
|
||||
#include "awt_AWTEvent.h"
|
||||
#include "awt_BitmapUtil.h"
|
||||
#include "awt_Component.h"
|
||||
#include "awt_Cursor.h"
|
||||
#include "awt_Dimension.h"
|
||||
@ -127,6 +128,7 @@ struct CreatePrintedPixelsStruct {
|
||||
jobject component;
|
||||
int srcx, srcy;
|
||||
int srcw, srch;
|
||||
jint alpha;
|
||||
};
|
||||
// Struct for _SetRectangularShape() method
|
||||
struct SetRectangularShapeStruct {
|
||||
@ -361,8 +363,8 @@ AwtComponent* AwtComponent::GetComponent(HWND hWnd) {
|
||||
AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {
|
||||
AwtComponent *component =
|
||||
(AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
DASSERT( !IsBadReadPtr(component, sizeof(AwtComponent)) );
|
||||
DASSERT( component->GetHWnd() == hWnd );
|
||||
DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
|
||||
DASSERT(!component || component->GetHWnd() == hWnd );
|
||||
return component;
|
||||
}
|
||||
|
||||
@ -1918,11 +1920,14 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
mr = mrConsume;
|
||||
break;
|
||||
}
|
||||
case WM_AWT_CREATE_PRINTED_PIXELS:
|
||||
retValue = (LRESULT)CreatePrintedPixels(*((SIZE *)wParam),
|
||||
*((SIZE *)lParam));
|
||||
case WM_AWT_CREATE_PRINTED_PIXELS: {
|
||||
CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam;
|
||||
SIZE loc = { cpps->srcx, cpps->srcy };
|
||||
SIZE size = { cpps->srcw, cpps->srch };
|
||||
retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha);
|
||||
mr = mrConsume;
|
||||
break;
|
||||
}
|
||||
case WM_UNDOCUMENTED_CLICKMENUBAR:
|
||||
{
|
||||
if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
|
||||
@ -4526,18 +4531,20 @@ void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)
|
||||
|
||||
void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
|
||||
{
|
||||
if (bitmapBits) {
|
||||
DWORD* dest = (DWORD*)bitmapBits;
|
||||
//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;
|
||||
}
|
||||
if (!bitmapBits) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD* dest = (DWORD*)bitmapBits;
|
||||
//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);
|
||||
|
||||
if (!::IsWindowVisible(GetHWnd())) {
|
||||
@ -4549,12 +4556,12 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
|
||||
return NULL;
|
||||
}
|
||||
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);
|
||||
SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);
|
||||
|
||||
RECT eraseR = { 0, 0, size.cx, size.cy };
|
||||
VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
|
||||
FillBackground(hMemoryDC, size);
|
||||
|
||||
VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));
|
||||
|
||||
@ -4562,6 +4569,14 @@ jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size) {
|
||||
// above.
|
||||
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);
|
||||
|
||||
BITMAPINFO bmi;
|
||||
@ -5937,10 +5952,6 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param)
|
||||
|
||||
CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param;
|
||||
jobject self = cpps->component;
|
||||
jint srcx = cpps->srcx;
|
||||
jint srcy = cpps->srcy;
|
||||
jint srcw = cpps->srcw;
|
||||
jint srch = cpps->srch;
|
||||
|
||||
jintArray result = NULL;
|
||||
AwtComponent *c = NULL;
|
||||
@ -5950,12 +5961,7 @@ jintArray AwtComponent::_CreatePrintedPixels(void *param)
|
||||
c = (AwtComponent *)pData;
|
||||
if (::IsWindow(c->GetHWnd()))
|
||||
{
|
||||
SIZE loc = { srcx, srcy };
|
||||
SIZE size = { srcw, srch };
|
||||
|
||||
result = (jintArray)
|
||||
c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)&loc,
|
||||
(LPARAM)&size);
|
||||
result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0);
|
||||
}
|
||||
ret:
|
||||
env->DeleteGlobalRef(self);
|
||||
@ -6749,7 +6755,7 @@ Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis)
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL
|
||||
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;
|
||||
|
||||
@ -6761,6 +6767,7 @@ Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,
|
||||
cpps->srcy = srcY;
|
||||
cpps->srcw = srcW;
|
||||
cpps->srch = srcH;
|
||||
cpps->alpha = alpha;
|
||||
|
||||
jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall(
|
||||
(void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps);
|
||||
|
||||
@ -596,7 +596,7 @@ public:
|
||||
|
||||
void UpdateColorModel();
|
||||
|
||||
jintArray CreatePrintedPixels(SIZE &loc, SIZE &size);
|
||||
jintArray CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha);
|
||||
|
||||
/*
|
||||
* HWND, AwtComponent and Java Peer interaction
|
||||
@ -738,7 +738,6 @@ protected:
|
||||
virtual void SetDragCapture(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 FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
|
||||
|
||||
|
||||
@ -464,7 +464,7 @@ void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
|
||||
size_t length = env->GetStringLength(javaWarningString) + 1;
|
||||
warningString = new WCHAR[length];
|
||||
env->GetStringRegion(javaWarningString, 0,
|
||||
static_cast<jsize>(length - 1), warningString);
|
||||
static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString));
|
||||
warningString[length-1] = L'\0';
|
||||
|
||||
env->DeleteLocalRef(javaWarningString);
|
||||
@ -2651,20 +2651,6 @@ void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
|
||||
::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
|
||||
* which was backed-out to avoid 5059656
|
||||
|
||||
@ -343,11 +343,6 @@ protected:
|
||||
BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */
|
||||
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() {
|
||||
return warningString != NULL;
|
||||
}
|
||||
|
||||
82
jdk/test/javax/swing/JComponent/6683775/bug6683775.java
Normal file
82
jdk/test/javax/swing/JComponent/6683775/bug6683775.java
Normal file
@ -0,0 +1,82 @@
|
||||
/* @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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
<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>
|
||||
44
jdk/test/javax/swing/JInternalFrame/6726866/bug6726866.java
Normal file
44
jdk/test/javax/swing/JInternalFrame/6726866/bug6726866.java
Normal file
@ -0,0 +1,44 @@
|
||||
/* @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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user