1 /* ErrorPainter.java 2 Copyright (C) 2012 Red Hat, Inc. 3 4 This file is part of IcedTea. 5 6 IcedTea is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 IcedTea is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with IcedTea; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 package net.sourceforge.jnlp.splashscreen.impls.defaultsplashscreen2012; 38 39 import java.awt.Color; 40 import java.awt.Font; 41 import java.awt.FontMetrics; 42 import java.awt.Graphics; 43 import java.awt.Graphics2D; 44 import java.awt.Point; 45 import java.awt.RenderingHints; 46 import java.util.Observable; 47 48 import net.sourceforge.jnlp.runtime.Translator; 49 import net.sourceforge.jnlp.splashscreen.parts.BasicComponentSplashScreen; 50 import net.sourceforge.jnlp.splashscreen.parts.InformationElement; 51 import net.sourceforge.jnlp.splashscreen.parts.extensions.ExtensionManager; 52 import net.sourceforge.jnlp.util.logging.OutputController; 53 54 public final class ErrorPainter extends BasePainter { 55 56 //colors 57 private static final Color TEA_DEAD_COLOR = Color.darkGray; 58 private static final Color BACKGROUND_DEAD_COLOR = Color.gray; 59 private static final Color TEA_LEAFS_STALKS_DEAD_COLOR = new Color(100, 100, 100); 60 private static final Color PLUGIN_DEAD_COLOR = Color.darkGray; 61 private static final Color WATER_DEAD_COLOR = Color.darkGray; 62 private static final Color PLAIN_TEXT_DEAD_COLOR = Color.white; 63 private static final String ERROR_MESSAGE_KEY = "SPLASHerror"; 64 private static final String ERROR_FLY_MESSAGE_KEY = "SPLASH_ERROR"; 65 private static final Color ERROR_FLY_COLOR = Color.red; 66 //for clicking ot error message 67 private Point errorCorner = null; 68 private boolean errorIsFlying = false; 69 private int errorFlyPercentage = 100; 70 71 /** 72 * Interpolation is root ratior is r= (currentSize / origSize) 73 * then value to-from is interpolaed from to to from accroding to ratio 74 * 75 * @param origSize 76 * @param currentSize 77 * @param from 78 * @param to 79 * @return interpolated value 80 */ interpol(double origSize, double currentSize, double from, double to)81 public static double interpol(double origSize, double currentSize, double from, double to) { 82 return getRatio(origSize, currentSize) * (to - from) + from; 83 } 84 85 /** 86 * is interpolating one color to another based on ration current/orig 87 * Each (r,g,b,a) part of color is interpolated separately 88 * resturned is new color composed form new r,g,b,a 89 * @param origSize 90 * @param currentSize 91 * @param from 92 * @param to 93 * @return interpolated {@link Color} 94 */ interpolateColor(double origSize, double currentSize, Color from, Color to)95 public static Color interpolateColor(double origSize, double currentSize, Color from, Color to) { 96 double r = interpol(origSize, currentSize, to.getRed(), from.getRed()); 97 double g = interpol(origSize, currentSize, to.getGreen(), from.getGreen()); 98 double b = interpol(origSize, currentSize, to.getBlue(), from.getBlue()); 99 double a = interpol(origSize, currentSize, to.getAlpha(), from.getAlpha()); 100 return new Color((int) r, (int) g, (int) b, (int) a); 101 } 102 //scaling end 103 ErrorPainter(BasicComponentSplashScreen master)104 public ErrorPainter(BasicComponentSplashScreen master) { 105 this(master, false); 106 } 107 ErrorPainter(BasicComponentSplashScreen master, boolean startScream)108 public ErrorPainter(BasicComponentSplashScreen master, boolean startScream) { 109 super(master); 110 if (startScream) { 111 startErrorScream(); 112 } 113 114 } 115 startErrorScream()116 public void startErrorScream() { 117 errorIsFlying = true; 118 getFlyingRedErrorTextThread().start(); 119 } 120 121 @Override paint(Graphics g)122 public void paint(Graphics g) { 123 Graphics2D g2d = (Graphics2D) g; 124 ensurePrerenderedStuff(); 125 if (errorIsFlying) { 126 paintStillTo(g2d, master.getInformationElement(), master.getVersion()); 127 } else { 128 if (prerenderedStuff != null) { 129 g2d.drawImage(prerenderedStuff, 0, 0, null); 130 } 131 } 132 133 if (super.showNiceTexts) { 134 ExtensionManager.getExtension().paint(g, this); 135 paintNiceTexts(g2d); 136 } else { 137 paintPlainTexts(g2d); 138 } 139 140 if (errorIsFlying) { 141 g2d.setClip(0, 0, master.getSplashWidth(), master.getSplashHeight()); 142 drawBigError(g2d); 143 } 144 145 146 } 147 drawBigError(Graphics2D g2d)148 private void drawBigError(Graphics2D g2d) { 149 Font f = new Font("Serif", Font.PLAIN, (int) scale(100, errorFlyPercentage, master.getSplashHeight())); 150 g2d.setColor(ERROR_FLY_COLOR); 151 g2d.setFont(f); 152 drawTextAroundCenter(g2d, 0, geFlyingErrorMessage()); 153 } 154 getErrorCorner()155 public Point getErrorCorner() { 156 return errorCorner; 157 } 158 setColors()159 private void setColors() { 160 161 teaColor = TEA_DEAD_COLOR; 162 backgroundColor = BACKGROUND_DEAD_COLOR; 163 teaLeafsStalksColor = TEA_LEAFS_STALKS_DEAD_COLOR; 164 pluginColor = PLUGIN_DEAD_COLOR; 165 waterColor = WATER_DEAD_COLOR; 166 167 } 168 interpolateColor(int origSize, int currentSize)169 private void interpolateColor(int origSize, int currentSize) { 170 teaColor = interpolateColor(origSize, currentSize, TEA_LIVE_COLOR, TEA_DEAD_COLOR); 171 backgroundColor = interpolateColor(origSize, currentSize, BACKGROUND_LIVE_COLOR, BACKGROUND_DEAD_COLOR); 172 teaLeafsStalksColor = interpolateColor(origSize, currentSize, TEA_LEAFS_STALKS_LIVE_COLOR, TEA_LEAFS_STALKS_DEAD_COLOR); 173 pluginColor = interpolateColor(origSize, currentSize, PLUGIN_LIVE_COLOR, PLUGIN_DEAD_COLOR); 174 waterColor = interpolateColor(origSize, currentSize, WATER_LIVE_COLOR, WATER_DEAD_COLOR); 175 plainTextColor = interpolateColor(origSize, currentSize, PLAIN_TEXT_LIVE_COLOR, PLAIN_TEXT_DEAD_COLOR); 176 } 177 178 @Override paintStillTo(Graphics2D g2d, InformationElement ic, String version)179 protected void paintStillTo(Graphics2D g2d, InformationElement ic, String version) { 180 RenderingHints r = g2d.getRenderingHints(); 181 FontMetrics fm = drawBase(g2d, ic, version); 182 drawError(g2d, ic, version, fm); 183 g2d.setRenderingHints(r); 184 } 185 getErrorMessage()186 private String getErrorMessage() { 187 String localised = Translator.R(ERROR_MESSAGE_KEY); 188 //if (localised==null)return errorMessage; 189 return localised; 190 } 191 geFlyingErrorMessage()192 private String geFlyingErrorMessage() { 193 String localised = Translator.R(ERROR_FLY_MESSAGE_KEY); 194 return localised; 195 } 196 getFlyingRedErrorTextThread()197 private Thread getFlyingRedErrorTextThread() { 198 // Create a new thread to draw big flying error in case of failure 199 Thread t = new Thread(new FlyingRedErrorTextRunner(this)); 200 //t.setDaemon(true); 201 return t; 202 } 203 204 private final class FlyingRedErrorTextRunner extends Observable implements Runnable { 205 206 private static final int FLYING_ERROR_PERCENTAGE_INCREMENT = -3; 207 private static final int FLYING_ERROR_PERCENTAGE_MINIMUM = 5; 208 private static final int FLYING_ERROR_PERCENTAGE_LOWER_BOUND = 80; 209 private static final int FLYING_ERROR_PERCENTAGE_UPPER_BOUND = 90; 210 private static final int FLYING_ERROR_DELAY = 75; 211 FlyingRedErrorTextRunner(ErrorPainter o)212 private FlyingRedErrorTextRunner(ErrorPainter o) { 213 this.addObserver(o); 214 } 215 216 @Override run()217 public void run() { 218 try { 219 while (errorIsFlying) { 220 errorFlyPercentage += FLYING_ERROR_PERCENTAGE_INCREMENT; 221 interpolateColor(100, errorFlyPercentage); 222 if (errorFlyPercentage <= FLYING_ERROR_PERCENTAGE_MINIMUM) { 223 errorIsFlying = false; 224 setColors(); 225 prerenderedStuff = null; 226 } 227 this.setChanged(); 228 this.notifyObservers(); 229 Thread.sleep(FLYING_ERROR_DELAY); 230 if (errorFlyPercentage < FLYING_ERROR_PERCENTAGE_UPPER_BOUND 231 && errorFlyPercentage > FLYING_ERROR_PERCENTAGE_LOWER_BOUND) { 232 clearCachedWaterTextImage(); 233 canWave = false; 234 } 235 } 236 } catch (Exception e) { 237 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e); 238 } finally { 239 canWave = true; 240 errorIsFlying = false; 241 setColors(); 242 prerenderedStuff = null; 243 master.repaint(); 244 245 } 246 } 247 }; 248 drawError(Graphics2D g2d, InformationElement ic, String version, FontMetrics fm)249 private void drawError(Graphics2D g2d, InformationElement ic, String version, FontMetrics fm) { 250 int minh = fm.getHeight(); 251 int minw = fm.stringWidth(getErrorMessage()); 252 int space = 5; 253 g2d.setColor(backgroundColor); 254 errorCorner = new Point(master.getSplashWidth() - space * 4 - minw, master.getSplashHeight() - space * 4 - minh); 255 if (errorCorner.x < 0) { 256 errorCorner.x = 0; 257 } 258 g2d.fillRect(errorCorner.x, errorCorner.y, space * 4 + minw, space * 4 + minh); 259 g2d.setColor(plainTextColor); 260 g2d.drawRect(errorCorner.x + space, errorCorner.y + space, space * 2 + minw, space * 2 + minh); 261 g2d.drawString(getErrorMessage(), errorCorner.x + 2 * space, errorCorner.y + 5 * space); 262 } 263 } 264