1 30 31 package com.jgoodies.looks.common; 32 33 import java.awt.*; 34 import java.awt.image.BufferedImage ; 35 import java.util.ArrayList ; 36 import java.util.List ; 37 38 import javax.swing.*; 39 import javax.swing.border.Border ; 40 41 53 public final class ShadowPopup extends Popup { 54 55 58 private static final int MAX_CACHE_SIZE = 5; 59 60 63 private static List cache; 64 65 68 private static final Border SHADOW_BORDER = ShadowPopupBorder.getInstance(); 69 70 73 private static final int SHADOW_SIZE = 5; 74 75 78 private static boolean canSnapshot = true; 79 80 83 private Component owner; 84 85 88 private Component contents; 89 90 93 private int x, y; 94 95 99 private Popup popup; 100 101 104 private Border oldBorder; 105 106 109 private boolean oldOpaque; 110 111 114 private Container heavyWeightContainer; 115 116 120 static Popup getInstance(Component owner, Component contents, int x, 121 int y, Popup delegate) { 122 ShadowPopup result; 123 synchronized (ShadowPopup.class) { 124 if (cache == null) { 125 cache = new ArrayList (MAX_CACHE_SIZE); 126 } 127 if (cache.size() > 0) { 128 result = (ShadowPopup) cache.remove(0); 129 } else { 130 result = new ShadowPopup(); 131 } 132 } 133 result.reset(owner, contents, x, y, delegate); 134 return result; 135 } 136 137 140 private static void recycle(ShadowPopup popup) { 141 synchronized (ShadowPopup.class) { 142 if (cache.size() < MAX_CACHE_SIZE) { 143 cache.add(popup); 144 } 145 } 146 } 147 148 public static boolean canSnapshot() { 149 return canSnapshot; 150 } 151 152 153 public void hide() { 154 JComponent parent = (JComponent) contents.getParent(); 155 popup.hide(); 156 if (parent.getBorder() == SHADOW_BORDER) { 157 parent.setBorder(oldBorder); 158 parent.setOpaque(oldOpaque); 159 oldBorder = null; 160 if (heavyWeightContainer != null) { 161 parent.putClientProperty(ShadowPopupFactory.PROP_HORIZONTAL_BACKGROUND, null); 162 parent.putClientProperty(ShadowPopupFactory.PROP_VERTICAL_BACKGROUND, null); 163 heavyWeightContainer = null; 164 } 165 } 166 owner = null; 167 contents = null; 168 popup = null; 169 recycle(this); 170 } 171 172 173 public void show() { 174 if (heavyWeightContainer != null) { 175 snapshot(); 176 } 177 popup.show(); 178 } 179 180 189 private void reset(Component owner, Component contents, int x, int y, 190 Popup popup) { 191 this.owner = owner; 192 this.contents = contents; 193 this.popup = popup; 194 this.x = x; 195 this.y = y; 196 if (owner instanceof JComboBox) { 197 return; 198 } 199 Container mediumWeightContainer = null; 200 for(Container p = contents.getParent(); p != null; p = p.getParent()) { 201 if (p instanceof JWindow) { 202 p.setBackground(contents.getBackground()); 204 heavyWeightContainer = p; 205 break; 206 } else if (p instanceof Panel) { 207 Color bg = p.getBackground(); 211 int rgba = contents.getBackground().getRGB() & 0x00ffffff; 212 if ((bg == null) || (bg.getRGB() != rgba)) { 213 p.setBackground(new Color(rgba, true)); 214 } 215 mediumWeightContainer = p; 216 break; 217 } 218 } 219 JComponent parent = (JComponent) contents.getParent(); 220 oldOpaque = parent.isOpaque(); 221 oldBorder = parent.getBorder(); 222 parent.setOpaque(false); 223 parent.setBorder(SHADOW_BORDER); 224 if (mediumWeightContainer != null) { 226 mediumWeightContainer.setSize( 227 mediumWeightContainer.getPreferredSize()); 228 } else { 229 parent.setSize(parent.getPreferredSize()); 230 } 231 } 232 233 239 private static final Point point = new Point(); 240 private static final Rectangle rect = new Rectangle(); 241 242 256 private void snapshot() { 257 try { 258 Robot robot = new Robot(); 260 Dimension size = heavyWeightContainer.getPreferredSize(); 261 int width = size.width; 262 int height = size.height; 263 264 rect.setBounds(x, y + height - SHADOW_SIZE, width, SHADOW_SIZE); 265 BufferedImage hShadowBg = robot.createScreenCapture(rect); 266 267 rect.setBounds(x + width - SHADOW_SIZE, y, SHADOW_SIZE, 268 height - SHADOW_SIZE); 269 BufferedImage vShadowBg = robot.createScreenCapture(rect); 270 271 JComponent parent = (JComponent) contents.getParent(); 272 parent.putClientProperty(ShadowPopupFactory.PROP_HORIZONTAL_BACKGROUND, hShadowBg); 273 parent.putClientProperty(ShadowPopupFactory.PROP_VERTICAL_BACKGROUND, vShadowBg); 274 275 JComponent layeredPane = getLayeredPane(); 276 if (layeredPane == null) { 277 return; 279 } 280 281 int layeredPaneWidth = layeredPane.getWidth(); 282 int layeredPaneHeight = layeredPane.getHeight(); 283 284 point.x = x; 285 point.y = y; 286 SwingUtilities.convertPointFromScreen(point, layeredPane); 287 288 rect.x = point.x; 290 rect.y = point.y + height - SHADOW_SIZE; 291 rect.width = width; 292 rect.height = SHADOW_SIZE; 293 294 if ((rect.x + rect.width) > layeredPaneWidth) { 295 rect.width = layeredPaneWidth - rect.x; 296 } 297 if ((rect.y + rect.height) > layeredPaneHeight) { 298 rect.height = layeredPaneHeight - rect.y; 299 } 300 if (!rect.isEmpty()) { 301 Graphics g = hShadowBg.createGraphics(); 302 g.translate(-rect.x, -rect.y); 303 g.setClip(rect); 304 boolean doubleBuffered = layeredPane.isDoubleBuffered(); 305 layeredPane.setDoubleBuffered(false); 306 layeredPane.paint(g); 307 layeredPane.setDoubleBuffered(doubleBuffered); 308 g.dispose(); 309 } 310 311 rect.x = point.x + width - SHADOW_SIZE; 313 rect.y = point.y; 314 rect.width = SHADOW_SIZE; 315 rect.height = height - SHADOW_SIZE; 316 317 if ((rect.x + rect.width) > layeredPaneWidth) { 318 rect.width = layeredPaneWidth - rect.x; 319 } 320 if ((rect.y + rect.height) > layeredPaneHeight) { 321 rect.height = layeredPaneHeight - rect.y; 322 } 323 if (!rect.isEmpty()) { 324 Graphics g = vShadowBg.createGraphics(); 325 g.translate(-rect.x, -rect.y); 326 g.setClip(rect); 327 boolean doubleBuffered = layeredPane.isDoubleBuffered(); 328 layeredPane.setDoubleBuffered(false); 329 layeredPane.paint(g); 330 layeredPane.setDoubleBuffered(doubleBuffered); 331 g.dispose(); 332 } 333 } catch (AWTException e) { 334 canSnapshot = false; 335 } catch (SecurityException e) { 336 canSnapshot = false; 337 } 338 } 339 340 343 private JComponent getLayeredPane() { 344 Container parent = null; 346 if (owner != null) { 347 parent = owner instanceof Container 348 ? (Container) owner 349 : owner.getParent(); 350 } 351 for (Container p = parent; p != null; p = p.getParent()) { 353 if (p instanceof JRootPane) { 354 if (p.getParent() instanceof JInternalFrame) { 355 continue; 356 } 357 parent = ((JRootPane)p).getLayeredPane(); 358 } else if(p instanceof Window) { 361 if (parent == null) { 362 parent = p; 363 } 364 break; 365 } else if (p instanceof JApplet) { 366 break; 370 } 371 } 372 return (JComponent) parent; 373 } 374 375 } | Popular Tags |