1 /* 2 * Copyright (c) 2003, 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 javax.swing.plaf.metal; 27 28 import java.awt.*; 29 import java.net.URL; 30 import java.util.*; 31 import javax.swing.*; 32 import javax.swing.plaf.*; 33 import sun.swing.SwingUtilities2; 34 import sun.swing.PrintColorUIResource; 35 36 /** 37 * The default theme for the {@code MetalLookAndFeel}. 38 * <p> 39 * The designers 40 * of the Metal Look and Feel strive to keep the default look up to 41 * date, possibly through the use of new themes in the future. 42 * Therefore, developers should only use this class directly when they 43 * wish to customize the "Ocean" look, or force it to be the current 44 * theme, regardless of future updates. 45 46 * <p> 47 * All colors returned by {@code OceanTheme} are completely 48 * opaque. 49 * 50 * @since 1.5 51 * @see MetalLookAndFeel#setCurrentTheme 52 */ 53 @SuppressWarnings("serial") // Superclass is not serializable across versions 54 public class OceanTheme extends DefaultMetalTheme { 55 private static final ColorUIResource PRIMARY1 = 56 new ColorUIResource(0x6382BF); 57 private static final ColorUIResource PRIMARY2 = 58 new ColorUIResource(0xA3B8CC); 59 private static final ColorUIResource PRIMARY3 = 60 new ColorUIResource(0xB8CFE5); 61 private static final ColorUIResource SECONDARY1 = 62 new ColorUIResource(0x7A8A99); 63 private static final ColorUIResource SECONDARY2 = 64 new ColorUIResource(0xB8CFE5); 65 private static final ColorUIResource SECONDARY3 = 66 new ColorUIResource(0xEEEEEE); 67 68 private static final ColorUIResource CONTROL_TEXT_COLOR = 69 new PrintColorUIResource(0x333333, Color.BLACK); 70 private static final ColorUIResource INACTIVE_CONTROL_TEXT_COLOR = 71 new ColorUIResource(0x999999); 72 private static final ColorUIResource MENU_DISABLED_FOREGROUND = 73 new ColorUIResource(0x999999); 74 private static final ColorUIResource OCEAN_BLACK = 75 new PrintColorUIResource(0x333333, Color.BLACK); 76 77 private static final ColorUIResource OCEAN_DROP = 78 new ColorUIResource(0xD2E9FF); 79 80 // ComponentOrientation Icon 81 // Delegates to different icons based on component orientation 82 private static class COIcon extends IconUIResource { 83 private Icon rtl; 84 85 public COIcon(Icon ltr, Icon rtl) { 86 super(ltr); 87 this.rtl = rtl; 88 } 89 90 public void paintIcon(Component c, Graphics g, int x, int y) { 91 if (MetalUtils.isLeftToRight(c)) { 92 super.paintIcon(c, g, x, y); 93 } else { 94 rtl.paintIcon(c, g, x, y); 95 } 96 } 97 } 98 99 // InternalFrame Icon 100 // Delegates to different icons based on button state 101 @SuppressWarnings("serial") // Superclass is not serializable across versions 102 private static class IFIcon extends IconUIResource { 103 private Icon pressed; 104 105 public IFIcon(Icon normal, Icon pressed) { 106 super(normal); 107 this.pressed = pressed; 108 } 109 110 public void paintIcon(Component c, Graphics g, int x, int y) { 111 ButtonModel model = ((AbstractButton)c).getModel(); 112 if (model.isPressed() && model.isArmed()) { 113 pressed.paintIcon(c, g, x, y); 114 } else { 115 super.paintIcon(c, g, x, y); 116 } 117 } 118 } 119 120 /** 121 * Creates an instance of <code>OceanTheme</code> 122 */ 123 public OceanTheme() { 124 } 125 126 /** 127 * Add this theme's custom entries to the defaults table. 128 * 129 * @param table the defaults table, non-null 130 * @throws NullPointerException if {@code table} is {@code null} 131 */ 132 public void addCustomEntriesToTable(UIDefaults table) { 133 UIDefaults.LazyValue focusBorder = t -> 134 new BorderUIResource.LineBorderUIResource(getPrimary1()); 135 // .30 0 DDE8F3 white secondary2 136 java.util.List buttonGradient = Arrays.asList( 137 new Object[] {new Float(.3f), new Float(0f), 138 new ColorUIResource(0xDDE8F3), getWhite(), getSecondary2() }); 139 140 // Other possible properties that aren't defined: 141 // 142 // Used when generating the disabled Icons, provides the region to 143 // constrain grays to. 144 // Button.disabledGrayRange -> Object[] of Integers giving min/max 145 // InternalFrame.inactiveTitleGradient -> Gradient when the 146 // internal frame is inactive. 147 Color cccccc = new ColorUIResource(0xCCCCCC); 148 Color dadada = new ColorUIResource(0xDADADA); 149 Color c8ddf2 = new ColorUIResource(0xC8DDF2); 150 Object directoryIcon = getIconResource("icons/ocean/directory.gif"); 151 Object fileIcon = getIconResource("icons/ocean/file.gif"); 152 java.util.List sliderGradient = Arrays.asList(new Object[] { 153 new Float(.3f), new Float(.2f), 154 c8ddf2, getWhite(), new ColorUIResource(SECONDARY2) }); 155 156 Object[] defaults = new Object[] { 157 "Button.gradient", buttonGradient, 158 "Button.rollover", Boolean.TRUE, 159 "Button.toolBarBorderBackground", INACTIVE_CONTROL_TEXT_COLOR, 160 "Button.disabledToolBarBorderBackground", cccccc, 161 "Button.rolloverIconType", "ocean", 162 163 "CheckBox.rollover", Boolean.TRUE, 164 "CheckBox.gradient", buttonGradient, 165 166 "CheckBoxMenuItem.gradient", buttonGradient, 167 168 // home2 169 "FileChooser.homeFolderIcon", 170 getIconResource("icons/ocean/homeFolder.gif"), 171 // directory2 172 "FileChooser.newFolderIcon", 173 getIconResource("icons/ocean/newFolder.gif"), 174 // updir2 175 "FileChooser.upFolderIcon", 176 getIconResource("icons/ocean/upFolder.gif"), 177 178 // computer2 179 "FileView.computerIcon", 180 getIconResource("icons/ocean/computer.gif"), 181 "FileView.directoryIcon", directoryIcon, 182 // disk2 183 "FileView.hardDriveIcon", 184 getIconResource("icons/ocean/hardDrive.gif"), 185 "FileView.fileIcon", fileIcon, 186 // floppy2 187 "FileView.floppyDriveIcon", 188 getIconResource("icons/ocean/floppy.gif"), 189 190 "Label.disabledForeground", getInactiveControlTextColor(), 191 192 "Menu.opaque", Boolean.FALSE, 193 194 "MenuBar.gradient", Arrays.asList(new Object[] { 195 new Float(1f), new Float(0f), 196 getWhite(), dadada, 197 new ColorUIResource(dadada) }), 198 "MenuBar.borderColor", cccccc, 199 200 "InternalFrame.activeTitleGradient", buttonGradient, 201 // close2 202 "InternalFrame.closeIcon", 203 new UIDefaults.LazyValue() { 204 public Object createValue(UIDefaults table) { 205 return new IFIcon(getHastenedIcon("icons/ocean/close.gif", table), 206 getHastenedIcon("icons/ocean/close-pressed.gif", table)); 207 } 208 }, 209 // minimize 210 "InternalFrame.iconifyIcon", 211 new UIDefaults.LazyValue() { 212 public Object createValue(UIDefaults table) { 213 return new IFIcon(getHastenedIcon("icons/ocean/iconify.gif", table), 214 getHastenedIcon("icons/ocean/iconify-pressed.gif", table)); 215 } 216 }, 217 // restore 218 "InternalFrame.minimizeIcon", 219 new UIDefaults.LazyValue() { 220 public Object createValue(UIDefaults table) { 221 return new IFIcon(getHastenedIcon("icons/ocean/minimize.gif", table), 222 getHastenedIcon("icons/ocean/minimize-pressed.gif", table)); 223 } 224 }, 225 // menubutton3 226 "InternalFrame.icon", 227 getIconResource("icons/ocean/menu.gif"), 228 // maximize2 229 "InternalFrame.maximizeIcon", 230 new UIDefaults.LazyValue() { 231 public Object createValue(UIDefaults table) { 232 return new IFIcon(getHastenedIcon("icons/ocean/maximize.gif", table), 233 getHastenedIcon("icons/ocean/maximize-pressed.gif", table)); 234 } 235 }, 236 // paletteclose 237 "InternalFrame.paletteCloseIcon", 238 new UIDefaults.LazyValue() { 239 public Object createValue(UIDefaults table) { 240 return new IFIcon(getHastenedIcon("icons/ocean/paletteClose.gif", table), 241 getHastenedIcon("icons/ocean/paletteClose-pressed.gif", table)); 242 } 243 }, 244 245 "List.focusCellHighlightBorder", focusBorder, 246 247 "MenuBarUI", "javax.swing.plaf.metal.MetalMenuBarUI", 248 249 "OptionPane.errorIcon", 250 getIconResource("icons/ocean/error.png"), 251 "OptionPane.informationIcon", 252 getIconResource("icons/ocean/info.png"), 253 "OptionPane.questionIcon", 254 getIconResource("icons/ocean/question.png"), 255 "OptionPane.warningIcon", 256 getIconResource("icons/ocean/warning.png"), 257 258 "RadioButton.gradient", buttonGradient, 259 "RadioButton.rollover", Boolean.TRUE, 260 261 "RadioButtonMenuItem.gradient", buttonGradient, 262 263 "ScrollBar.gradient", buttonGradient, 264 265 "Slider.altTrackColor", new ColorUIResource(0xD2E2EF), 266 "Slider.gradient", sliderGradient, 267 "Slider.focusGradient", sliderGradient, 268 269 "SplitPane.oneTouchButtonsOpaque", Boolean.FALSE, 270 "SplitPane.dividerFocusColor", c8ddf2, 271 272 "TabbedPane.borderHightlightColor", getPrimary1(), 273 "TabbedPane.contentAreaColor", c8ddf2, 274 "TabbedPane.contentBorderInsets", new Insets(4, 2, 3, 3), 275 "TabbedPane.selected", c8ddf2, 276 "TabbedPane.tabAreaBackground", dadada, 277 "TabbedPane.tabAreaInsets", new Insets(2, 2, 0, 6), 278 "TabbedPane.unselectedBackground", SECONDARY3, 279 280 "Table.focusCellHighlightBorder", focusBorder, 281 "Table.gridColor", SECONDARY1, 282 "TableHeader.focusCellBackground", c8ddf2, 283 284 "ToggleButton.gradient", buttonGradient, 285 286 "ToolBar.borderColor", cccccc, 287 "ToolBar.isRollover", Boolean.TRUE, 288 289 "Tree.closedIcon", directoryIcon, 290 291 "Tree.collapsedIcon", 292 new UIDefaults.LazyValue() { 293 public Object createValue(UIDefaults table) { 294 return new COIcon(getHastenedIcon("icons/ocean/collapsed.gif", table), 295 getHastenedIcon("icons/ocean/collapsed-rtl.gif", table)); 296 } 297 }, 298 299 "Tree.expandedIcon", 300 getIconResource("icons/ocean/expanded.gif"), 301 "Tree.leafIcon", fileIcon, 302 "Tree.openIcon", directoryIcon, 303 "Tree.selectionBorderColor", getPrimary1(), 304 "Tree.dropLineColor", getPrimary1(), 305 "Table.dropLineColor", getPrimary1(), 306 "Table.dropLineShortColor", OCEAN_BLACK, 307 308 "Table.dropCellBackground", OCEAN_DROP, 309 "Tree.dropCellBackground", OCEAN_DROP, 310 "List.dropCellBackground", OCEAN_DROP, 311 "List.dropLineColor", getPrimary1() 312 }; 313 table.putDefaults(defaults); 314 } 315 316 /** 317 * Overriden to enable picking up the system fonts, if applicable. 318 */ 319 boolean isSystemTheme() { 320 return true; 321 } 322 323 /** 324 * Return the name of this theme, "Ocean". 325 * 326 * @return "Ocean" 327 */ 328 public String getName() { 329 return "Ocean"; 330 } 331 332 /** 333 * Returns the primary 1 color. This returns a color with an rgb hex value 334 * of {@code 0x6382BF}. 335 * 336 * @return the primary 1 color 337 * @see java.awt.Color#decode 338 */ 339 protected ColorUIResource getPrimary1() { 340 return PRIMARY1; 341 } 342 343 /** 344 * Returns the primary 2 color. This returns a color with an rgb hex value 345 * of {@code 0xA3B8CC}. 346 * 347 * @return the primary 2 color 348 * @see java.awt.Color#decode 349 */ 350 protected ColorUIResource getPrimary2() { 351 return PRIMARY2; 352 } 353 354 /** 355 * Returns the primary 3 color. This returns a color with an rgb hex value 356 * of {@code 0xB8CFE5}. 357 * 358 * @return the primary 3 color 359 * @see java.awt.Color#decode 360 */ 361 protected ColorUIResource getPrimary3() { 362 return PRIMARY3; 363 } 364 365 /** 366 * Returns the secondary 1 color. This returns a color with an rgb hex 367 * value of {@code 0x7A8A99}. 368 * 369 * @return the secondary 1 color 370 * @see java.awt.Color#decode 371 */ 372 protected ColorUIResource getSecondary1() { 373 return SECONDARY1; 374 } 375 376 /** 377 * Returns the secondary 2 color. This returns a color with an rgb hex 378 * value of {@code 0xB8CFE5}. 379 * 380 * @return the secondary 2 color 381 * @see java.awt.Color#decode 382 */ 383 protected ColorUIResource getSecondary2() { 384 return SECONDARY2; 385 } 386 387 /** 388 * Returns the secondary 3 color. This returns a color with an rgb hex 389 * value of {@code 0xEEEEEE}. 390 * 391 * @return the secondary 3 color 392 * @see java.awt.Color#decode 393 */ 394 protected ColorUIResource getSecondary3() { 395 return SECONDARY3; 396 } 397 398 /** 399 * Returns the black color. This returns a color with an rgb hex 400 * value of {@code 0x333333}. 401 * 402 * @return the black color 403 * @see java.awt.Color#decode 404 */ 405 protected ColorUIResource getBlack() { 406 return OCEAN_BLACK; 407 } 408 409 /** 410 * Returns the desktop color. This returns a color with an rgb hex 411 * value of {@code 0xFFFFFF}. 412 * 413 * @return the desktop color 414 * @see java.awt.Color#decode 415 */ 416 public ColorUIResource getDesktopColor() { 417 return MetalTheme.white; 418 } 419 420 /** 421 * Returns the inactive control text color. This returns a color with an 422 * rgb hex value of {@code 0x999999}. 423 * 424 * @return the inactive control text color 425 */ 426 public ColorUIResource getInactiveControlTextColor() { 427 return INACTIVE_CONTROL_TEXT_COLOR; 428 } 429 430 /** 431 * Returns the control text color. This returns a color with an 432 * rgb hex value of {@code 0x333333}. 433 * 434 * @return the control text color 435 */ 436 public ColorUIResource getControlTextColor() { 437 return CONTROL_TEXT_COLOR; 438 } 439 440 /** 441 * Returns the menu disabled foreground color. This returns a color with an 442 * rgb hex value of {@code 0x999999}. 443 * 444 * @return the menu disabled foreground color 445 */ 446 public ColorUIResource getMenuDisabledForeground() { 447 return MENU_DISABLED_FOREGROUND; 448 } 449 450 private Object getIconResource(String iconID) { 451 return SwingUtilities2.makeIcon(getClass(), OceanTheme.class, iconID); 452 } 453 454 // makes use of getIconResource() to fetch an icon and then hastens it 455 // - calls createValue() on it and returns the actual icon 456 private Icon getHastenedIcon(String iconID, UIDefaults table) { 457 Object res = getIconResource(iconID); 458 return (Icon)((UIDefaults.LazyValue)res).createValue(table); 459 } 460 }