7124282: [macosx] Can't see table cell highlighter when the highlight border is the same color as the cell.
Reviewed-by: psadhukhan, prr
This commit is contained in:
parent
9a3cb93038
commit
bd6026c10c
src/java.desktop/macosx
classes
com/apple/laf
sun/lwawt/macosx
native/libawt_lwawt/awt
test/jdk/javax/swing/JTable/7124282
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,11 +25,21 @@
|
||||
|
||||
package com.apple.laf;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
|
||||
/**
|
||||
@ -113,22 +123,35 @@ public class AquaFocusHandler implements FocusListener, PropertyChangeListener {
|
||||
|
||||
final Color bg = c.getSelectionBackground();
|
||||
final Color fg = c.getSelectionForeground();
|
||||
|
||||
if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return;
|
||||
|
||||
if (Boolean.FALSE.equals(value)) {
|
||||
setSelectionColors(c, "Table.selectionInactiveForeground", "Table.selectionInactiveBackground");
|
||||
setSelectionColors(c, "Table.selectionInactiveForeground",
|
||||
"Table.selectionInactiveBackground");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(value)) {
|
||||
setSelectionColors(c, "Table.selectionForeground", "Table.selectionBackground");
|
||||
setSelectionColors(c, "Table.selectionForeground",
|
||||
"Table.selectionBackground");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void setSelectionColors(final JTable c, final String fgName, final String bgName) {
|
||||
|
||||
c.setSelectionForeground(UIManager.getColor(fgName));
|
||||
c.setSelectionBackground(UIManager.getColor(bgName));
|
||||
|
||||
// focus ring changes for on-the-fly accent color changes
|
||||
Color prominentFocusRing = AquaLookAndFeel.deriveProminentFocusRing(
|
||||
UIManager.getColor("Table.cellFocusRing"));
|
||||
BorderUIResource.LineBorderUIResource focusCellHighlightBorder =
|
||||
new BorderUIResource.LineBorderUIResource(prominentFocusRing, 2);
|
||||
UIManager.getDefaults().put("Table.focusCellHighlightBorder",
|
||||
focusCellHighlightBorder);
|
||||
|
||||
}
|
||||
|
||||
static void swapSelectionColors(final String prefix, final JList<?> c, final Object value) {
|
||||
@ -139,12 +162,14 @@ public class AquaFocusHandler implements FocusListener, PropertyChangeListener {
|
||||
if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return;
|
||||
|
||||
if (Boolean.FALSE.equals(value)) {
|
||||
setSelectionColors(c, "List.selectionInactiveForeground", "List.selectionInactiveBackground");
|
||||
setSelectionColors(c, "List.selectionInactiveForeground",
|
||||
"List.selectionInactiveBackground");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(value)) {
|
||||
setSelectionColors(c, "List.selectionForeground", "List.selectionBackground");
|
||||
setSelectionColors(c, "List.selectionForeground",
|
||||
"List.selectionBackground");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -506,6 +506,10 @@ public class AquaImageFactory {
|
||||
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.KEYBOARD_FOCUS_COLOR));
|
||||
}
|
||||
|
||||
public static Color getCellHighlightColorUIResource() {
|
||||
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.CELL_HIGHLIGHT_COLOR));
|
||||
}
|
||||
|
||||
public static Color getSelectionInactiveBackgroundColorUIResource() {
|
||||
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_BACKGROUND_COLOR));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -388,6 +388,9 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
|
||||
final Color focusRingColor = AquaImageFactory.getFocusRingColorUIResource();
|
||||
final Border focusCellHighlightBorder = new BorderUIResource.LineBorderUIResource(focusRingColor);
|
||||
|
||||
// for table cell highlighter
|
||||
final Color cellFocusRingColor = AquaImageFactory.getCellHighlightColorUIResource();
|
||||
|
||||
final Color windowBackgroundColor = AquaImageFactory.getWindowBackgroundColorUIResource();
|
||||
final Color panelBackgroundColor = windowBackgroundColor;
|
||||
final Color tabBackgroundColor = windowBackgroundColor;
|
||||
@ -889,7 +892,9 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
|
||||
"Table.gridColor", white, // grid line color
|
||||
"Table.focusCellBackground", textHighlightText,
|
||||
"Table.focusCellForeground", textHighlight,
|
||||
"Table.focusCellHighlightBorder", focusCellHighlightBorder,
|
||||
"Table.cellFocusRing", cellFocusRingColor,
|
||||
"Table.focusCellHighlightBorder", new BorderUIResource.LineBorderUIResource(
|
||||
deriveProminentFocusRing(cellFocusRingColor), 2),
|
||||
"Table.scrollPaneBorder", scollListBorder,
|
||||
|
||||
"Table.ancestorInputMap", aquaKeyBindings.getTableInputMap(),
|
||||
@ -1122,4 +1127,61 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
|
||||
};
|
||||
table.putDefaults(uiDefaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new cell focus ring color by changing saturation
|
||||
* and setting the brightness to 100% for incoming cellFocusRing.
|
||||
*
|
||||
* If the incoming cellFocusRingColor is equal to white/black/grayish,
|
||||
* the returned cellFocusRingColor is Light Gray. For all other colors,
|
||||
* new cellFocusRingColor (in the latter case), is obtained by adjusting
|
||||
* the saturation levels and setting the brightness to 100% of the
|
||||
* incoming cellFocusRingColor.
|
||||
*
|
||||
* @param cellFocusRingColor - the {@code Color} object
|
||||
* @return the {@code Color} object corresponding to new HSB values
|
||||
*/
|
||||
static Color deriveProminentFocusRing(Color cellFocusRingColor) {
|
||||
|
||||
// define constants
|
||||
float satLowerValue = 0.30f;
|
||||
float satUpperValue = 1.0f;
|
||||
|
||||
// saturation threshold for grayish colors
|
||||
float satGrayScale = 0.10f;
|
||||
|
||||
// used to compare with saturation value of original focus ring and
|
||||
// set it to either lower or upper saturation value
|
||||
float saturationThreshold = 0.5f;
|
||||
|
||||
// brightness always set to 100%
|
||||
float brightnessValue = 1.0f;
|
||||
|
||||
float[] hsbValues = new float[3];
|
||||
|
||||
int redValue = cellFocusRingColor.getRed();
|
||||
int greenValue = cellFocusRingColor.getGreen();
|
||||
int blueValue = cellFocusRingColor.getBlue();
|
||||
|
||||
Color.RGBtoHSB(redValue, greenValue, blueValue, hsbValues);
|
||||
|
||||
// if cellFocusRing is White/Black/Grayish
|
||||
if ((hsbValues[0] == 0 && hsbValues[1] == 0)
|
||||
|| hsbValues[1] <= satGrayScale) {
|
||||
return Color.LIGHT_GRAY;
|
||||
}
|
||||
|
||||
// if cellFocusRing color NOT White/Black/Grayish
|
||||
// saturation adjustment - saturation set to either lower or
|
||||
// upper saturation value based on current saturation level
|
||||
hsbValues[1] = hsbValues[1] >= saturationThreshold ?
|
||||
satLowerValue : satUpperValue;
|
||||
|
||||
// brightness adjustment - brightness set to 100%, always return the
|
||||
// brightest color for the new color
|
||||
hsbValues[2] = brightnessValue;
|
||||
|
||||
//create and return color corresponding to new hsbValues
|
||||
return Color.getHSBColor(hsbValues[0], hsbValues[1], hsbValues[2]);
|
||||
}
|
||||
}
|
||||
|
@ -209,16 +209,19 @@ public final class LWCToolkit extends LWToolkit {
|
||||
/*
|
||||
* System colors with default initial values, overwritten by toolkit if system values differ and are available.
|
||||
*/
|
||||
private static final int NUM_APPLE_COLORS = 4;
|
||||
private static final int NUM_APPLE_COLORS = 5;
|
||||
public static final int KEYBOARD_FOCUS_COLOR = 0;
|
||||
public static final int INACTIVE_SELECTION_BACKGROUND_COLOR = 1;
|
||||
public static final int INACTIVE_SELECTION_FOREGROUND_COLOR = 2;
|
||||
public static final int SELECTED_CONTROL_TEXT_COLOR = 3;
|
||||
public static final int CELL_HIGHLIGHT_COLOR = 4;
|
||||
|
||||
private static int[] appleColors = {
|
||||
0xFF808080, // keyboardFocusColor = Color.gray;
|
||||
0xFFC0C0C0, // secondarySelectedControlColor
|
||||
0xFF303030, // controlDarkShadowColor
|
||||
0xFFFFFFFF, // controlTextColor
|
||||
0xFF808080, // cellHighlightColor = Color.gray;
|
||||
};
|
||||
|
||||
private native void loadNativeColors(final int[] systemColors, final int[] appleColors);
|
||||
|
@ -120,6 +120,12 @@ JNI_COCOA_EXIT(env);
|
||||
}
|
||||
}
|
||||
|
||||
// added for JTable Focus Ring
|
||||
if (@available(macOS 10.14, *)) {
|
||||
appleColors[sun_lwawt_macosx_LWCToolkit_CELL_HIGHLIGHT_COLOR] = [NSColor controlAccentColor];
|
||||
} else {
|
||||
appleColors[sun_lwawt_macosx_LWCToolkit_CELL_HIGHLIGHT_COLOR] = [NSColor keyboardFocusIndicatorColor];
|
||||
}
|
||||
appleColors[sun_lwawt_macosx_LWCToolkit_KEYBOARD_FOCUS_COLOR] = [NSColor keyboardFocusIndicatorColor];
|
||||
appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_BACKGROUND_COLOR] = [NSColor secondarySelectedControlColor];
|
||||
appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_FOREGROUND_COLOR] = [NSColor controlDarkShadowColor];
|
||||
|
149
test/jdk/javax/swing/JTable/7124282/JTableFocusRingTest.java
Normal file
149
test/jdk/javax/swing/JTable/7124282/JTableFocusRingTest.java
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7124282
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
* @summary Checks whether the JTable's focus ring color's RGB color
|
||||
* diff with selectionBackground is greater in comparison to original
|
||||
* focus ring (represented by 'Table.cellFocusRing' property in Aqua LAF
|
||||
* UIDefaults).
|
||||
* @run main JTableFocusRingTest
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Arrays;
|
||||
import javax.swing.plaf.BorderUIResource.LineBorderUIResource;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
|
||||
public class JTableFocusRingTest {
|
||||
|
||||
public static void main(String[] args) throws Exception{
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
|
||||
} catch (ClassNotFoundException | InstantiationException |
|
||||
IllegalAccessException | UnsupportedLookAndFeelException e) {
|
||||
throw new RuntimeException("Unsupported Look&Feel Class");
|
||||
}
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
|
||||
float[] bckRGB = new float[3];
|
||||
float[] oldCellRingRGB = new float[3];
|
||||
float[] newCellRingRGB = new float[3];
|
||||
|
||||
Color selectionBck = null;
|
||||
Color originalRingColor = null;
|
||||
Color newRingColor = null;
|
||||
|
||||
// saturation threshold for grayish colors
|
||||
float satGrayScale = 0.10f;
|
||||
|
||||
if (UIManager.getDefaults().get("Table.selectionBackground") != null
|
||||
&& UIManager.getDefaults().get("Table.selectionBackground")
|
||||
instanceof Color) {
|
||||
selectionBck = (Color) UIManager.getDefaults()
|
||||
.get("Table.selectionBackground");
|
||||
}
|
||||
if (UIManager.getDefaults().get("Table.cellFocusRing") != null
|
||||
&& UIManager.getDefaults().get("Table.cellFocusRing")
|
||||
instanceof Color) {
|
||||
originalRingColor = (Color) UIManager.getDefaults().get("Table.cellFocusRing");
|
||||
}
|
||||
|
||||
if (UIManager.getDefaults()
|
||||
.get("Table.focusCellHighlightBorder") != null &&
|
||||
UIManager.getDefaults().get("Table.focusCellHighlightBorder")
|
||||
instanceof LineBorderUIResource) {
|
||||
LineBorderUIResource cellFocusBorderObj = (LineBorderUIResource)
|
||||
UIManager.getDefaults().get("Table.focusCellHighlightBorder");
|
||||
newRingColor = cellFocusBorderObj.getLineColor();
|
||||
}
|
||||
|
||||
if (selectionBck == null || originalRingColor == null ||
|
||||
newRingColor == null) {
|
||||
throw new RuntimeException("One or more color values are null");
|
||||
}
|
||||
System.out.println(UIManager.getLookAndFeel().toString());
|
||||
System.out.println("Selection Background Color: "
|
||||
+ selectionBck.toString());
|
||||
|
||||
System.out.println("Original FocusRing Color: "
|
||||
+ originalRingColor.toString());
|
||||
|
||||
System.out.println("Brighter FocusRing Color: "
|
||||
+ newRingColor.toString());
|
||||
|
||||
int redValue = originalRingColor.getRed();
|
||||
int greenValue = originalRingColor.getGreen();
|
||||
int blueValue = originalRingColor.getBlue();
|
||||
|
||||
float[] hsbValues = new float[3];
|
||||
Color.RGBtoHSB(redValue, greenValue, blueValue, hsbValues);
|
||||
|
||||
System.out.println("Original Focus Ring Hue, Saturation and" +
|
||||
" Brightness: "+ Arrays.toString(hsbValues));
|
||||
|
||||
// Edge case - Original Focus ring color: WHITE/BLACK/GRAY
|
||||
if (((hsbValues[0] == 0 && hsbValues[1] == 0)
|
||||
|| hsbValues[1] <= satGrayScale) &&
|
||||
newRingColor.equals(Color.LIGHT_GRAY)) {
|
||||
System.out.println("Original Focus ring color:" +
|
||||
"WHITE/BLACK/GRAYISH, Cell Focus Ring Color: LIGHT GRAY");
|
||||
System.out.println("Test case passed");
|
||||
return;
|
||||
}
|
||||
selectionBck.getRGBColorComponents(bckRGB);
|
||||
originalRingColor.getRGBColorComponents(oldCellRingRGB);
|
||||
newRingColor.getRGBColorComponents(newCellRingRGB);
|
||||
|
||||
float originalRGBDiff = calculateRGBDiff(oldCellRingRGB, bckRGB);
|
||||
float brighterRGBDiff = calculateRGBDiff(newCellRingRGB, bckRGB);
|
||||
|
||||
System.out.println("Original RGB Diff: "+ originalRGBDiff);
|
||||
System.out.println("Brighter RGB Diff: "+ brighterRGBDiff);
|
||||
|
||||
if (brighterRGBDiff <= originalRGBDiff) {
|
||||
throw new RuntimeException("Cell Focus Ring Not Visible");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* calculates the difference between individual RGB components of 2 colors
|
||||
and returns the total difference. A higher RGB difference is preferred
|
||||
for a prominent cell highlighter */
|
||||
|
||||
private static float calculateRGBDiff(float[] focusRingRGB, float[] bckRGB) {
|
||||
|
||||
float totalRGBDiff = 0;
|
||||
for (int i=0; i< focusRingRGB.length; i++) {
|
||||
totalRGBDiff += Math.abs(focusRingRGB[i] - bckRGB[i]);
|
||||
}
|
||||
return totalRGBDiff;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user