components/visual-panels/core/src/java/util/com/oracle/solaris/vp/util/swing/ColorUtil.java
changeset 827 0944d8c0158b
equal deleted inserted replaced
826:c6aad84d2493 827:0944d8c0158b
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 package com.oracle.solaris.vp.util.swing;
       
    27 
       
    28 import java.awt.*;
       
    29 import javax.swing.*;
       
    30 
       
    31 public class ColorUtil {
       
    32     //
       
    33     // Static data
       
    34     //
       
    35 
       
    36     /**
       
    37      * According to the java.awt.Component API, {@code null} should cause the
       
    38      * background of a {@code Component} to be transparent.  But buttons and
       
    39      * other components of some L∓Fs (<cough> metal <cough>)
       
    40      * paint their own background in that case.  So a completely transparent
       
    41      * color is provided here instead.
       
    42      */
       
    43     public static Color TRANSPARENT = new Color(0, 0, 0, 0);
       
    44 
       
    45     //
       
    46     // Static methods
       
    47     //
       
    48 
       
    49     /**
       
    50      * Returns a color identicial to the given color but with a new alpha.
       
    51      *
       
    52      * @param	    c
       
    53      *		    the subject color
       
    54      *
       
    55      * @param	    alpha
       
    56      *		    the alpha setting
       
    57      */
       
    58     public static Color alpha(Color c, float alpha) {
       
    59 	float[] rgb = c.getRGBColorComponents(null);
       
    60 	return new Color(rgb[0], rgb[1], rgb[2], alpha);
       
    61     }
       
    62 
       
    63     /**
       
    64      * Returns a darker version of the given color by the given factor.
       
    65      * <p>
       
    66      * Compared with {@code Color.darker()}, this method provides finer
       
    67      * control over how much to darken the given color.
       
    68      *
       
    69      * @param	    c
       
    70      *		    the subject color
       
    71      *
       
    72      * @param	    factor
       
    73      *		    a number between 0 (no change) and 1 (resulting color will
       
    74      *		    be black) inclusive
       
    75      *
       
    76      * @return	    a darker (closer to black) version of the given color
       
    77      *
       
    78      * @exception   IllegalArgumentException
       
    79      *		    if factor is not betwee 0 and 1 inclusive
       
    80      */
       
    81     public static Color darker(Color c, float factor) {
       
    82 	return blend(c, Color.BLACK, factor);
       
    83     }
       
    84 
       
    85     public static double distance(Color c1, Color c2) {
       
    86 	float[] rgb1 = c1.getRGBColorComponents(null);
       
    87 	float[] rgb2 = c2.getRGBColorComponents(null);
       
    88 
       
    89 	double x = rgb2[0] - rgb1[0];
       
    90 	double y = rgb2[1] - rgb1[1];
       
    91 	double z = rgb2[2] - rgb1[2];
       
    92 
       
    93 	return Math.sqrt(x * x + y * y + z * z);
       
    94     }
       
    95 
       
    96     /**
       
    97      * Blends the given colors by the given factor.
       
    98      *
       
    99      * @param	    cFrom
       
   100      *		    the color to blend with cTo
       
   101      *
       
   102      * @param	    cTo
       
   103      *		    the color to blend with cFrom
       
   104      *
       
   105      * @param	    factor
       
   106      *		    a number between 0 (resulting color will be {@code cFrom})
       
   107      *		    and 1 (resulting color will be {@code cTo}) inclusive, with
       
   108      *		    .5 indicating an even blend between the two
       
   109      *
       
   110      * @return	    a blend of the given colors
       
   111      *
       
   112      * @exception   IllegalArgumentException
       
   113      *		    if factor is not betwee 0 and 1 inclusive
       
   114      */
       
   115     public static Color blend(Color cFrom, Color cTo, float factor) {
       
   116 	if (factor < 0f || factor > 1f) {
       
   117 	    throw new IllegalArgumentException(
       
   118 		"factor not between 0 and 1: " + factor);
       
   119 	}
       
   120 
       
   121 	float[] rgbaFrom = cFrom.getRGBComponents(null);
       
   122 	float[] rgbaTo = cTo.getRGBComponents(null);
       
   123 
       
   124 	rgbaFrom[0] += (rgbaTo[0] - rgbaFrom[0]) * factor;
       
   125 	rgbaFrom[1] += (rgbaTo[1] - rgbaFrom[1]) * factor;
       
   126 	rgbaFrom[2] += (rgbaTo[2] - rgbaFrom[2]) * factor;
       
   127 
       
   128 	return new Color(rgbaFrom[0], rgbaFrom[1], rgbaFrom[2], rgbaFrom[3]);
       
   129     }
       
   130 
       
   131     public static Color getRandomColor() {
       
   132 	return new Color(
       
   133 	    (int)(Math.random() * 256),
       
   134 	    (int)(Math.random() * 256),
       
   135 	    (int)(Math.random() * 256));
       
   136     }
       
   137 
       
   138     /**
       
   139      * Determines whether the given {@code Color} is more dark than light.
       
   140      */
       
   141     public static boolean isDark(Color c) {
       
   142 	double whiteDist = distance(c, Color.WHITE);
       
   143 	double blackDist = distance(c, Color.BLACK);
       
   144 
       
   145 	return whiteDist > blackDist;
       
   146     }
       
   147 
       
   148     /**
       
   149      * Returns a lighter version of the given color by the given
       
   150      * factor.
       
   151      * <p>
       
   152      * Compared with {@code Color.brighter()}, this method provides finer
       
   153      * control over how much to lighten the given color.
       
   154      * <p>
       
   155      * Note: When {@code factor &gt; 0}, this method differs functionally from
       
   156      * {@code Color.brighter()} - repeated invocations of the former for any
       
   157      * color will eventually yield white, whereas the latter will just create a
       
   158      * brighter version of the same color.  For "pure" colors (zero r, g, or b),
       
   159      * repeated invocations of {@code Color.brighter()} will never yield white.
       
   160      *
       
   161      * @param	    c
       
   162      *		    the subject color
       
   163      *
       
   164      * @param	    factor
       
   165      *		    a number between 0 (no change) and 1 (resulting color will
       
   166      *		    be white) inclusive
       
   167      *
       
   168      * @return	    a lighter (closer to white) version of the given color
       
   169      *
       
   170      * @exception   IllegalArgumentException
       
   171      *		    if factor is not betwee 0 and 1 inclusive
       
   172      */
       
   173     public static Color lighter(Color c, float factor) {
       
   174 	return blend(c, Color.WHITE, factor);
       
   175     }
       
   176 
       
   177     public static void main(String args[]) {
       
   178 	Color color = Color.RED;
       
   179 	JPanel panel = new JPanel();
       
   180 	panel.setLayout(new GridLayout(0, 1, 5, 5));
       
   181 	for (int i = -10; i <= 10; i++) {
       
   182 	    float factor = (float)i / (float)10;
       
   183 	    Color lighter = i < 0 ?
       
   184 		darker(color, -factor) : lighter(color, factor);
       
   185 	    JLabel l = new JLabel(factor + ": " + lighter.toString());
       
   186 	    l.setBackground(lighter);
       
   187 	    l.setForeground(isDark(lighter) ? Color.WHITE : Color.BLACK);
       
   188 	    l.setOpaque(true);
       
   189 	    panel.add(l);
       
   190 	}
       
   191 
       
   192 	JFrame frame = new JFrame();
       
   193 	Container c = frame.getContentPane();
       
   194 	c.setLayout(new BorderLayout());
       
   195 	c.add(new JScrollPane(panel), BorderLayout.CENTER);
       
   196 	frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       
   197 	frame.pack();
       
   198 	frame.setVisible(true);
       
   199     }
       
   200 }