1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright (c) 2000 by Sun Microsystems, Inc. 26 * All rights reserved. 27 */ 28 29 /* 30 * Copyright (C) 1996 Active Software, Inc. 31 * All rights reserved. 32 * 33 * @(#) ImageLabel.java 1.30 - last change made 07/25/97 34 */ 35 36 package sunsoft.jws.visual.rt.awt; 37 38 import sunsoft.jws.visual.rt.base.Global; 39 import sunsoft.jws.visual.rt.base.DesignerAccess; 40 import java.awt.*; 41 import java.awt.image.RGBImageFilter; 42 import java.awt.image.FilteredImageSource; 43 44 /** 45 * An image label. It greys itself out when disabled. 46 * 47 * @(#) @(#) ImageLabel.java 1.30 - last change made 07/25/97 48 */ 49 public class ImageLabel extends Canvas { 50 /** 51 * The original image set in the constructor or in setImage(). 52 */ 53 protected Image origImg; 54 55 /** 56 * The massaged image (after the win95 work-around.) 57 */ 58 protected Image upImg; 59 60 /* BEGIN JSTYLED */ 61 /** 62 * The image to use when the component is disabled. 63 * This is the upImg 64 * stippled with the background color. 65 */ 66 /* END JSTYLED */ 67 protected Image disImg; 68 69 protected int padWidth = 0; 70 protected int defaultWidth; 71 protected int defaultHeight; 72 protected int imgWidth = -1; 73 protected int imgHeight = -1; 74 ImageLabel(Image img)75 public ImageLabel(Image img) { 76 this(img, 20, 20); 77 } 78 ImageLabel(Image img, int w, int h)79 public ImageLabel(Image img, int w, int h) { 80 origImg = img; 81 upImg = null; 82 disImg = null; 83 defaultWidth = w; 84 defaultHeight = h; 85 } 86 setPadWidth(int w)87 public void setPadWidth(int w) { 88 padWidth = w; 89 repaint(); 90 } 91 getPadWidth()92 public int getPadWidth() { 93 return (padWidth); 94 } 95 setDefaultWidth(int w)96 public void setDefaultWidth(int w) { 97 if (w <= 0) 98 return; 99 defaultWidth = w; 100 } 101 getDefaultWidth()102 public int getDefaultWidth() { 103 return defaultWidth; 104 } 105 setDefaultHeight(int h)106 public void setDefaultHeight(int h) { 107 if (h <= 0) 108 return; 109 defaultHeight = h; 110 } 111 getDefaultHeight()112 public int getDefaultHeight() { 113 return defaultHeight; 114 } 115 setUpImages()116 private void setUpImages() { 117 if (origImg != null && upImg == null) { 118 disImg = null; 119 imgWidth = -1; 120 imgHeight = -1; 121 122 if (getBackground() != null) { 123 upImg = origImg; 124 125 // WORK-AROUND: create an image filter 126 // for transparent gifs on Win95 127 if (Global.isWindows95() && Global.javaVersion() == 128 1.0) { 129 RGBImageFilter wfilter = new TransWorkAroundFilter( 130 getBackground()); 131 upImg = createImage(new FilteredImageSource( 132 upImg.getSource(), 133 wfilter)); 134 } 135 136 // start the loading of the main image 137 prepareImage(upImg, this); 138 139 // width and height might be immediately 140 // available if already loaded 141 imgWidth = upImg.getWidth(this); 142 imgHeight = upImg.getHeight(this); 143 } 144 } else { 145 imgWidth = defaultWidth; 146 imgHeight = defaultHeight; 147 } 148 149 if (origImg != null && disImg == null && 150 getBackground() != null) { 151 // create a checkerboard image for disabled 152 // version of the button 153 RGBImageFilter filter = new CheckerboardFilter( 154 getBackground()); 155 disImg = createImage(new FilteredImageSource( 156 origImg.getSource(), filter)); 157 } 158 } 159 setImage(Image img)160 public void setImage(Image img) { 161 origImg = img; 162 upImg = null; 163 disImg = null; 164 setUpImages(); 165 repaint(); 166 } 167 getImage()168 public Image getImage() { 169 return (origImg); 170 } 171 minimumSize()172 public Dimension minimumSize() { 173 if (upImg != null) { 174 if (imgWidth == -1 || imgHeight == -1) { 175 imgWidth = upImg.getWidth(this); 176 imgHeight = upImg.getHeight(this); 177 } 178 179 if (imgWidth == -1 || imgHeight == -1) 180 return (new Dimension(defaultWidth + padWidth * 2, 181 defaultHeight + padWidth * 2)); 182 else 183 return (new Dimension(imgWidth + padWidth * 2, 184 imgHeight + padWidth * 2)); 185 } else { 186 // return(new Dimension(0, 0)); 187 return (new Dimension(20, 20)); 188 } 189 } 190 preferredSize()191 public Dimension preferredSize() { 192 return minimumSize(); 193 } 194 195 /** 196 * Overrides Component setBackground in order to redo the images, 197 * because of the transparent gif workaround and also because the 198 * disabled image relies on the background color. 199 */ setBackground(Color bg)200 public void setBackground(Color bg) { 201 super.setBackground(bg); 202 if (upImg != null) { 203 // this isn't just a work-around for Win95, 204 // but on ALL platforms 205 // the disabled image must be redone when 206 // the background color changes 207 upImg = null; 208 disImg = null; 209 setUpImages(); 210 } 211 } 212 /* BEGIN JSTYLED */ 213 /* Invalidate all of a component's containers and then validate the 214 * Window at the top. Call this when the size of a component 215 * changes and you wish to make the window that contains it resize 216 * to accomodate the new size. 217 */ 218 /* END JSTYLED */ updateWindow(Component c)219 protected void updateWindow(Component c) { 220 while (c != null) { 221 c.invalidate(); 222 if (c instanceof Window) { 223 c.validate(); 224 break; 225 } 226 c = c.getParent(); 227 } 228 } 229 230 /** 231 * Figures out if this component needs to be resized. 232 */ updateSize(int w, int h)233 protected void updateSize(int w, int h) { 234 if (w >= 0 && h >= 0) { 235 Dimension d = size(); 236 if (d.width != w + padWidth * 2 || d.height != h + 237 padWidth * 2) { 238 resize(w + padWidth * 2, h + padWidth * 2); 239 updateWindow(this); 240 } 241 } 242 } 243 244 /** 245 * By overriding update we insure that this component won't be 246 * completely cleared with the background color each time it's 247 * updated (while loading.) We'd like less flickering than that. 248 */ update(Graphics g)249 public void update(Graphics g) { 250 if (Global.isWindows()) 251 g = getGraphics(); 252 synchronized (DesignerAccess.mutex) { 253 g.setColor(getBackground()); 254 Dimension d = size(); 255 if (upImg != null && (imgWidth >= 0 && imgHeight >= 0)) { 256 // clear only the areas around the image (to 257 // avoid having the image 258 // flicker as it is loaded scanline-by-scanline) 259 int x = (d.width - imgWidth) / 2; 260 int y = (d.height - imgHeight) / 2; 261 if (x > 0) 262 g.fillRect(0, 0, x, d.height); 263 if (y > 0) 264 g.fillRect(0, 0, d.width, y); 265 if (d.width > imgWidth) 266 g.fillRect(x + imgWidth, 0, d.width - (x 267 + imgWidth), d.height); 268 if (d.height > imgHeight) 269 g.fillRect(0, y + imgHeight, d.width, 270 d.height - (y + imgHeight)); 271 } else { 272 // there is no image, so clear the whole area 273 g.fillRect(0, 0, d.width, d.height); 274 } 275 g.setColor(getForeground()); 276 } 277 paint(g); 278 } 279 280 /* BEGIN JSTYLED */ 281 /** 282 * Draw the image in the center of the available area. 283 * No background 284 * clearing is done here (that job belongs to update().) 285 */ 286 /* END JSTYLED */ paint(Graphics g)287 public void paint(Graphics g) { 288 if (Global.isWindows()) 289 g = getGraphics(); 290 synchronized (DesignerAccess.mutex) { 291 Dimension d = size(); 292 if (upImg != null && (imgWidth >= 0 && imgHeight >= 0)) { 293 Image img = isEnabled() ? upImg : disImg; 294 int x = (d.width - imgWidth) / 2; 295 int y = (d.height - imgHeight) / 2; 296 g.drawImage(img, x, y, getBackground(), this); 297 } else { 298 g.setColor(getForeground()); 299 g.drawRect(0, 0, d.width-1, d.height-1); 300 } 301 } 302 } 303 imageUpdate(Image img, int flags, int x, int y, int w, int h)304 public boolean imageUpdate(Image img, int flags, 305 int x, int y, int w, int h) { 306 307 if (img == upImg && (flags & ERROR) == 0) { 308 boolean updateSize = false; 309 310 if ((flags & WIDTH) != 0) { 311 imgWidth = w; 312 updateSize = true; 313 } 314 if ((flags & HEIGHT) != 0) { 315 imgHeight = h; 316 updateSize = true; 317 } 318 319 if (updateSize && imgWidth >= 0 && imgHeight >= 0) { 320 // As soon as the size is known this 321 // component needs to resize itself. 322 updateSize(imgWidth, imgHeight); 323 324 // This repaint is needed for images 325 // that are already loaded, and 326 // are being loaded a second time. 327 // In this situation, the 328 // update for the width and height comes 329 // in after all the other 330 // updates. The call to super.imageUpdate 331 // does not do a repaint 332 // when the size changes, so we need to do one here. 333 repaint(); 334 } 335 } 336 337 return super.imageUpdate(img, flags, x, y, w, h); 338 } 339 enable()340 public void enable() { 341 if (!isEnabled()) { 342 super.enable(); 343 repaint(); 344 } 345 } 346 disable()347 public void disable() { 348 if (isEnabled()) { 349 super.disable(); 350 repaint(); 351 } 352 } 353 addNotify()354 public void addNotify() { 355 super.addNotify(); 356 setUpImages(); 357 } 358 } 359 360 361 /** 362 * A Work-around filter. 363 * 364 * Transparent gifs don't display properly on Windows 95. 365 * The work-around 366 * is to replace transparent pixels with the background color of the 367 * component they're being displayed in before drawing them. 368 */ 369 class TransWorkAroundFilter extends RGBImageFilter { 370 private Color bg; 371 TransWorkAroundFilter(Color bg)372 TransWorkAroundFilter(Color bg) { 373 if (bg != null) { 374 this.bg = bg; 375 canFilterIndexColorModel = false; 376 } else { 377 throw new Error( 378 /* JSTYLED */ 379 Global.fmtMsg("sunsoft.jws.visual.rt.awt.ImageLabel.nullColor", "TransWorkAroundFilter")); 380 } 381 } 382 filterRGB(int x, int y, int rgb)383 public int filterRGB(int x, int y, int rgb) { 384 if ((rgb & 0xff000000) == 0) 385 return (bg.getRGB()); 386 else 387 return (rgb); 388 } 389 } 390 391 392 /** 393 * Checkerboard color filter. 394 * 395 * Use for creating a greyed-out version of another image. Supply the 396 * color for the checkerboard spaces. Every other pixel will still be 397 * in the original color of the image. 398 */ 399 class CheckerboardFilter extends RGBImageFilter { 400 private Color checked; 401 CheckerboardFilter(Color checked)402 CheckerboardFilter(Color checked) { 403 if (checked != null) { 404 this.checked = checked; 405 canFilterIndexColorModel = false; 406 } else { 407 throw new Error( 408 /* JSTYLED */ 409 Global.fmtMsg("sunsoft.jws.visual.rt.awt.ImageLabel.nullColor", "CheckerboardFilter")); 410 } 411 } 412 filterRGB(int x, int y, int rgb)413 public int filterRGB(int x, int y, int rgb) { 414 if (y % 2 == x % 2) 415 return (rgb); 416 else 417 return (checked.getRGB()); 418 } 419 } 420