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