View Javadoc

1   /* Open Log Viewer
2    *
3    * Copyright 2011
4    *
5    * This file is part of the OpenLogViewer project.
6    *
7    * OpenLogViewer software is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation, either version 3 of the License, or
10   * (at your option) any later version.
11   *
12   * OpenLogViewer software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with any OpenLogViewer software.  If not, see http://www.gnu.org/licenses/
19   *
20   * I ask that if you make any changes to this file you fork the code on github.com!
21   *
22   */
23  package org.diyefi.openlogviewer.coloring;
24  
25  import java.awt.Color;
26  import java.util.List;
27  import java.util.LinkedList;
28  import java.util.ListIterator;
29  
30  /**
31   * InitialLineColoring is used to provide the coloring for the GenericDataElements.
32   * The colors provided should be the most contrasting colors possible.
33   * @author Ben Fenner
34   */
35  public enum InitialLineColoring {
36  
37  	INSTANCE;
38  	// ALMOST_ONE is used to seed colorList with a red that will stay at the end of
39  	// the list. If you create a Color with a hue of 1F then it actually gets
40  	// created as a Color with a hue of 0F which is identical to the red at the
41  	// beginning of the list, which prevents it working as a good book-end.
42  	// 0.999F must be used instead of 0.9999F or more because it will get rounded
43  	// by the Color constructor to 1F.
44  	private static final float ALMOST_ONE = 0.999F;
45  	private static final float THREE = 3F;
46  	private static final float ONE_THIRD = 1F / THREE;
47  	private static final float TWO_THIRDS = 2F / THREE;
48  
49  	private final List<Color> colorList;
50  	private final Color bookEndRed = Color.getHSBColor(ALMOST_ONE, 1.0F, 1.0F);
51  
52  	private InitialLineColoring() {
53  		colorList = new LinkedList<Color>();
54  		colorList.add(0, bookEndRed); // Seed with high value red
55  	}
56  
57  	public Color getBestAvailableColor() {
58  		Color newColor;
59  		int index = 0;
60  
61  		final Color seedRed = Color.getHSBColor(0.0F, 1.0F, 1.0F);
62  		final Color seedGreen = Color.getHSBColor(ONE_THIRD, 1.0F, 1.0F);
63  		final Color seedBlue = Color.getHSBColor(TWO_THIRDS, 1.0F, 1.0F);
64  		if (!colorList.contains(seedRed)) { // Seed with low value red
65  			newColor = seedRed;
66  			index = 0;
67  		} else if (!colorList.contains(seedGreen)) { // Seed with green
68  			newColor = seedGreen;
69  			index = 1;
70  		} else if (!colorList.contains(seedBlue)) { // Seed with blue
71  			newColor = seedBlue;
72  			index = 2;
73  		} else {
74  
75  			float hue = 0.0F;
76  			float maxDistance = 0.0F;
77  			final ListIterator<Color> i = colorList.listIterator();
78  			Color c2;
79  
80  			while (i.hasNext()) {
81  				final Color c1 = i.next();
82  
83  				if (i.hasNext()) {
84  					c2 = i.next();
85  					i.previous();
86  				} else {
87  					c2 = colorList.get(colorList.size() - 1);
88  				}
89  				final float[] hsbValues1 = Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), null);
90  				final float[] hsbValues2 = Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(), null);
91  				final float distance = hsbValues2[0] - hsbValues1[0];
92  				if (distance > maxDistance) {
93  					maxDistance = distance;
94  					index = colorList.indexOf(c2);
95  					hue = hsbValues1[0] + (distance / 2.0F);
96  				}
97  			}
98  			newColor = Color.getHSBColor(hue, 1.0F, 1.0F);
99  		}
100 		colorList.add(index, newColor);
101 		return newColor;
102 	}
103 
104 	public boolean giveBackColor(final Color c) {
105 		return colorList.remove(c);
106 	}
107 
108 	public void giveBackAllColors() {
109 		while (!colorList.isEmpty()) {
110 			colorList.remove(0);
111 		}
112 		colorList.add(0, bookEndRed);
113 	}
114 }