-
Bug
-
Resolution: Unresolved
-
P3
-
8, 11, 16, 17
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Edition Windows 10 Home
Version 21H1
Installed on 11/6/2020
OS build 19043.1165
Experience Windows Feature Experience Pack 120.2212.3530.0
java version "16" 2021-03-16
Java(TM) SE Runtime Environment (build 16+36-2231)
Java HotSpot(TM) 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When window background is set to a color with alpha=0, repaint calls never results in paint callback.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test case
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test case runs the same test using a background color with alpha=255; followed by a background color with alpha=0. Expect the display to update in both cases.
ACTUAL -
With background color with alpha=0, text is not updated.
---------- BEGIN SOURCE ----------
package TransparentWindow;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class TransparentWindow {
private Window window;
private Image staticImage;
private BufferedImage overlay;
private int height = 320;
private int width = 320;
private int wiggle = -10;
private int paintCount = 1;
public static void main(String[] args) {
try {
new TransparentWindow().start();
} catch ( IOException ex ) {}
}
private void start() throws IOException {
createStaticTransparentImage();
displayWindow(Color.GRAY);
displayWindow(new Color(0,0,0,0));
System.exit(0);
}
private void displayWindow(Color back) {
wiggle = -10;
paintCount = 1;
createDynamicTransparentImage();
window = new MyWindow(back);
for (int i = 0; i < 20; i++) {
sleep(250);
window.setSize(width + wiggle, height);
window.repaint();
wiggle *= -1;
}
sleep(2000);
window.dispose();
}
private void updateWindow(Graphics2D g2D) {
g2D.drawImage(staticImage, null, window);
drawMessage(g2D, "Window: Hello World! " + paintCount, 40);
Graphics2D g = overlay.createGraphics();
g.setStroke(new BasicStroke(1f));
/**Set Antialias Rendering**/
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
drawMessage(g, "Image: Hello World! " + paintCount, height - 40);
g.dispose();
g2D.drawImage(overlay, null, window);
paintCount++;
}
private void drawMessage(Graphics2D g2D, String mess, int y) {
TextLayout layout = new TextLayout(mess, g2D.getFont(), g2D.getFontRenderContext());
int mx = (width - (int)Math.ceil(layout.getAdvance())) / 2;
int my = y - (int)Math.ceil(layout.getDescent() + layout.getLeading());
int mh = (int)Math.ceil(layout.getAscent() + layout.getDescent() + layout.getLeading());
int cx = Math.max(mx - 1, 0);
int cy = my - (int)Math.ceil(layout.getAscent()) - 1;
int ch = mh + 2;
int cw = (int)Math.ceil(layout.getAdvance()) + 2;
g2D.setPaint(Color.WHITE);
g2D.fillRect(cx, cy, cw, ch);
g2D.setPaint(Color.BLACK);
g2D.drawString(mess, mx, my);
}
private void createStaticTransparentImage() {
staticImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = ((BufferedImage)staticImage).createGraphics();
g.setBackground(new Color(0,0,0,0));
g.clearRect(0, 0, width, height);
g.setPaint(Color.CYAN);
g.fillRect(0, 0, 80, 80);
g.setPaint(Color.BLUE);
g.fillRect(width - 80, 0, 80, 80);
g.setPaint(Color.GREEN);
g.fillRect(0, height - 80, 80, 80);
g.setPaint(Color.MAGENTA);
g.fillRect(width - 80, height - 80, 80, 80);
g.setPaint(Color.YELLOW);
g.fillOval((width / 2) - 40, (height / 2) - 40, 80, 80);
g.dispose();
}
private void createDynamicTransparentImage() {
overlay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = overlay.createGraphics();
g.setBackground(new Color(0,0,0,0));
g.clearRect(0, 0, width, height);
g.dispose();
}
private void sleep(int mills) {
try {
Thread.sleep(mills);
} catch ( InterruptedException ex ) {}
}
private class MyWindow extends Window {
public MyWindow(Color background) {
super(null);
setSize(width, height);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// Center window
int x = (screenSize.width - width) / 2;
int y = (screenSize.height - height) / 2;
setLocation(x, y);
// Make Window visible
setBackground(background);
setAlwaysOnTop(true);
setVisible(true);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
@Override
public void paint(Graphics g) {
super.paint(g);
updateWindow((Graphics2D)g);
}
@Override
public void update(Graphics g) {
paint(g);
}
}
}
---------- END SOURCE ----------
FREQUENCY : always
Edition Windows 10 Home
Version 21H1
Installed on 11/6/2020
OS build 19043.1165
Experience Windows Feature Experience Pack 120.2212.3530.0
java version "16" 2021-03-16
Java(TM) SE Runtime Environment (build 16+36-2231)
Java HotSpot(TM) 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When window background is set to a color with alpha=0, repaint calls never results in paint callback.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test case
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test case runs the same test using a background color with alpha=255; followed by a background color with alpha=0. Expect the display to update in both cases.
ACTUAL -
With background color with alpha=0, text is not updated.
---------- BEGIN SOURCE ----------
package TransparentWindow;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class TransparentWindow {
private Window window;
private Image staticImage;
private BufferedImage overlay;
private int height = 320;
private int width = 320;
private int wiggle = -10;
private int paintCount = 1;
public static void main(String[] args) {
try {
new TransparentWindow().start();
} catch ( IOException ex ) {}
}
private void start() throws IOException {
createStaticTransparentImage();
displayWindow(Color.GRAY);
displayWindow(new Color(0,0,0,0));
System.exit(0);
}
private void displayWindow(Color back) {
wiggle = -10;
paintCount = 1;
createDynamicTransparentImage();
window = new MyWindow(back);
for (int i = 0; i < 20; i++) {
sleep(250);
window.setSize(width + wiggle, height);
window.repaint();
wiggle *= -1;
}
sleep(2000);
window.dispose();
}
private void updateWindow(Graphics2D g2D) {
g2D.drawImage(staticImage, null, window);
drawMessage(g2D, "Window: Hello World! " + paintCount, 40);
Graphics2D g = overlay.createGraphics();
g.setStroke(new BasicStroke(1f));
/**Set Antialias Rendering**/
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
drawMessage(g, "Image: Hello World! " + paintCount, height - 40);
g.dispose();
g2D.drawImage(overlay, null, window);
paintCount++;
}
private void drawMessage(Graphics2D g2D, String mess, int y) {
TextLayout layout = new TextLayout(mess, g2D.getFont(), g2D.getFontRenderContext());
int mx = (width - (int)Math.ceil(layout.getAdvance())) / 2;
int my = y - (int)Math.ceil(layout.getDescent() + layout.getLeading());
int mh = (int)Math.ceil(layout.getAscent() + layout.getDescent() + layout.getLeading());
int cx = Math.max(mx - 1, 0);
int cy = my - (int)Math.ceil(layout.getAscent()) - 1;
int ch = mh + 2;
int cw = (int)Math.ceil(layout.getAdvance()) + 2;
g2D.setPaint(Color.WHITE);
g2D.fillRect(cx, cy, cw, ch);
g2D.setPaint(Color.BLACK);
g2D.drawString(mess, mx, my);
}
private void createStaticTransparentImage() {
staticImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = ((BufferedImage)staticImage).createGraphics();
g.setBackground(new Color(0,0,0,0));
g.clearRect(0, 0, width, height);
g.setPaint(Color.CYAN);
g.fillRect(0, 0, 80, 80);
g.setPaint(Color.BLUE);
g.fillRect(width - 80, 0, 80, 80);
g.setPaint(Color.GREEN);
g.fillRect(0, height - 80, 80, 80);
g.setPaint(Color.MAGENTA);
g.fillRect(width - 80, height - 80, 80, 80);
g.setPaint(Color.YELLOW);
g.fillOval((width / 2) - 40, (height / 2) - 40, 80, 80);
g.dispose();
}
private void createDynamicTransparentImage() {
overlay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = overlay.createGraphics();
g.setBackground(new Color(0,0,0,0));
g.clearRect(0, 0, width, height);
g.dispose();
}
private void sleep(int mills) {
try {
Thread.sleep(mills);
} catch ( InterruptedException ex ) {}
}
private class MyWindow extends Window {
public MyWindow(Color background) {
super(null);
setSize(width, height);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// Center window
int x = (screenSize.width - width) / 2;
int y = (screenSize.height - height) / 2;
setLocation(x, y);
// Make Window visible
setBackground(background);
setAlwaysOnTop(true);
setVisible(true);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
@Override
public void paint(Graphics g) {
super.paint(g);
updateWindow((Graphics2D)g);
}
@Override
public void update(Graphics g) {
paint(g);
}
}
}
---------- END SOURCE ----------
FREQUENCY : always