1 19 20 package org.netbeans.core.windows.view.ui.slides; 21 22 import java.awt.AlphaComposite ; 23 import java.awt.BorderLayout ; 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import java.awt.Composite ; 27 import java.awt.Container ; 28 import java.awt.Dimension ; 29 import java.awt.Graphics ; 30 import java.awt.Graphics2D ; 31 import java.awt.GraphicsEnvironment ; 32 import java.awt.Image ; 33 import java.awt.Rectangle ; 34 import java.awt.event.ActionEvent ; 35 import java.awt.event.ActionListener ; 36 import java.awt.geom.AffineTransform ; 37 import java.awt.image.BufferedImage ; 38 import javax.swing.CellRendererPane ; 39 import javax.swing.JButton ; 40 import javax.swing.JComponent ; 41 import javax.swing.JLayeredPane ; 42 import javax.swing.JPanel ; 43 import javax.swing.SwingUtilities ; 44 import javax.swing.Timer ; 45 import javax.swing.event.ChangeListener ; 46 47 52 final class ScaleFx implements SlidingFx, ActionListener { 53 54 private float initialAlpha = 0.1f; 55 private float finishAlpha = 0.9f; 56 57 private int iterCount = 9; 58 59 private int curIter = 0; 60 61 private static final float DIVIDING_FACTOR = 2.0f; 62 63 private static final int FRAME_DELAY = 20; 64 65 private Rectangle middle = new Rectangle (); 66 private Rectangle current = new Rectangle (); 67 68 private Timer timer = null; 69 70 private StretchedImageComp stretchedImage = new StretchedImageComp(); 71 72 private Rectangle [] path; 73 74 private JLayeredPane pane; 75 76 private SlideOperation operation; 77 78 private Image preparedImage; 79 80 private ChangeListener finishL; 81 82 private final boolean shouldOperationWait; 83 84 public ScaleFx(float initialAlpha, float finishAlpha, boolean shouldOperationWait) { 85 setTransparency(initialAlpha, finishAlpha); 86 this.shouldOperationWait = shouldOperationWait; 87 } 88 89 public void prepareEffect(SlideOperation operation) { 90 Component comp = operation.getComponent(); 91 preparedImage = createCompImage(operation.getComponent(), operation.getComponent().getSize()); 92 } 93 94 public void showEffect(JLayeredPane pane, Integer layer, SlideOperation operation) { 95 this.pane = pane; 96 this.operation = operation; 97 Component comp = operation.getComponent(); 98 Graphics2D gr2d = (Graphics2D )pane.getGraphics(); 99 Rectangle start = operation.getStartBounds(); 100 Rectangle finish = operation.getFinishBounds(); 101 Dimension finishSize = finish.getSize(); 102 Dimension startSize = start.getSize(); 103 Rectangle current = start; 104 Image compImage = preparedImage; 105 106 113 pane.add(stretchedImage, layer); 114 115 path = computePath(start, finish); 116 117 curIter = 1; 118 if (compImage != null) { 119 stretchedImage.setOrigImage(compImage); 120 } else { 121 if (finishSize.width * finishSize.height > startSize.width * startSize.height) { 122 stretchedImage.setComp(comp, finishSize); 123 } else { 124 stretchedImage.setComp(comp, startSize); 125 } 126 } 127 stretchedImage.setBoundsAndAlpha(start, initialAlpha); 128 129 getTimer().start(); 130 } 131 132 public void actionPerformed(ActionEvent e) { 133 float coef = (float)curIter / (float)(iterCount - 1); 134 float curAlpha = (1 - coef) * initialAlpha + coef * finishAlpha; 135 136 stretchedImage.setBoundsAndAlpha(path[curIter], curAlpha); 137 138 curIter++; 139 140 if (curIter >= iterCount) { 141 getTimer().stop(); 142 finish(); 143 } 144 } 145 146 private void finish () { 147 pane.remove(stretchedImage); 148 stretchedImage.cleanup(); 149 if (finishL != null) { 151 finishL.stateChanged(null); 152 } 153 } 154 155 public void setTransparency(float initialAlpha, float finishAlpha) { 156 this.initialAlpha = initialAlpha; 157 this.finishAlpha = finishAlpha; 158 } 159 160 private void setSuggestedIterations(int count) { 161 if (count < 3) { 162 count = 3; 163 } 164 this.iterCount = count % 2 == 0 ? count + 1 : count; 166 } 167 168 private Rectangle [] computePath(Rectangle start, Rectangle finish) { 169 Rectangle [] path = new Rectangle [iterCount]; 170 171 middle.x = Math.abs((finish.x + start.x) / 2); 172 middle.y = Math.abs((finish.y + start.y) / 2); 173 middle.width = Math.abs((finish.width + start.width) / 2); 174 middle.height = Math.abs((finish.height + start.height) / 2); 175 176 current = new Rectangle (middle); 177 for (int i = iterCount / 2 - 1; i >= 0; i--) { 178 current.x = (int)Math.abs((current.x + start.x) / DIVIDING_FACTOR); 179 current.y = (int)Math.abs((current.y + start.y) / DIVIDING_FACTOR); 180 current.width = (int)Math.abs((current.width + start.width) / DIVIDING_FACTOR); 181 current.height = (int)Math.abs((current.height + start.height) / DIVIDING_FACTOR); 182 path[i] = new Rectangle (current); 183 } 184 path[iterCount / 2] = new Rectangle (middle); 185 current = middle; 186 for (int i = iterCount / 2 + 1; i < iterCount; i++) { 187 current.x = (int)Math.abs((current.x + finish.x) / DIVIDING_FACTOR); 188 current.y = (int)Math.abs((current.y + finish.y) / DIVIDING_FACTOR); 189 current.width = (int)Math.abs((current.width + finish.width) / DIVIDING_FACTOR); 190 current.height = (int)Math.abs((current.height + finish.height) / DIVIDING_FACTOR); 191 path[i] = new Rectangle (current); 192 } 193 194 return path; 195 } 196 197 private Image createCompImage(Component comp, Dimension targetSize) { 198 if (!comp.isShowing()) { 201 return null; 202 } 203 204 Image image = comp.createImage(comp.getWidth(), comp.getHeight()); 205 206 209 211 Graphics2D gr2d = (Graphics2D )image.getGraphics(); 212 213 comp.paint(gr2d); 214 215 gr2d.dispose(); 216 217 return image; 218 } 219 220 259 260 private Timer getTimer () { 261 if (timer == null) { 262 timer = new Timer (FRAME_DELAY, this); 263 timer.setRepeats(true); 264 } 265 return timer; 266 } 267 268 public void setFinishListener(ChangeListener finishL) { 269 this.finishL = finishL; 270 } 271 272 public boolean shouldOperationWait() { 273 return shouldOperationWait; 274 } 275 276 277 private class StretchedImageComp extends JComponent { 280 281 private Image origImage; 282 283 private float alpha = 1.0f; 284 285 private Component comp; 286 287 private Dimension scaleSource, targetSize; 288 289 public void setComp(Component comp, Dimension targetSize) { 290 this.comp = comp; 291 this.targetSize = targetSize; 292 } 293 294 public void setOrigImage(Image origImage) { 295 this.origImage = origImage; 296 } 297 298 public void setScaleSource(Dimension scaleSource) { 299 this.scaleSource = scaleSource; 300 } 301 302 public void setBoundsAndAlpha(Rectangle bounds, float alpha) { 303 this.alpha = alpha; 304 setBounds(bounds); 305 if (origImage == null) { 306 origImage = tryCreateImage(); 307 } 308 } 309 310 private Image tryCreateImage () { 311 Image result = null; 312 if (comp != null && isDisplayable()) { 313 comp.setSize(targetSize); 314 add(comp); 315 result = createCompImage(comp, targetSize); 316 remove(comp); 317 } 318 return result; 319 } 320 321 public void cleanup() { 322 comp = null; 323 origImage = null; 324 scaleSource = null; 325 targetSize = null; 326 } 327 328 public void paint(Graphics g) { 329 Rectangle bounds = getBounds(); 330 331 if (origImage == null) { 332 if (comp == null) { 333 return; 334 } 335 origImage = tryCreateImage(); 336 if (origImage == null) { 337 return; 338 } 339 } 340 Image img = origImage; 341 Graphics2D g2d = (Graphics2D ) g; 342 Composite origComposite = g2d.getComposite(); 343 g2d.setComposite (AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 344 348 g2d.drawImage(img, 0, 0, bounds.width, bounds.height, null); 349 352 if (origComposite != null) { 353 g2d.setComposite(origComposite); 354 } 355 } 356 357 358 } 360 361 } 362 | Popular Tags |