Skip to content

Commit 1d666e6

Browse files
author
aghaisas
committed
8177380: Add standard colors in ColorPicker color palette
Reviewed-by: nlisker, kcr
1 parent 5580e04 commit 1d666e6

File tree

4 files changed

+108
-29
lines changed

4 files changed

+108
-29
lines changed

Diff for: modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPalette.java

+91-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,7 @@ class ColorPalette extends Region {
7979
CustomColorDialog customColorDialog = null;
8080

8181
private ColorPicker colorPicker;
82+
private final GridPane standardColorGrid = new GridPane();
8283
private final GridPane customColorGrid = new GridPane();
8384
private final Separator separator = new Separator();
8485
private final Label customColorLabel = new Label(getColorPickerString("customColorLabel"));
@@ -137,6 +138,10 @@ public ColorPalette(final ColorPicker colorPicker) {
137138
});
138139

139140
initNavigation();
141+
142+
buildStandardColors();
143+
standardColorGrid.getStyleClass().add("color-picker-grid");
144+
standardColorGrid.setVisible(true);
140145
customColorGrid.getStyleClass().add("color-picker-grid");
141146
customColorGrid.setVisible(false);
142147
buildCustomColors();
@@ -148,7 +153,7 @@ public ColorPalette(final ColorPicker colorPicker) {
148153

149154
VBox paletteBox = new VBox();
150155
paletteBox.getStyleClass().add("color-palette");
151-
paletteBox.getChildren().addAll(colorPickerGrid, customColorLabel, customColorGrid, separator, customColorLink);
156+
paletteBox.getChildren().addAll(standardColorGrid, colorPickerGrid, customColorLabel, customColorGrid, separator, customColorLink);
152157

153158
hoverSquare.setMouseTransparent(true);
154159
hoverSquare.getStyleClass().addAll("hover-square");
@@ -193,6 +198,35 @@ private void setFocusedSquare(ColorSquare square) {
193198
hoverSquare.setLayoutY(snapPositionY(y) - focusedSquare.getHeight() / 2.0 + (hoverSquare.getScaleY() == 1.0 ? 0 : focusedSquare.getHeight() / 4.0));
194199
}
195200

201+
private void buildStandardColors() {
202+
// WARNING:
203+
// Make sure that the number of standard colors is equal to NUM_OF_COLUMNS
204+
// Currently, 12 standard colors are supported in a single row
205+
// Note : Creation & access logic of standardColorGrid needs to be updated
206+
// in case more colors are added as separate row(s) in future.
207+
208+
final Color[] STANDARD_COLORS = {
209+
Color.AQUA,
210+
Color.TEAL,
211+
Color.BLUE,
212+
Color.NAVY,
213+
Color.FUCHSIA,
214+
Color.PURPLE,
215+
Color.RED,
216+
Color.MAROON,
217+
Color.YELLOW,
218+
Color.OLIVE,
219+
Color.GREEN,
220+
Color.LIME
221+
};
222+
223+
standardColorGrid.getChildren().clear();
224+
225+
for (int i = 0; i < NUM_OF_COLUMNS; i++) {
226+
standardColorGrid.add(new ColorSquare(STANDARD_COLORS[i], i, ColorType.STANDARD), i, 0);
227+
}
228+
}
229+
196230
private void buildCustomColors() {
197231
final ObservableList<Color> customColors = colorPicker.getCustomColors();
198232
customColorNumber = customColors.size();
@@ -228,7 +262,7 @@ private void buildCustomColors() {
228262

229263
for (int i = 0; i < customColors.size(); i++) {
230264
Color c = customColors.get(i);
231-
ColorSquare square = new ColorSquare(c, i, true);
265+
ColorSquare square = new ColorSquare(c, i, ColorType.CUSTOM);
232266
square.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
233267
if (e.getCode() == KeyCode.DELETE) {
234268
customColors.remove(square.rectangle.getFill());
@@ -293,24 +327,37 @@ public Node select(Node owner, Direction dir, TraversalContext context) {
293327
}
294328

295329
private Node processArrow(ColorSquare owner, Direction dir) {
296-
final int row = owner.index / NUM_OF_COLUMNS;
297-
final int column = owner.index % NUM_OF_COLUMNS;
330+
int row = 0;
331+
int column = 0;
332+
333+
if (owner.colorType == ColorType.STANDARD) {
334+
row = 0;
335+
column = owner.index;
336+
} else {
337+
row = owner.index / NUM_OF_COLUMNS;
338+
column = owner.index % NUM_OF_COLUMNS;
339+
}
298340

299341
// Adjust the direction according to color picker orientation
300342
dir = dir.getDirectionForNodeOrientation(colorPicker.getEffectiveNodeOrientation());
301343
// This returns true for all the cases which we need to override
302-
if (isAtBorder(dir, row, column, owner.isCustom)) {
344+
if (isAtBorder(dir, row, column, (owner.colorType == ColorType.CUSTOM))) {
303345
// There's no other node in the direction from the square, so we need to continue on some other row
304346
// or cycle
305347
int subsequentRow = row;
306348
int subsequentColumn = column;
307-
boolean subSequentSquareCustom = owner.isCustom;
349+
boolean subSequentSquareCustom = (owner.colorType == ColorType.CUSTOM);
350+
boolean subSequentSquareStandard = (owner.colorType == ColorType.STANDARD);
308351
switch (dir) {
309352
case LEFT:
310353
case RIGHT:
311354
// The next row is either the first or the last, except when cycling in custom colors, the last row
312355
// might have different number of columns
313-
if (owner.isCustom) {
356+
if (owner.colorType == ColorType.STANDARD) {
357+
subsequentRow = 0;
358+
subsequentColumn = (dir == Direction.LEFT)? NUM_OF_COLUMNS - 1 : 0;
359+
}
360+
else if (owner.colorType == ColorType.CUSTOM) {
314361
subsequentRow = Math.floorMod(dir == Direction.LEFT ? row - 1 : row + 1, customColorRows);
315362
subsequentColumn = dir == Direction.LEFT ? subsequentRow == customColorRows - 1 ?
316363
customColorLastRowLength - 1 : NUM_OF_COLUMNS - 1 : 0;
@@ -320,7 +367,9 @@ private Node processArrow(ColorSquare owner, Direction dir) {
320367
}
321368
break;
322369
case UP: // custom color are not handled here
323-
subsequentRow = NUM_OF_ROWS - 1;
370+
if (owner.colorType == ColorType.NORMAL && row == 0) {
371+
subSequentSquareStandard = true;
372+
}
324373
break;
325374
case DOWN: // custom color are not handled here
326375
if (customColorNumber > 0) {
@@ -329,12 +378,14 @@ private Node processArrow(ColorSquare owner, Direction dir) {
329378
subsequentColumn = customColorRows > 1 ? column : Math.min(customColorLastRowLength - 1, column);
330379
break;
331380
} else {
332-
return null; // Let the default algorith handle this
381+
return null; // Let the default algorithm handle this
333382
}
334383

335384
}
336385
if (subSequentSquareCustom) {
337386
return customColorGrid.getChildren().get(subsequentRow * NUM_OF_COLUMNS + subsequentColumn);
387+
} else if (subSequentSquareStandard) {
388+
return standardColorGrid.getChildren().get(subsequentColumn);
338389
} else {
339390
return colorPickerGrid.getChildren().get(subsequentRow * NUM_OF_COLUMNS + subsequentColumn);
340391
}
@@ -359,7 +410,7 @@ private boolean isAtBorder(Direction dir, int row, int column, boolean custom) {
359410

360411
@Override
361412
public Node selectFirst(TraversalContext context) {
362-
return colorPickerGrid.getChildren().get(0);
413+
return standardColorGrid.getChildren().get(0);
363414
}
364415

365416
@Override
@@ -386,21 +437,28 @@ public boolean isCustomColorDialogShowing() {
386437
return false;
387438
}
388439

440+
441+
enum ColorType {
442+
NORMAL,
443+
STANDARD,
444+
CUSTOM
445+
};
446+
389447
class ColorSquare extends StackPane {
390448
Rectangle rectangle;
391449
int index;
392450
boolean isEmpty;
393-
boolean isCustom;
451+
ColorType colorType = ColorType.NORMAL;
394452

395453
public ColorSquare() {
396-
this(null, -1, false);
454+
this(null, -1, ColorType.NORMAL);
397455
}
398456

399457
public ColorSquare(Color color, int index) {
400-
this(color, index, false);
458+
this(color, index, ColorType.NORMAL);
401459
}
402460

403-
public ColorSquare(Color color, int index, boolean isCustom) {
461+
public ColorSquare(Color color, int index, ColorType type) {
404462
// Add style class to handle selected color square
405463
getStyleClass().add("color-square");
406464
if (color != null) {
@@ -429,7 +487,7 @@ public ColorSquare(Color color, int index, boolean isCustom) {
429487
colorPicker.hide();
430488
} else if (event.getButton() == MouseButton.SECONDARY ||
431489
event.getButton() == MouseButton.MIDDLE) {
432-
if (isCustom && contextMenu != null) {
490+
if ((colorType == ColorType.CUSTOM) && contextMenu != null) {
433491
if (!contextMenu.isShowing()) {
434492
contextMenu.show(ColorSquare.this, Side.RIGHT, 0, 0);
435493
Utils.addMnemonics(contextMenu, ColorSquare.this.getScene(), NodeHelper.isShowMnemonics(colorPicker));
@@ -442,7 +500,7 @@ public ColorSquare(Color color, int index, boolean isCustom) {
442500
});
443501
}
444502
this.index = index;
445-
this.isCustom = isCustom;
503+
this.colorType = type;
446504
rectangle = new Rectangle(SQUARE_SIZE, SQUARE_SIZE);
447505
if (color == null) {
448506
rectangle.setFill(Color.WHITE);
@@ -477,20 +535,29 @@ public void selectColor(KeyEvent event) {
477535
public void updateSelection(Color color) {
478536
setFocusedSquare(null);
479537

480-
for (ColorSquare c : colorPickerGrid.getSquares()) {
481-
if (c.rectangle.getFill().equals(color)) {
482-
setFocusedSquare(c);
538+
// Check all color grids to find ColorSquare that matches color
539+
// if found, set focus to it
540+
541+
List<GridPane> gridList = List.of(standardColorGrid, colorPickerGrid,
542+
customColorGrid);
543+
544+
for (GridPane grid : gridList) {
545+
ColorSquare sq = findColorSquare(grid, color);
546+
if (sq != null) {
547+
setFocusedSquare(sq);
483548
return;
484549
}
485550
}
486-
// check custom colors
487-
for (Node n : customColorGrid.getChildren()) {
551+
}
552+
553+
private ColorSquare findColorSquare(GridPane colorGrid, Color color) {
554+
for (Node n : colorGrid.getChildren()) {
488555
ColorSquare c = (ColorSquare) n;
489556
if (c.rectangle.getFill().equals(color)) {
490-
setFocusedSquare(c);
491-
return;
557+
return c;
492558
}
493559
}
560+
return null;
494561
}
495562

496563
class ColorPickerGrid extends GridPane {

Diff for: modules/javafx.controls/src/main/java/javafx/scene/control/skin/ColorPickerSkin.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -343,7 +343,7 @@ private void updateComboBoxMode() {
343343
}
344344
}
345345

346-
private static final Map<Color, String> colorNameMap = new HashMap<>(24);
346+
private static final Map<Color, String> colorNameMap = new HashMap<>(30);
347347
private static final Map<Color, String> cssNameMap = new HashMap<>(139);
348348
static {
349349
// Translatable display names for the most common colors
@@ -364,11 +364,17 @@ private void updateComboBoxMode() {
364364
colorNameMap.put(LIGHTGRAY, Properties.getColorPickerString("colorName.lightgray"));
365365
colorNameMap.put(LIGHTGREEN, Properties.getColorPickerString("colorName.lightgreen"));
366366
colorNameMap.put(LIGHTYELLOW, Properties.getColorPickerString("colorName.lightyellow"));
367+
colorNameMap.put(LIME, Properties.getColorPickerString("colorName.lime"));
367368
colorNameMap.put(MAGENTA, Properties.getColorPickerString("colorName.magenta"));
369+
colorNameMap.put(MAROON, Properties.getColorPickerString("colorName.maroon"));
368370
colorNameMap.put(MEDIUMBLUE, Properties.getColorPickerString("colorName.mediumblue"));
371+
colorNameMap.put(NAVY, Properties.getColorPickerString("colorName.navy"));
372+
colorNameMap.put(OLIVE, Properties.getColorPickerString("colorName.olive"));
369373
colorNameMap.put(ORANGE, Properties.getColorPickerString("colorName.orange"));
370374
colorNameMap.put(PINK, Properties.getColorPickerString("colorName.pink"));
375+
colorNameMap.put(PURPLE, Properties.getColorPickerString("colorName.purple"));
371376
colorNameMap.put(RED, Properties.getColorPickerString("colorName.red"));
377+
colorNameMap.put(TEAL, Properties.getColorPickerString("colorName.teal"));
372378
colorNameMap.put(WHITE, Properties.getColorPickerString("colorName.white"));
373379
colorNameMap.put(YELLOW, Properties.getColorPickerString("colorName.yellow"));
374380

Diff for: modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/resources/controls.properties

+6
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,17 @@ ColorPicker.colorName.lightcyan=Light Cyan
7070
ColorPicker.colorName.lightgray=Light Gray
7171
ColorPicker.colorName.lightgreen=Light Green
7272
ColorPicker.colorName.lightyellow=Light Yellow
73+
ColorPicker.colorName.lime=Lime
7374
ColorPicker.colorName.magenta=Magenta
75+
ColorPicker.colorName.maroon=Maroon
7476
ColorPicker.colorName.mediumblue=Medium Blue
77+
ColorPicker.colorName.navy=Navy
78+
ColorPicker.colorName.olive=Olive
7579
ColorPicker.colorName.orange=Orange
7680
ColorPicker.colorName.pink=Pink
81+
ColorPicker.colorName.purple=Purple
7782
ColorPicker.colorName.red=Red
83+
ColorPicker.colorName.teal=Teal
7884
ColorPicker.colorName.white=White
7985
ColorPicker.colorName.yellow=Yellow
8086

Diff for: modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/ColorPickerSkinTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -80,10 +80,10 @@ public class ColorPickerSkinTest {
8080
paletteScene.getWindow().requestFocus();
8181

8282
SceneHelper.processMouseEvent(paletteScene,
83-
generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+85, yval+40));
83+
generator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, xval+85, yval+65));
8484

8585
SceneHelper.processMouseEvent(paletteScene,
86-
generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+85, yval+40));
86+
generator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, xval+85, yval+65));
8787
tk.firePulse();
8888

8989
assertEquals(colorPicker.getValue().toString(), "0x330033ff");

0 commit comments

Comments
 (0)