From ac4ec9c390b9786a3a3814201520c2485d008872 Mon Sep 17 00:00:00 2001 From: Branislav Stojkovic Date: Mon, 24 Oct 2016 21:26:28 +0200 Subject: [PATCH] use volatile image to optimize --- .../cloud/view/browser/CloudGlassPane.java | 82 +++++++++++++------ 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java index 8bd22d15..c0efa715 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/CloudGlassPane.java @@ -3,7 +3,10 @@ package org.diylc.swing.plugins.cloud.view.browser; import java.awt.Color; import java.awt.Cursor; import java.awt.FontMetrics; +import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; @@ -13,6 +16,7 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.awt.image.VolatileImage; import javax.swing.JPanel; import javax.swing.Timer; @@ -32,15 +36,21 @@ public class CloudGlassPane extends JPanel implements MouseListener, KeyListener private long startTime; private final int msPerPx = 6; + private final Color bgColor = new Color(192, 222, 237); private Timer animationTimer; + private VolatileImage volatileImg; + public CloudGlassPane() { addKeyListener(this); addMouseListener(this); setCursor(new Cursor(Cursor.WAIT_CURSOR)); setOpaque(false); - setBackground(new Color(192, 222, 237)); + setBackground(bgColor); + + setLayout(new GridBagLayout()); + animationTimer = new Timer(20, new ActionListener() { @@ -61,34 +71,60 @@ public class CloudGlassPane extends JPanel implements MouseListener, KeyListener super.setVisible(aFlag); }; + private void createBackBuffer() { + GraphicsConfiguration gc = getGraphicsConfiguration(); + volatileImg = gc.createCompatibleVolatileImage(getWidth(), getHeight()); + } + @Override public void paint(java.awt.Graphics g) { - Graphics2D g2d = (Graphics2D) g; - // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); - Image cloud = IconLoader.CloudBg.getImage(); + createBackBuffer(); - g2d.setColor(new Color(192, 222, 237)); - g2d.fillRect(0, cloud.getHeight(null), getWidth(), getHeight()); + do { - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - long ellapsed = System.currentTimeMillis() - startTime; - long dx = (ellapsed / msPerPx) % cloud.getWidth(null); - g2d.drawImage(cloud, -(int) dx, 0, null); - if (cloud.getWidth(null) - dx < getWidth()) { - g2d.drawImage(cloud, (int) (cloud.getWidth(null) - dx), 0, null); - } + // Validate the volatile image for the graphics configuration of this + // component. If the volatile image doesn't apply for this graphics configuration + // (in other words, the hardware acceleration doesn't apply for the new device) + // then we need to re-create it. + GraphicsConfiguration gc = this.getGraphicsConfiguration(); + int valCode = volatileImg.validate(gc); - g2d.setColor(Color.white); - g2d.setFont(g2d.getFont().deriveFont(22f)); - String text = "Querying the cloud, please hold on..."; - FontMetrics metrics = g.getFontMetrics(g2d.getFont()); - Rectangle rect = new Rectangle(getSize()); - int x = (rect.width - metrics.stringWidth(text)) / 2; - int y = ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent(); - g.drawString(text, x, y); - }; + // This means the device doesn't match up to this hardware accelerated image. + if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) { + createBackBuffer(); // recreate the hardware accelerated image. + } + + Graphics offscreenGraphics = volatileImg.getGraphics(); + Graphics2D g2d = (Graphics2D) offscreenGraphics; + Image cloud = IconLoader.CloudBg.getImage(); + + g2d.setColor(bgColor); + g2d.fillRect(0, cloud.getHeight(null), getWidth(), getHeight()); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + long ellapsed = System.currentTimeMillis() - startTime; + long dx = (ellapsed / msPerPx) % cloud.getWidth(null); + g2d.drawImage(cloud, -(int) dx, 0, null); + if (cloud.getWidth(null) - dx < getWidth()) { + g2d.drawImage(cloud, (int) (cloud.getWidth(null) - dx), 0, null); + } + + g2d.setColor(Color.white); + g2d.setFont(g2d.getFont().deriveFont(22f)); + String text = "Querying the cloud, please hold on..."; + FontMetrics metrics = g.getFontMetrics(g2d.getFont()); + Rectangle rect = new Rectangle(getSize()); + int x = (rect.width - metrics.stringWidth(text)) / 2; + int y = ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent(); + g2d.drawString(text, x, y); + + // paint back buffer to main graphics + g.drawImage(volatileImg, 0, 0, this); + // Test if content is lost + } while (volatileImg.contentsLost()); + } @Override public void mouseClicked(final MouseEvent pArg0) {}