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