1 /* 2 * Copyright (c) 2012, 2015, 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 javafx.scene.control.skin; 27 28 import com.sun.javafx.css.StyleManager; 29 30 import com.sun.javafx.scene.control.Properties; 31 import com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior; 32 import com.sun.javafx.scene.control.skin.Utils; 33 import javafx.beans.property.StringProperty; 34 import javafx.css.StyleOrigin; 35 import javafx.css.StyleableBooleanProperty; 36 import javafx.css.CssMetaData; 37 38 import javafx.css.converter.BooleanConverter; 39 40 import java.util.ArrayList; 41 import java.util.Collections; 42 import java.util.List; 43 44 import javafx.css.StyleableDoubleProperty; 45 import javafx.css.StyleableStringProperty; 46 import javafx.geometry.Pos; 47 import javafx.scene.Node; 48 import javafx.scene.control.Control; 49 import javafx.scene.image.ImageView; 50 import javafx.scene.layout.StackPane; 51 import javafx.scene.shape.Rectangle; 52 53 import javafx.css.converter.SizeConverter; 54 import javafx.css.converter.StringConverter; 55 import com.sun.javafx.scene.control.behavior.ColorPickerBehavior; 56 57 import java.util.HashMap; 58 import java.util.Map; 59 60 import javafx.scene.control.ColorPicker; 61 import javafx.scene.control.TextField; 62 import javafx.beans.property.BooleanProperty; 63 import javafx.beans.value.WritableValue; 64 import javafx.css.Styleable; 65 import javafx.css.StyleableProperty; 66 import javafx.scene.control.Label; 67 import javafx.scene.paint.Color; 68 69 import static javafx.scene.paint.Color.*; 70 71 /** 72 * Default skin implementation for the {@link ColorPicker} control. 73 * 74 * @see ColorPicker 75 * @since 9 76 */ 77 public class ColorPickerSkin extends ComboBoxPopupControl<Color> { 78 79 /*************************************************************************** 80 * * 81 * Private fields * 82 * * 83 **************************************************************************/ 84 85 private Label displayNode; 86 private StackPane pickerColorBox; 87 private Rectangle colorRect; 88 private ColorPalette popupContent; 89 90 private final ColorPickerBehavior behavior; 91 92 93 94 /*************************************************************************** 95 * * 96 * Constructors * 97 * * 98 **************************************************************************/ 99 100 /** 101 * Creates a new ColorPickerSkin instance, installing the necessary child 102 * nodes into the Control {@link Control#getChildren() children} list, as 103 * well as the necessary input mappings for handling key, mouse, etc events. 104 * 105 * @param control The control that this skin should be installed onto. 106 */ 107 public ColorPickerSkin(final ColorPicker control) { 108 super(control); 109 110 // install default input map for the control 111 this.behavior = new ColorPickerBehavior(control); 112 // control.setInputMap(behavior.getInputMap()); 113 114 updateComboBoxMode(); 115 registerChangeListener(control.valueProperty(), e -> updateColor()); 116 117 // create displayNode 118 displayNode = new Label(); 119 displayNode.getStyleClass().add("color-picker-label"); 120 displayNode.setManaged(false); 121 122 // label graphic 123 pickerColorBox = new PickerColorBox(); 124 pickerColorBox.getStyleClass().add("picker-color"); 125 colorRect = new Rectangle(12, 12); 126 colorRect.getStyleClass().add("picker-color-rect"); 127 128 updateColor(); 129 130 pickerColorBox.getChildren().add(colorRect); 131 displayNode.setGraphic(pickerColorBox); 132 } 133 134 135 136 /*************************************************************************** 137 * * 138 * Properties * 139 * * 140 **************************************************************************/ 141 142 // --- color label visible 143 BooleanProperty colorLabelVisible = new StyleableBooleanProperty(true) { 144 @Override public void invalidated() { 145 if (displayNode != null) { 146 if (colorLabelVisible.get()) { 147 displayNode.setText(colorDisplayName(((ColorPicker)getSkinnable()).getValue())); 148 } else { 149 displayNode.setText(""); 150 } 151 } 152 } 153 @Override public Object getBean() { 154 return ColorPickerSkin.this; 155 } 156 @Override public String getName() { 157 return "colorLabelVisible"; 158 } 159 @Override public CssMetaData<ColorPicker,Boolean> getCssMetaData() { 160 return StyleableProperties.COLOR_LABEL_VISIBLE; 161 } 162 }; 163 164 // --- image url 165 private final StringProperty imageUrlProperty() { return imageUrl; } 166 private final StyleableStringProperty imageUrl = new StyleableStringProperty() { 167 @Override public void applyStyle(StyleOrigin origin, String v) { 168 super.applyStyle(origin, v); 169 if (v == null) { 170 // remove old image view 171 if (pickerColorBox.getChildren().size() == 2) pickerColorBox.getChildren().remove(1); 172 } else { 173 if (pickerColorBox.getChildren().size() == 2) { 174 ImageView imageView = (ImageView)pickerColorBox.getChildren().get(1); 175 imageView.setImage(StyleManager.getInstance().getCachedImage(v)); 176 } else { 177 pickerColorBox.getChildren().add(new ImageView(StyleManager.getInstance().getCachedImage(v))); 178 } 179 } 180 } 181 @Override public Object getBean() { 182 return ColorPickerSkin.this; 183 } 184 @Override public String getName() { 185 return "imageUrl"; 186 } 187 @Override public CssMetaData<ColorPicker,String> getCssMetaData() { 188 return StyleableProperties.GRAPHIC; 189 } 190 }; 191 192 // --- color rect width 193 private final StyleableDoubleProperty colorRectWidth = new StyleableDoubleProperty(12) { 194 @Override protected void invalidated() { 195 if(pickerColorBox!=null) pickerColorBox.requestLayout(); 196 } 197 @Override public CssMetaData<ColorPicker,Number> getCssMetaData() { 198 return StyleableProperties.COLOR_RECT_WIDTH; 199 } 200 @Override public Object getBean() { 201 return ColorPickerSkin.this; 202 } 203 @Override public String getName() { 204 return "colorRectWidth"; 205 } 206 }; 207 208 // --- color rect height 209 private final StyleableDoubleProperty colorRectHeight = new StyleableDoubleProperty(12) { 210 @Override protected void invalidated() { 211 if(pickerColorBox!=null) pickerColorBox.requestLayout(); 212 } 213 @Override public CssMetaData<ColorPicker,Number> getCssMetaData() { 214 return StyleableProperties.COLOR_RECT_HEIGHT; 215 } 216 @Override public Object getBean() { 217 return ColorPickerSkin.this; 218 } 219 @Override public String getName() { 220 return "colorRectHeight"; 221 } 222 }; 223 224 // --- color rect X 225 private final StyleableDoubleProperty colorRectX = new StyleableDoubleProperty(0) { 226 @Override protected void invalidated() { 227 if(pickerColorBox!=null) pickerColorBox.requestLayout(); 228 } 229 @Override public CssMetaData<ColorPicker,Number> getCssMetaData() { 230 return StyleableProperties.COLOR_RECT_X; 231 } 232 @Override public Object getBean() { 233 return ColorPickerSkin.this; 234 } 235 @Override public String getName() { 236 return "colorRectX"; 237 } 238 }; 239 240 // --- color rect Y 241 private final StyleableDoubleProperty colorRectY = new StyleableDoubleProperty(0) { 242 @Override protected void invalidated() { 243 if(pickerColorBox!=null) pickerColorBox.requestLayout(); 244 } 245 @Override public CssMetaData<ColorPicker,Number> getCssMetaData() { 246 return StyleableProperties.COLOR_RECT_Y; 247 } 248 @Override public Object getBean() { 249 return ColorPickerSkin.this; 250 } 251 @Override public String getName() { 252 return "colorRectY"; 253 } 254 }; 255 256 257 258 /*************************************************************************** 259 * * 260 * Public API * 261 * * 262 **************************************************************************/ 263 264 /** {@inheritDoc} */ 265 @Override public void dispose() { 266 super.dispose(); 267 268 if (behavior != null) { 269 behavior.dispose(); 270 } 271 } 272 273 /** {@inheritDoc} */ 274 @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 275 if (!colorLabelVisible.get()) { 276 return super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset); 277 } 278 String displayNodeText = displayNode.getText(); 279 double width = 0; 280 for (String name : colorNameMap.values()) { 281 displayNode.setText(name); 282 width = Math.max(width, super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset)); 283 } 284 displayNode.setText(Utils.formatHexString(Color.BLACK)); // #000000 285 width = Math.max(width, super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset)); 286 displayNode.setText(displayNodeText); 287 return width; 288 } 289 290 /** {@inheritDoc} */ 291 @Override protected Node getPopupContent() { 292 if (popupContent == null) { 293 // popupContent = new ColorPalette(colorPicker.getValue(), colorPicker); 294 popupContent = new ColorPalette((ColorPicker)getSkinnable()); 295 popupContent.setPopupControl(getPopup()); 296 } 297 return popupContent; 298 } 299 300 /** {@inheritDoc} */ 301 @Override public void show() { 302 super.show(); 303 final ColorPicker colorPicker = (ColorPicker)getSkinnable(); 304 popupContent.updateSelection(colorPicker.getValue()); 305 } 306 307 /** {@inheritDoc} */ 308 @Override public Node getDisplayNode() { 309 return displayNode; 310 } 311 312 /** {@inheritDoc} */ 313 @Override protected void layoutChildren(final double x, final double y, 314 final double w, final double h) { 315 updateComboBoxMode(); 316 super.layoutChildren(x, y, w, h); 317 } 318 319 320 321 /*************************************************************************** 322 * * 323 * Private implementation * 324 * * 325 **************************************************************************/ 326 327 /** {@inheritDoc} */ 328 @Override void focusLost() { 329 // do nothing 330 } 331 332 /** {@inheritDoc} */ 333 @Override ComboBoxBaseBehavior getBehavior() { 334 return behavior; 335 } 336 337 private void updateComboBoxMode() { 338 List<String> styleClass = getSkinnable().getStyleClass(); 339 if (styleClass.contains(ColorPicker.STYLE_CLASS_BUTTON)) { 340 setMode(ComboBoxMode.BUTTON); 341 } else if (styleClass.contains(ColorPicker.STYLE_CLASS_SPLIT_BUTTON)) { 342 setMode(ComboBoxMode.SPLITBUTTON); 343 } 344 } 345 346 private static final Map<Color, String> colorNameMap = new HashMap<>(24); 347 private static final Map<Color, String> cssNameMap = new HashMap<>(139); 348 static { 349 // Translatable display names for the most common colors 350 colorNameMap.put(TRANSPARENT, Properties.getColorPickerString("colorName.transparent")); 351 colorNameMap.put(BLACK, Properties.getColorPickerString("colorName.black")); 352 colorNameMap.put(BLUE, Properties.getColorPickerString("colorName.blue")); 353 colorNameMap.put(CYAN, Properties.getColorPickerString("colorName.cyan")); 354 colorNameMap.put(DARKBLUE, Properties.getColorPickerString("colorName.darkblue")); 355 colorNameMap.put(DARKCYAN, Properties.getColorPickerString("colorName.darkcyan")); 356 colorNameMap.put(DARKGRAY, Properties.getColorPickerString("colorName.darkgray")); 357 colorNameMap.put(DARKGREEN, Properties.getColorPickerString("colorName.darkgreen")); 358 colorNameMap.put(DARKMAGENTA, Properties.getColorPickerString("colorName.darkmagenta")); 359 colorNameMap.put(DARKRED, Properties.getColorPickerString("colorName.darkred")); 360 colorNameMap.put(GRAY, Properties.getColorPickerString("colorName.gray")); 361 colorNameMap.put(GREEN, Properties.getColorPickerString("colorName.green")); 362 colorNameMap.put(LIGHTBLUE, Properties.getColorPickerString("colorName.lightblue")); 363 colorNameMap.put(LIGHTCYAN, Properties.getColorPickerString("colorName.lightcyan")); 364 colorNameMap.put(LIGHTGRAY, Properties.getColorPickerString("colorName.lightgray")); 365 colorNameMap.put(LIGHTGREEN, Properties.getColorPickerString("colorName.lightgreen")); 366 colorNameMap.put(LIGHTYELLOW, Properties.getColorPickerString("colorName.lightyellow")); 367 colorNameMap.put(MAGENTA, Properties.getColorPickerString("colorName.magenta")); 368 colorNameMap.put(MEDIUMBLUE, Properties.getColorPickerString("colorName.mediumblue")); 369 colorNameMap.put(ORANGE, Properties.getColorPickerString("colorName.orange")); 370 colorNameMap.put(PINK, Properties.getColorPickerString("colorName.pink")); 371 colorNameMap.put(RED, Properties.getColorPickerString("colorName.red")); 372 colorNameMap.put(WHITE, Properties.getColorPickerString("colorName.white")); 373 colorNameMap.put(YELLOW, Properties.getColorPickerString("colorName.yellow")); 374 375 // CSS names. 376 // Note that synonyms (such as "grey") have been removed here, 377 // since a color can be presented with only one name in this 378 // skin. If a reverse map is created for parsing names in the 379 // future, then the synonyms should be included there. For a 380 // full list of CSS names, see Color.java. 381 cssNameMap.put(ALICEBLUE, "aliceblue"); 382 cssNameMap.put(ANTIQUEWHITE, "antiquewhite"); 383 cssNameMap.put(AQUAMARINE, "aquamarine"); 384 cssNameMap.put(AZURE, "azure"); 385 cssNameMap.put(BEIGE, "beige"); 386 cssNameMap.put(BISQUE, "bisque"); 387 cssNameMap.put(BLACK, "black"); 388 cssNameMap.put(BLANCHEDALMOND, "blanchedalmond"); 389 cssNameMap.put(BLUE, "blue"); 390 cssNameMap.put(BLUEVIOLET, "blueviolet"); 391 cssNameMap.put(BROWN, "brown"); 392 cssNameMap.put(BURLYWOOD, "burlywood"); 393 cssNameMap.put(CADETBLUE, "cadetblue"); 394 cssNameMap.put(CHARTREUSE, "chartreuse"); 395 cssNameMap.put(CHOCOLATE, "chocolate"); 396 cssNameMap.put(CORAL, "coral"); 397 cssNameMap.put(CORNFLOWERBLUE, "cornflowerblue"); 398 cssNameMap.put(CORNSILK, "cornsilk"); 399 cssNameMap.put(CRIMSON, "crimson"); 400 cssNameMap.put(CYAN, "cyan"); 401 cssNameMap.put(DARKBLUE, "darkblue"); 402 cssNameMap.put(DARKCYAN, "darkcyan"); 403 cssNameMap.put(DARKGOLDENROD, "darkgoldenrod"); 404 cssNameMap.put(DARKGRAY, "darkgray"); 405 cssNameMap.put(DARKGREEN, "darkgreen"); 406 cssNameMap.put(DARKKHAKI, "darkkhaki"); 407 cssNameMap.put(DARKMAGENTA, "darkmagenta"); 408 cssNameMap.put(DARKOLIVEGREEN, "darkolivegreen"); 409 cssNameMap.put(DARKORANGE, "darkorange"); 410 cssNameMap.put(DARKORCHID, "darkorchid"); 411 cssNameMap.put(DARKRED, "darkred"); 412 cssNameMap.put(DARKSALMON, "darksalmon"); 413 cssNameMap.put(DARKSEAGREEN, "darkseagreen"); 414 cssNameMap.put(DARKSLATEBLUE, "darkslateblue"); 415 cssNameMap.put(DARKSLATEGRAY, "darkslategray"); 416 cssNameMap.put(DARKTURQUOISE, "darkturquoise"); 417 cssNameMap.put(DARKVIOLET, "darkviolet"); 418 cssNameMap.put(DEEPPINK, "deeppink"); 419 cssNameMap.put(DEEPSKYBLUE, "deepskyblue"); 420 cssNameMap.put(DIMGRAY, "dimgray"); 421 cssNameMap.put(DODGERBLUE, "dodgerblue"); 422 cssNameMap.put(FIREBRICK, "firebrick"); 423 cssNameMap.put(FLORALWHITE, "floralwhite"); 424 cssNameMap.put(FORESTGREEN, "forestgreen"); 425 cssNameMap.put(GAINSBORO, "gainsboro"); 426 cssNameMap.put(GHOSTWHITE, "ghostwhite"); 427 cssNameMap.put(GOLD, "gold"); 428 cssNameMap.put(GOLDENROD, "goldenrod"); 429 cssNameMap.put(GRAY, "gray"); 430 cssNameMap.put(GREEN, "green"); 431 cssNameMap.put(GREENYELLOW, "greenyellow"); 432 cssNameMap.put(HONEYDEW, "honeydew"); 433 cssNameMap.put(HOTPINK, "hotpink"); 434 cssNameMap.put(INDIANRED, "indianred"); 435 cssNameMap.put(INDIGO, "indigo"); 436 cssNameMap.put(IVORY, "ivory"); 437 cssNameMap.put(KHAKI, "khaki"); 438 cssNameMap.put(LAVENDER, "lavender"); 439 cssNameMap.put(LAVENDERBLUSH, "lavenderblush"); 440 cssNameMap.put(LAWNGREEN, "lawngreen"); 441 cssNameMap.put(LEMONCHIFFON, "lemonchiffon"); 442 cssNameMap.put(LIGHTBLUE, "lightblue"); 443 cssNameMap.put(LIGHTCORAL, "lightcoral"); 444 cssNameMap.put(LIGHTCYAN, "lightcyan"); 445 cssNameMap.put(LIGHTGOLDENRODYELLOW, "lightgoldenrodyellow"); 446 cssNameMap.put(LIGHTGRAY, "lightgray"); 447 cssNameMap.put(LIGHTGREEN, "lightgreen"); 448 cssNameMap.put(LIGHTPINK, "lightpink"); 449 cssNameMap.put(LIGHTSALMON, "lightsalmon"); 450 cssNameMap.put(LIGHTSEAGREEN, "lightseagreen"); 451 cssNameMap.put(LIGHTSKYBLUE, "lightskyblue"); 452 cssNameMap.put(LIGHTSLATEGRAY, "lightslategray"); 453 cssNameMap.put(LIGHTSTEELBLUE, "lightsteelblue"); 454 cssNameMap.put(LIGHTYELLOW, "lightyellow"); 455 cssNameMap.put(LIME, "lime"); 456 cssNameMap.put(LIMEGREEN, "limegreen"); 457 cssNameMap.put(LINEN, "linen"); 458 cssNameMap.put(MAGENTA, "magenta"); 459 cssNameMap.put(MAROON, "maroon"); 460 cssNameMap.put(MEDIUMAQUAMARINE, "mediumaquamarine"); 461 cssNameMap.put(MEDIUMBLUE, "mediumblue"); 462 cssNameMap.put(MEDIUMORCHID, "mediumorchid"); 463 cssNameMap.put(MEDIUMPURPLE, "mediumpurple"); 464 cssNameMap.put(MEDIUMSEAGREEN, "mediumseagreen"); 465 cssNameMap.put(MEDIUMSLATEBLUE, "mediumslateblue"); 466 cssNameMap.put(MEDIUMSPRINGGREEN, "mediumspringgreen"); 467 cssNameMap.put(MEDIUMTURQUOISE, "mediumturquoise"); 468 cssNameMap.put(MEDIUMVIOLETRED, "mediumvioletred"); 469 cssNameMap.put(MIDNIGHTBLUE, "midnightblue"); 470 cssNameMap.put(MINTCREAM, "mintcream"); 471 cssNameMap.put(MISTYROSE, "mistyrose"); 472 cssNameMap.put(MOCCASIN, "moccasin"); 473 cssNameMap.put(NAVAJOWHITE, "navajowhite"); 474 cssNameMap.put(NAVY, "navy"); 475 cssNameMap.put(OLDLACE, "oldlace"); 476 cssNameMap.put(OLIVE, "olive"); 477 cssNameMap.put(OLIVEDRAB, "olivedrab"); 478 cssNameMap.put(ORANGE, "orange"); 479 cssNameMap.put(ORANGERED, "orangered"); 480 cssNameMap.put(ORCHID, "orchid"); 481 cssNameMap.put(PALEGOLDENROD, "palegoldenrod"); 482 cssNameMap.put(PALEGREEN, "palegreen"); 483 cssNameMap.put(PALETURQUOISE, "paleturquoise"); 484 cssNameMap.put(PALEVIOLETRED, "palevioletred"); 485 cssNameMap.put(PAPAYAWHIP, "papayawhip"); 486 cssNameMap.put(PEACHPUFF, "peachpuff"); 487 cssNameMap.put(PERU, "peru"); 488 cssNameMap.put(PINK, "pink"); 489 cssNameMap.put(PLUM, "plum"); 490 cssNameMap.put(POWDERBLUE, "powderblue"); 491 cssNameMap.put(PURPLE, "purple"); 492 cssNameMap.put(RED, "red"); 493 cssNameMap.put(ROSYBROWN, "rosybrown"); 494 cssNameMap.put(ROYALBLUE, "royalblue"); 495 cssNameMap.put(SADDLEBROWN, "saddlebrown"); 496 cssNameMap.put(SALMON, "salmon"); 497 cssNameMap.put(SANDYBROWN, "sandybrown"); 498 cssNameMap.put(SEAGREEN, "seagreen"); 499 cssNameMap.put(SEASHELL, "seashell"); 500 cssNameMap.put(SIENNA, "sienna"); 501 cssNameMap.put(SILVER, "silver"); 502 cssNameMap.put(SKYBLUE, "skyblue"); 503 cssNameMap.put(SLATEBLUE, "slateblue"); 504 cssNameMap.put(SLATEGRAY, "slategray"); 505 cssNameMap.put(SNOW, "snow"); 506 cssNameMap.put(SPRINGGREEN, "springgreen"); 507 cssNameMap.put(STEELBLUE, "steelblue"); 508 cssNameMap.put(TAN, "tan"); 509 cssNameMap.put(TEAL, "teal"); 510 cssNameMap.put(THISTLE, "thistle"); 511 cssNameMap.put(TOMATO, "tomato"); 512 cssNameMap.put(TRANSPARENT, "transparent"); 513 cssNameMap.put(TURQUOISE, "turquoise"); 514 cssNameMap.put(VIOLET, "violet"); 515 cssNameMap.put(WHEAT, "wheat"); 516 cssNameMap.put(WHITE, "white"); 517 cssNameMap.put(WHITESMOKE, "whitesmoke"); 518 cssNameMap.put(YELLOW, "yellow"); 519 cssNameMap.put(YELLOWGREEN, "yellowgreen"); 520 } 521 522 static String colorDisplayName(Color c) { 523 if (c != null) { 524 String displayName = colorNameMap.get(c); 525 if (displayName == null) { 526 displayName = Utils.formatHexString(c); 527 } 528 return displayName; 529 } else { 530 return null; 531 } 532 } 533 534 static String tooltipString(Color c) { 535 if (c != null) { 536 String tooltipStr = ""; 537 String displayName = colorNameMap.get(c); 538 if (displayName != null) { 539 tooltipStr += displayName + " "; 540 } 541 542 tooltipStr += Utils.formatHexString(c); 543 544 String cssName = cssNameMap.get(c); 545 if (cssName != null) { 546 tooltipStr += " (css: " + cssName + ")"; 547 } 548 return tooltipStr; 549 } else { 550 return null; 551 } 552 } 553 554 private void updateColor() { 555 final ColorPicker colorPicker = (ColorPicker)getSkinnable(); 556 colorRect.setFill(colorPicker.getValue()); 557 if (colorLabelVisible.get()) { 558 displayNode.setText(colorDisplayName(colorPicker.getValue())); 559 } else { 560 displayNode.setText(""); 561 } 562 } 563 564 565 566 /*************************************************************************** 567 * * 568 * picker-color-cell * 569 * * 570 **************************************************************************/ 571 572 private class PickerColorBox extends StackPane { 573 @Override protected void layoutChildren() { 574 final double top = snappedTopInset(); 575 final double left = snappedLeftInset(); 576 final double width = getWidth(); 577 final double height = getHeight(); 578 final double right = snappedRightInset(); 579 final double bottom = snappedBottomInset(); 580 colorRect.setX(snapPosition(colorRectX.get())); 581 colorRect.setY(snapPosition(colorRectY.get())); 582 colorRect.setWidth(snapSize(colorRectWidth.get())); 583 colorRect.setHeight(snapSize(colorRectHeight.get())); 584 if (getChildren().size() == 2) { 585 final ImageView icon = (ImageView) getChildren().get(1); 586 Pos childAlignment = StackPane.getAlignment(icon); 587 layoutInArea(icon, left, top, 588 width - left - right, height - top - bottom, 589 0, getMargin(icon), 590 childAlignment != null? childAlignment.getHpos() : getAlignment().getHpos(), 591 childAlignment != null? childAlignment.getVpos() : getAlignment().getVpos()); 592 colorRect.setLayoutX(icon.getLayoutX()); 593 colorRect.setLayoutY(icon.getLayoutY()); 594 } else { 595 Pos childAlignment = StackPane.getAlignment(colorRect); 596 layoutInArea(colorRect, left, top, 597 width - left - right, height - top - bottom, 598 0, getMargin(colorRect), 599 childAlignment != null? childAlignment.getHpos() : getAlignment().getHpos(), 600 childAlignment != null? childAlignment.getVpos() : getAlignment().getVpos()); 601 } 602 } 603 } 604 605 /*************************************************************************** 606 * * 607 * Stylesheet Handling * 608 * * 609 **************************************************************************/ 610 611 private static class StyleableProperties { 612 private static final CssMetaData<ColorPicker,Boolean> COLOR_LABEL_VISIBLE = 613 new CssMetaData<ColorPicker,Boolean>("-fx-color-label-visible", 614 BooleanConverter.getInstance(), Boolean.TRUE) { 615 616 @Override public boolean isSettable(ColorPicker n) { 617 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 618 return skin.colorLabelVisible == null || !skin.colorLabelVisible.isBound(); 619 } 620 621 @Override public StyleableProperty<Boolean> getStyleableProperty(ColorPicker n) { 622 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 623 return (StyleableProperty<Boolean>)(WritableValue<Boolean>)skin.colorLabelVisible; 624 } 625 }; 626 private static final CssMetaData<ColorPicker,Number> COLOR_RECT_WIDTH = 627 new CssMetaData<ColorPicker,Number>("-fx-color-rect-width", SizeConverter.getInstance(), 12d) { 628 @Override public boolean isSettable(ColorPicker n) { 629 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 630 return !skin.colorRectWidth.isBound(); 631 } 632 @Override public StyleableProperty<Number> getStyleableProperty(ColorPicker n) { 633 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 634 return skin.colorRectWidth; 635 } 636 }; 637 private static final CssMetaData<ColorPicker,Number> COLOR_RECT_HEIGHT = 638 new CssMetaData<ColorPicker,Number>("-fx-color-rect-height", SizeConverter.getInstance(), 12d) { 639 @Override public boolean isSettable(ColorPicker n) { 640 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 641 return !skin.colorRectHeight.isBound(); 642 } 643 @Override public StyleableProperty<Number> getStyleableProperty(ColorPicker n) { 644 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 645 return skin.colorRectHeight; 646 } 647 }; 648 private static final CssMetaData<ColorPicker,Number> COLOR_RECT_X = 649 new CssMetaData<ColorPicker,Number>("-fx-color-rect-x", SizeConverter.getInstance(), 0) { 650 @Override public boolean isSettable(ColorPicker n) { 651 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 652 return !skin.colorRectX.isBound(); 653 } 654 @Override public StyleableProperty<Number> getStyleableProperty(ColorPicker n) { 655 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 656 return skin.colorRectX; 657 } 658 }; 659 private static final CssMetaData<ColorPicker,Number> COLOR_RECT_Y = 660 new CssMetaData<ColorPicker,Number>("-fx-color-rect-y", SizeConverter.getInstance(), 0) { 661 @Override public boolean isSettable(ColorPicker n) { 662 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 663 return !skin.colorRectY.isBound(); 664 } 665 @Override public StyleableProperty<Number> getStyleableProperty(ColorPicker n) { 666 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 667 return skin.colorRectY; 668 } 669 }; 670 private static final CssMetaData<ColorPicker,String> GRAPHIC = 671 new CssMetaData<ColorPicker,String>("-fx-graphic", StringConverter.getInstance()) { 672 @Override public boolean isSettable(ColorPicker n) { 673 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 674 return !skin.imageUrl.isBound(); 675 } 676 @Override public StyleableProperty<String> getStyleableProperty(ColorPicker n) { 677 final ColorPickerSkin skin = (ColorPickerSkin) n.getSkin(); 678 return skin.imageUrl; 679 } 680 }; 681 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 682 static { 683 final List<CssMetaData<? extends Styleable, ?>> styleables = 684 new ArrayList<CssMetaData<? extends Styleable, ?>>(ComboBoxBaseSkin.getClassCssMetaData()); 685 styleables.add(COLOR_LABEL_VISIBLE); 686 styleables.add(COLOR_RECT_WIDTH); 687 styleables.add(COLOR_RECT_HEIGHT); 688 styleables.add(COLOR_RECT_X); 689 styleables.add(COLOR_RECT_Y); 690 styleables.add(GRAPHIC); 691 STYLEABLES = Collections.unmodifiableList(styleables); 692 } 693 } 694 695 /** 696 * Returns the CssMetaData associated with this class, which may include the 697 * CssMetaData of its superclasses. 698 */ 699 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 700 return StyleableProperties.STYLEABLES; 701 } 702 703 /** 704 * {@inheritDoc} 705 */ 706 @Override 707 public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { 708 return getClassCssMetaData(); 709 } 710 711 /** {@inheritDoc} */ 712 @Override protected javafx.util.StringConverter<Color> getConverter() { 713 return null; 714 } 715 716 /** 717 * ColorPicker does not use a main text field, so this method has been 718 * overridden to return null. 719 */ 720 @Override protected TextField getEditor() { 721 return null; 722 } 723 }