1 /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.laf; 27 28 import java.awt.*; 29 import java.awt.image.BufferedImage; 30 import java.security.PrivilegedAction; 31 32 import javax.swing.*; 33 import javax.swing.plaf.*; 34 35 import sun.lwawt.macosx.LWCToolkit; 36 import apple.laf.JRSUIConstants.AlignmentHorizontal; 37 import apple.laf.JRSUIConstants.AlignmentVertical; 38 import apple.laf.JRSUIConstants.Direction; 39 import apple.laf.JRSUIConstants.State; 40 import apple.laf.JRSUIConstants.Widget; 41 import apple.laf.*; 42 43 import com.apple.eio.FileManager; 44 import com.apple.laf.AquaIcon.InvertableIcon; 45 import com.apple.laf.AquaIcon.JRSUIControlSpec; 46 import com.apple.laf.AquaIcon.SystemIcon; 47 import com.apple.laf.AquaUtils.RecyclableObject; 48 import com.apple.laf.AquaUtils.RecyclableSingleton; 49 import java.util.Arrays; 50 import java.util.List; 51 import sun.awt.image.MultiResolutionBufferedImage; 52 import sun.awt.image.MultiResolutionImage; 53 54 public class AquaImageFactory { 55 public static IconUIResource getConfirmImageIcon() { 56 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 57 58 return new IconUIResource(new AquaIcon.CachingScalingIcon(kAlertIconSize, kAlertIconSize) { 59 Image createImage() { 60 return getThisApplicationsIcon(kAlertIconSize, kAlertIconSize); 61 } 62 }); 63 } 64 65 public static IconUIResource getCautionImageIcon() { 66 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 67 return getAppIconCompositedOn(AquaIcon.SystemIcon.getCautionIcon()); 68 } 69 70 public static IconUIResource getStopImageIcon() { 71 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 72 return getAppIconCompositedOn(AquaIcon.SystemIcon.getStopIcon()); 73 } 74 75 public static IconUIResource getLockImageIcon() { 76 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 77 if (JRSUIUtils.Images.shouldUseLegacySecurityUIPath()) { 78 final Image lockIcon = AquaUtils.getCImageCreator().createImageFromFile("/System/Library/CoreServices/SecurityAgent.app/Contents/Resources/Security.icns", kAlertIconSize, kAlertIconSize); 79 return getAppIconCompositedOn(lockIcon); 80 } 81 82 final Image lockIcon = Toolkit.getDefaultToolkit().getImage("NSImage://NSSecurity"); 83 return getAppIconCompositedOn(lockIcon); 84 } 85 86 static Image getThisApplicationsIcon(final int width, final int height) { 87 final String path = getPathToThisApplication(); 88 89 if (path == null) { 90 return getGenericJavaIcon(); 91 } 92 93 if (path.endsWith("/Home/bin")) { 94 return getGenericJavaIcon(); 95 } 96 97 if (path.startsWith("/usr/bin")) { 98 return getGenericJavaIcon(); 99 } 100 101 return AquaUtils.getCImageCreator().createImageOfFile(path, height, width); 102 } 103 104 static Image getGenericJavaIcon() { 105 return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() { 106 public Image run() { 107 return com.apple.eawt.Application.getApplication().getDockIconImage(); 108 } 109 }); 110 } 111 112 static String getPathToThisApplication() { 113 return java.security.AccessController.doPrivileged(new PrivilegedAction<String>() { 114 public String run() { 115 return FileManager.getPathToApplicationBundle(); 116 } 117 }); 118 } 119 120 static IconUIResource getAppIconCompositedOn(final SystemIcon systemIcon) { 121 systemIcon.setSize(kAlertIconSize, kAlertIconSize); 122 return getAppIconCompositedOn(systemIcon.createImage()); 123 } 124 125 private static final int kAlertIconSize = 64; 126 static IconUIResource getAppIconCompositedOn(final Image background) { 127 128 final BufferedImage iconImage = getAppIconImageCompositedOn(background, 1); 129 130 if (background instanceof MultiResolutionIconImage) { 131 BufferedImage background2x 132 = ((MultiResolutionIconImage) background).resolutionVariant; 133 BufferedImage icon2xImage = getAppIconImageCompositedOn(background2x, 2); 134 135 return new IconUIResource(new ImageIcon( 136 new MultiResolutionIconImage(iconImage, icon2xImage))); 137 } 138 return new IconUIResource(new ImageIcon(iconImage)); 139 } 140 141 static BufferedImage getAppIconImageCompositedOn(final Image background, int scaleFactor) { 142 143 final int scaledAlertIconSize = kAlertIconSize * scaleFactor; 144 final int kAlertSubIconSize = (int) (scaledAlertIconSize * 0.5); 145 final int kAlertSubIconInset = scaledAlertIconSize - kAlertSubIconSize; 146 final Icon smallAppIconScaled = new AquaIcon.CachingScalingIcon( 147 kAlertSubIconSize, kAlertSubIconSize) { 148 Image createImage() { 149 return getThisApplicationsIcon(kAlertSubIconSize, kAlertSubIconSize); 150 } 151 }; 152 153 final BufferedImage image = new BufferedImage(scaledAlertIconSize, 154 scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB); 155 final Graphics g = image.getGraphics(); 156 g.drawImage(background, 0, 0, 157 scaledAlertIconSize, scaledAlertIconSize, null); 158 if (g instanceof Graphics2D) { 159 // improves icon rendering quality in Quartz 160 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, 161 RenderingHints.VALUE_RENDER_QUALITY); 162 } 163 164 smallAppIconScaled.paintIcon(null, g, 165 kAlertSubIconInset, kAlertSubIconInset); 166 g.dispose(); 167 168 return image; 169 } 170 171 public static IconUIResource getTreeFolderIcon() { 172 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 173 return AquaIcon.SystemIcon.getFolderIconUIResource(); 174 } 175 176 public static IconUIResource getTreeOpenFolderIcon() { 177 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 178 return AquaIcon.SystemIcon.getOpenFolderIconUIResource(); 179 } 180 181 public static IconUIResource getTreeDocumentIcon() { 182 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 183 return AquaIcon.SystemIcon.getDocumentIconUIResource(); 184 } 185 186 public static UIResource getTreeExpandedIcon() { 187 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 188 return AquaIcon.getIconFor(new JRSUIControlSpec() { 189 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 190 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 191 painter.state.set(State.ACTIVE); 192 painter.state.set(Direction.DOWN); 193 painter.state.set(AlignmentHorizontal.CENTER); 194 painter.state.set(AlignmentVertical.CENTER); 195 } 196 }, 20, 20); 197 } 198 199 public static UIResource getTreeCollapsedIcon() { 200 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 201 return AquaIcon.getIconFor(new JRSUIControlSpec() { 202 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 203 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 204 painter.state.set(State.ACTIVE); 205 painter.state.set(Direction.RIGHT); 206 painter.state.set(AlignmentHorizontal.CENTER); 207 painter.state.set(AlignmentVertical.CENTER); 208 } 209 }, 20, 20); 210 } 211 212 public static UIResource getTreeRightToLeftCollapsedIcon() { 213 // public, because UIDefaults.ProxyLazyValue uses reflection to get this value 214 return AquaIcon.getIconFor(new JRSUIControlSpec() { 215 public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { 216 painter.state.set(Widget.DISCLOSURE_TRIANGLE); 217 painter.state.set(State.ACTIVE); 218 painter.state.set(Direction.LEFT); 219 painter.state.set(AlignmentHorizontal.CENTER); 220 painter.state.set(AlignmentVertical.CENTER); 221 } 222 }, 20, 20); 223 } 224 225 static class NamedImageSingleton extends RecyclableSingleton<Image> { 226 final String namedImage; 227 228 NamedImageSingleton(final String namedImage) { 229 this.namedImage = namedImage; 230 } 231 232 @Override 233 protected Image getInstance() { 234 return getNSIcon(namedImage); 235 } 236 } 237 238 static class IconUIResourceSingleton extends RecyclableSingleton<IconUIResource> { 239 final NamedImageSingleton holder; 240 241 public IconUIResourceSingleton(final NamedImageSingleton holder) { 242 this.holder = holder; 243 } 244 245 @Override 246 protected IconUIResource getInstance() { 247 return new IconUIResource(new ImageIcon(holder.get())); 248 } 249 } 250 251 @SuppressWarnings("serial") // Superclass is not serializable across versions 252 static class InvertableImageIcon extends ImageIcon implements InvertableIcon, UIResource { 253 Icon invertedImage; 254 public InvertableImageIcon(final Image image) { 255 super(image); 256 } 257 258 @Override 259 public Icon getInvertedIcon() { 260 if (invertedImage != null) return invertedImage; 261 return invertedImage = new IconUIResource(new ImageIcon(AquaUtils.generateLightenedImage(getImage(), 100))); 262 } 263 } 264 265 protected static final NamedImageSingleton northArrow = new NamedImageSingleton("NSMenuScrollUp"); 266 protected static final IconUIResourceSingleton northArrowIcon = new IconUIResourceSingleton(northArrow); 267 protected static final NamedImageSingleton southArrow = new NamedImageSingleton("NSMenuScrollDown"); 268 protected static final IconUIResourceSingleton southArrowIcon = new IconUIResourceSingleton(southArrow); 269 protected static final NamedImageSingleton westArrow = new NamedImageSingleton("NSMenuSubmenuLeft"); 270 protected static final IconUIResourceSingleton westArrowIcon = new IconUIResourceSingleton(westArrow); 271 protected static final NamedImageSingleton eastArrow = new NamedImageSingleton("NSMenuSubmenu"); 272 protected static final IconUIResourceSingleton eastArrowIcon = new IconUIResourceSingleton(eastArrow); 273 274 static Image getArrowImageForDirection(final int direction) { 275 switch(direction) { 276 case SwingConstants.NORTH: return northArrow.get(); 277 case SwingConstants.SOUTH: return southArrow.get(); 278 case SwingConstants.EAST: return eastArrow.get(); 279 case SwingConstants.WEST: return westArrow.get(); 280 } 281 return null; 282 } 283 284 static Icon getArrowIconForDirection(int direction) { 285 switch(direction) { 286 case SwingConstants.NORTH: return northArrowIcon.get(); 287 case SwingConstants.SOUTH: return southArrowIcon.get(); 288 case SwingConstants.EAST: return eastArrowIcon.get(); 289 case SwingConstants.WEST: return westArrowIcon.get(); 290 } 291 return null; 292 } 293 294 public static Icon getMenuArrowIcon() { 295 return new InvertableImageIcon(AquaUtils.generateLightenedImage(eastArrow.get(), 25)); 296 } 297 298 public static Icon getMenuItemCheckIcon() { 299 return new InvertableImageIcon(AquaUtils.generateLightenedImage( 300 getNSIcon("NSMenuItemSelection"), 25)); 301 } 302 303 public static Icon getMenuItemDashIcon() { 304 return new InvertableImageIcon(AquaUtils.generateLightenedImage( 305 getNSIcon("NSMenuMixedState"), 25)); 306 } 307 308 private static Image getNSIcon(String imageName) { 309 Image icon = Toolkit.getDefaultToolkit() 310 .getImage("NSImage://" + imageName); 311 312 if (icon instanceof MultiResolutionImage) { 313 return icon; 314 } 315 316 Image icon2x = AquaUtils.getCImageCreator().createImageFromName( 317 imageName, 2 * icon.getWidth(null), 2 * icon.getHeight(null)); 318 return new MultiResolutionBufferedImage( 319 BufferedImage.TYPE_INT_ARGB_PRE, 0, icon, icon2x); 320 } 321 322 public static class NineSliceMetrics { 323 public final int wCut, eCut, nCut, sCut; 324 public final int minW, minH; 325 public final boolean showMiddle, stretchH, stretchV; 326 327 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut) { 328 this(minWidth, minHeight, westCut, eastCut, northCut, southCut, true); 329 } 330 331 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle) { 332 this(minWidth, minHeight, westCut, eastCut, northCut, southCut, showMiddle, true, true); 333 } 334 335 public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { 336 this.wCut = westCut; this.eCut = eastCut; this.nCut = northCut; this.sCut = southCut; 337 this.minW = minWidth; this.minH = minHeight; 338 this.showMiddle = showMiddle; this.stretchH = stretchHorizontally; this.stretchV = stretchVertically; 339 } 340 } 341 342 /* 343 * A "paintable" which holds nine images, which represent a sliced up initial 344 * image that can be streched from its middles. 345 */ 346 public static class SlicedImageControl { 347 final BufferedImage NW, N, NE; 348 final BufferedImage W, C, E; 349 final BufferedImage SW, S, SE; 350 351 final NineSliceMetrics metrics; 352 353 final int totalWidth, totalHeight; 354 final int centerColWidth, centerRowHeight; 355 356 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut) { 357 this(img, westCut, eastCut, northCut, southCut, true); 358 } 359 360 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle) { 361 this(img, westCut, eastCut, northCut, southCut, useMiddle, true, true); 362 } 363 364 public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { 365 this(img, new NineSliceMetrics(img.getWidth(null), img.getHeight(null), westCut, eastCut, northCut, southCut, useMiddle, stretchHorizontally, stretchVertically)); 366 } 367 368 public SlicedImageControl(final Image img, final NineSliceMetrics metrics) { 369 this.metrics = metrics; 370 371 if (img.getWidth(null) != metrics.minW || img.getHeight(null) != metrics.minH) { 372 throw new IllegalArgumentException("SlicedImageControl: template image and NineSliceMetrics don't agree on minimum dimensions"); 373 } 374 375 totalWidth = metrics.minW; 376 totalHeight = metrics.minH; 377 centerColWidth = totalWidth - metrics.wCut - metrics.eCut; 378 centerRowHeight = totalHeight - metrics.nCut - metrics.sCut; 379 380 NW = createSlice(img, 0, 0, metrics.wCut, metrics.nCut); 381 N = createSlice(img, metrics.wCut, 0, centerColWidth, metrics.nCut); 382 NE = createSlice(img, totalWidth - metrics.eCut, 0, metrics.eCut, metrics.nCut); 383 W = createSlice(img, 0, metrics.nCut, metrics.wCut, centerRowHeight); 384 C = metrics.showMiddle ? createSlice(img, metrics.wCut, metrics.nCut, centerColWidth, centerRowHeight) : null; 385 E = createSlice(img, totalWidth - metrics.eCut, metrics.nCut, metrics.eCut, centerRowHeight); 386 SW = createSlice(img, 0, totalHeight - metrics.sCut, metrics.wCut, metrics.sCut); 387 S = createSlice(img, metrics.wCut, totalHeight - metrics.sCut, centerColWidth, metrics.sCut); 388 SE = createSlice(img, totalWidth - metrics.eCut, totalHeight - metrics.sCut, metrics.eCut, metrics.sCut); 389 } 390 391 static BufferedImage createSlice(final Image img, final int x, final int y, final int w, final int h) { 392 if (w == 0 || h == 0) return null; 393 394 final BufferedImage slice = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); 395 final Graphics2D g2d = slice.createGraphics(); 396 g2d.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); 397 g2d.dispose(); 398 399 return slice; 400 } 401 402 public void paint(final Graphics g, final int x, final int y, final int w, final int h) { 403 g.translate(x, y); 404 405 if (w < totalWidth || h < totalHeight) { 406 paintCompressed(g, w, h); 407 } else { 408 paintStretchedMiddles(g, w, h); 409 } 410 411 g.translate(-x, -y); 412 } 413 414 void paintStretchedMiddles(final Graphics g, final int w, final int h) { 415 int baseX = metrics.stretchH ? 0 : ((w / 2) - (totalWidth / 2)); 416 int baseY = metrics.stretchV ? 0 : ((h / 2) - (totalHeight / 2)); 417 int adjustedWidth = metrics.stretchH ? w : totalWidth; 418 int adjustedHeight = metrics.stretchV ? h : totalHeight; 419 420 if (NW != null) g.drawImage(NW, baseX, baseY, null); 421 if (N != null) g.drawImage(N, baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut, null); 422 if (NE != null) g.drawImage(NE, baseX + adjustedWidth - metrics.eCut, baseY, null); 423 if (W != null) g.drawImage(W, baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 424 if (C != null) g.drawImage(C, baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 425 if (E != null) g.drawImage(E, baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut, null); 426 if (SW != null) g.drawImage(SW, baseX, baseY + adjustedHeight - metrics.sCut, null); 427 if (S != null) g.drawImage(S, baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut, null); 428 if (SE != null) g.drawImage(SE, baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, null); 429 430 /* 431 if (NW != null) {g.setColor(Color.GREEN); g.fillRect(baseX, baseY, NW.getWidth(), NW.getHeight());} 432 if (N != null) {g.setColor(Color.RED); g.fillRect(baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut);} 433 if (NE != null) {g.setColor(Color.BLUE); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY, NE.getWidth(), NE.getHeight());} 434 if (W != null) {g.setColor(Color.PINK); g.fillRect(baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} 435 if (C != null) {g.setColor(Color.ORANGE); g.fillRect(baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} 436 if (E != null) {g.setColor(Color.CYAN); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut);} 437 if (SW != null) {g.setColor(Color.MAGENTA); g.fillRect(baseX, baseY + adjustedHeight - metrics.sCut, SW.getWidth(), SW.getHeight());} 438 if (S != null) {g.setColor(Color.DARK_GRAY); g.fillRect(baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut);} 439 if (SE != null) {g.setColor(Color.YELLOW); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, SE.getWidth(), SE.getHeight());} 440 */ 441 } 442 443 void paintCompressed(final Graphics g, final int w, final int h) { 444 final double heightRatio = h > totalHeight ? 1.0 : (double)h / (double)totalHeight; 445 final double widthRatio = w > totalWidth ? 1.0 : (double)w / (double)totalWidth; 446 447 final int northHeight = (int)(metrics.nCut * heightRatio); 448 final int southHeight = (int)(metrics.sCut * heightRatio); 449 final int centerHeight = h - northHeight - southHeight; 450 451 final int westWidth = (int)(metrics.wCut * widthRatio); 452 final int eastWidth = (int)(metrics.eCut * widthRatio); 453 final int centerWidth = w - westWidth - eastWidth; 454 455 if (NW != null) g.drawImage(NW, 0, 0, westWidth, northHeight, null); 456 if (N != null) g.drawImage(N, westWidth, 0, centerWidth, northHeight, null); 457 if (NE != null) g.drawImage(NE, w - eastWidth, 0, eastWidth, northHeight, null); 458 if (W != null) g.drawImage(W, 0, northHeight, westWidth, centerHeight, null); 459 if (C != null) g.drawImage(C, westWidth, northHeight, centerWidth, centerHeight, null); 460 if (E != null) g.drawImage(E, w - eastWidth, northHeight, eastWidth, centerHeight, null); 461 if (SW != null) g.drawImage(SW, 0, h - southHeight, westWidth, southHeight, null); 462 if (S != null) g.drawImage(S, westWidth, h - southHeight, centerWidth, southHeight, null); 463 if (SE != null) g.drawImage(SE, w - eastWidth, h - southHeight, eastWidth, southHeight, null); 464 } 465 } 466 467 public abstract static class RecyclableSlicedImageControl extends RecyclableObject<SlicedImageControl> { 468 final NineSliceMetrics metrics; 469 470 public RecyclableSlicedImageControl(final NineSliceMetrics metrics) { 471 this.metrics = metrics; 472 } 473 474 @Override 475 protected SlicedImageControl create() { 476 return new SlicedImageControl(createTemplateImage(metrics.minW, metrics.minH), metrics); 477 } 478 479 protected abstract Image createTemplateImage(final int width, final int height); 480 } 481 482 // when we use SystemColors, we need to proxy the color with something that implements UIResource, 483 // so that it will be uninstalled when the look and feel is changed. 484 @SuppressWarnings("serial") // JDK implementation class 485 private static class SystemColorProxy extends Color implements UIResource { 486 final Color color; 487 public SystemColorProxy(final Color color) { 488 super(color.getRGB()); 489 this.color = color; 490 } 491 492 public int getRGB() { 493 return color.getRGB(); 494 } 495 } 496 497 public static Color getWindowBackgroundColorUIResource() { 498 //return AquaNativeResources.getWindowBackgroundColorUIResource(); 499 return new SystemColorProxy(SystemColor.window); 500 } 501 502 public static Color getTextSelectionBackgroundColorUIResource() { 503 return new SystemColorProxy(SystemColor.textHighlight); 504 } 505 506 public static Color getTextSelectionForegroundColorUIResource() { 507 return new SystemColorProxy(SystemColor.textHighlightText); 508 } 509 510 public static Color getSelectionBackgroundColorUIResource() { 511 return new SystemColorProxy(SystemColor.controlHighlight); 512 } 513 514 public static Color getSelectionForegroundColorUIResource() { 515 return new SystemColorProxy(SystemColor.controlLtHighlight); 516 } 517 518 public static Color getFocusRingColorUIResource() { 519 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.KEYBOARD_FOCUS_COLOR)); 520 } 521 522 public static Color getSelectionInactiveBackgroundColorUIResource() { 523 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_BACKGROUND_COLOR)); 524 } 525 526 public static Color getSelectionInactiveForegroundColorUIResource() { 527 return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR)); 528 } 529 530 static class MultiResolutionIconImage extends BufferedImage 531 implements MultiResolutionImage { 532 533 BufferedImage resolutionVariant; 534 535 public MultiResolutionIconImage(BufferedImage image, BufferedImage resolutionVariant) { 536 super(image.getWidth(), image.getHeight(), image.getType()); 537 this.resolutionVariant = resolutionVariant; 538 Graphics g = getGraphics(); 539 g.drawImage(image, 0, 0, null); 540 g.dispose(); 541 } 542 543 @Override 544 public Image getResolutionVariant(int width, int height) { 545 return ((width <= getWidth() && height <= getHeight())) 546 ? this : resolutionVariant; 547 } 548 549 @Override 550 public List<Image> getResolutionVariants() { 551 return Arrays.asList(this, resolutionVariant); 552 } 553 } 554 }