2
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Substance Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.substance.internal.utils;
33
import java.awt.MultipleGradientPaint.CycleMethod;
34
import java.awt.geom.*;
35
import java.awt.image.*;
38
import javax.swing.text.JTextComponent;
40
import org.pushingpixels.lafwidget.LafWidgetUtilities;
41
import org.pushingpixels.substance.api.*;
42
import org.pushingpixels.substance.api.SubstanceConstants.Side;
43
import org.pushingpixels.substance.api.painter.border.FlatBorderPainter;
44
import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter;
45
import org.pushingpixels.substance.api.painter.fill.SubstanceFillPainter;
46
import org.pushingpixels.substance.api.watermark.SubstanceWatermark;
47
import org.pushingpixels.substance.internal.colorscheme.ShiftColorScheme;
48
import org.pushingpixels.substance.internal.painter.SimplisticFillPainter;
49
import org.pushingpixels.substance.internal.utils.filters.*;
52
* Provides utility functions for creating various images for <b>Substance </b>
53
* look and feel. This class is <b>for internal use only</b>.
55
* @author Kirill Grouchnikov
57
public final class SubstanceImageCreator {
59
* Custom fill painter for filling the checkmarks of checkboxes and radio
62
* @author Kirill Grouchnikov
64
public static class SimplisticSoftBorderReverseFillPainter extends
65
SimplisticFillPainter {
69
public static final SubstanceFillPainter INSTANCE = new SimplisticSoftBorderReverseFillPainter();
72
* Private constructor.
74
private SimplisticSoftBorderReverseFillPainter() {
78
public String getDisplayName() {
79
return "Simplistic Soft Border Reverse";
83
public Color getTopFillColor(SubstanceColorScheme fillScheme) {
84
return super.getBottomFillColor(fillScheme);
88
public Color getBottomFillColor(SubstanceColorScheme fillScheme) {
89
return super.getTopFillColor(fillScheme);
94
* Paints border instance of specified dimensions and status.
101
* Component left X (in graphics context).
103
* Component top Y (in graphics context).
110
* @param borderScheme
111
* border color scheme.
113
public static void paintBorder(Component c, Graphics2D graphics, int x,
114
int y, int width, int height, float radius,
115
SubstanceColorScheme borderScheme) {
117
SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
118
.getBorderPainter(c);
119
graphics.translate(x, y);
120
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
121
int borderDelta = (int) Math.floor(SubstanceSizeUtils
122
.getBorderStrokeWidth(componentFontSize) / 2.0);
123
Shape contour = SubstanceOutlineUtilities.getBaseOutline(width, height,
124
radius, null, borderDelta);
125
int borderThickness = (int) SubstanceSizeUtils
126
.getBorderStrokeWidth(componentFontSize);
127
boolean skipInnerBorder = (c instanceof JTextComponent)
128
|| ((SwingUtilities.getAncestorOfClass(CellRendererPane.class,
129
c) != null) && (SwingUtilities.getAncestorOfClass(
130
JFileChooser.class, c) != null));
131
GeneralPath contourInner = skipInnerBorder ? null
132
: SubstanceOutlineUtilities.getBaseOutline(width, height,
133
radius - borderThickness, null, borderThickness
135
borderPainter.paintBorder(graphics, c, width, height, contour,
136
contourInner, borderScheme);
137
graphics.translate(-x, -y);
141
* Paints border instance of specified dimensions and status.
148
* Component left X (in graphics context).
150
* Component top Y (in graphics context).
157
* @param borderScheme
158
* Border color scheme.
160
public static void paintTextComponentBorder(JComponent c,
161
Graphics graphics, int x, int y, int width, int height,
162
float radius, SubstanceColorScheme borderScheme) {
164
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
165
int borderDelta = (int) Math.floor(SubstanceSizeUtils
166
.getBorderStrokeWidth(componentFontSize) / 2.0);
167
Shape contour = SubstanceOutlineUtilities
168
.getBaseOutline(width, height, radius,
169
SubstanceCoreUtilities.getSides(c,
170
SubstanceLookAndFeel.BUTTON_SIDE_PROPERTY),
172
int borderThickness = (int) SubstanceSizeUtils
173
.getBorderStrokeWidth(componentFontSize);
174
GeneralPath contourInner = SubstanceOutlineUtilities.getBaseOutline(
175
width, height, radius - borderThickness, null, borderThickness
178
Graphics2D g2d = (Graphics2D) graphics.create();
181
ComponentState stateForOuterBorder = c.isEnabled() ? ComponentState.ENABLED
182
: ComponentState.DISABLED_UNSELECTED;
183
Color lightColor = SubstanceColorUtilities.getDefaultBackgroundColor(c,
184
stateForOuterBorder);
186
if (stateForOuterBorder.isDisabled()) {
187
float alpha = SubstanceColorSchemeUtilities.getAlpha(c,
188
stateForOuterBorder);
189
lightColor = SubstanceColorUtilities.getAlphaColor(lightColor,
190
(int) (255 * alpha));
193
Color outerColor = SubstanceColorUtilities
194
.getOuterTextComponentBorderColor(lightColor);
195
float[] hsb = Color.RGBtoHSB(lightColor.getRed(),
196
lightColor.getGreen(), lightColor.getBlue(), null);
197
// hsb[1] = hsb[1] * 0.5f;
198
// System.out.println(lightColor + " -> " + hsb[1] + ":" + hsb[2]);
199
double bottomInnerBlend = 0.85;
200
double topInnerBlend = 0.8;
202
bottomInnerBlend = 0.6;
203
topInnerBlend = 0.95;
204
} else if (hsb[2] < 0.5f) {
205
bottomInnerBlend = 0.8;
206
} else if (hsb[2] < 0.75f) {
207
bottomInnerBlend = 0.7;
210
Color darkColor = borderScheme.getDarkColor();
212
Color topInnerColor = SubstanceColorUtilities.getInterpolatedColor(
213
darkColor, lightColor, topInnerBlend);
214
Color bottomInnerColor = SubstanceColorUtilities.getInterpolatedColor(
215
lightColor, darkColor, bottomInnerBlend);
217
// darkColor = SubstanceColorUtilities.getAlphaColor(darkColor, 196);
219
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
220
RenderingHints.VALUE_ANTIALIAS_ON);
221
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
222
RenderingHints.VALUE_STROKE_NORMALIZE);
224
float strokeWidth = SubstanceSizeUtils
225
.getBorderStrokeWidth(SubstanceSizeUtils
226
.getComponentFontSize(c));
227
g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_BUTT,
228
BasicStroke.JOIN_ROUND));
230
g2d.setPaint(new GradientPaint(0, 0, outerColor, 0, height, outerColor));
231
// g2d.setColor(Color.red);
233
g2d.setPaint(new GradientPaint(0, 0, topInnerColor, 0, height,
235
// g2d.setColor(Color.green);
236
g2d.draw(contourInner);
238
// System.out.println("Outer : " + outerColor + "[" + lightColor
239
// + "] from " + borderScheme.getDisplayName());
245
* Retrieves check mark image.
248
* Check mark dimension.
252
* Color scheme for the check mark.
253
* @param checkMarkVisibility
254
* Checkmark visibility in 0.0-1.0 range.
255
* @return Check mark image.
257
private static BufferedImage getCheckMark(int dimension, boolean isEnabled,
258
SubstanceColorScheme scheme, float checkMarkVisibility) {
259
BufferedImage result = SubstanceCoreUtilities.getBlankImage(dimension,
262
// get graphics and set hints
263
Graphics2D graphics = (Graphics2D) result.getGraphics();
264
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
265
RenderingHints.VALUE_ANTIALIAS_ON);
267
// create curved checkbox path
268
GeneralPath path = new GeneralPath();
270
path.moveTo(0.25f * dimension, 0.5f * dimension);
271
path.quadTo(0.37f * dimension, 0.6f * dimension, 0.47f * dimension,
273
path.quadTo(0.55f * dimension, 0.5f * dimension, 0.85f * dimension, 0f);
275
// compute the x-based clip for the visibility
276
float xClipStart = 0.15f * dimension;
277
float xClipEnd = 0.95f * dimension;
279
float xClipRealEnd = xClipStart + (xClipEnd - xClipStart)
280
* checkMarkVisibility;
282
graphics.setClip(0, 0, (int) Math.ceil(xClipRealEnd), dimension);
284
graphics.setColor(SubstanceColorUtilities.getMarkColor(scheme,
286
Stroke stroke = new BasicStroke((float) 0.15 * dimension,
287
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
288
graphics.setStroke(stroke);
295
* Returns arrow icon for the specified parameters.
302
* Arrow icon color scheme.
303
* @return Arrow icon.
305
public static Icon getArrowIcon(int fontSize, int direction,
306
SubstanceColorScheme colorScheme) {
307
float width = SubstanceSizeUtils.getArrowIconWidth(fontSize);
308
float height = SubstanceSizeUtils.getArrowIconHeight(fontSize);
309
if (direction == SwingConstants.CENTER)
311
float strokeWidth = SubstanceSizeUtils.getArrowStrokeWidth(fontSize);
312
return new ImageIcon(getArrow(width, height, strokeWidth, direction,
317
* Retrieves arrow icon.
328
* Color scheme for the arrow.
329
* @return Arrow image.
330
* @see SwingConstants#NORTH
331
* @see SwingConstants#WEST
332
* @see SwingConstants#SOUTH
333
* @see SwingConstants#EAST
335
public static Icon getArrowIcon(float width, float height,
336
float strokeWidth, int direction, SubstanceColorScheme scheme) {
337
return new ImageIcon(getArrow(width, height, strokeWidth, direction,
342
* Retrieves arrow image.
353
* Color scheme for the arrow.
354
* @return Arrow image.
355
* @see SwingConstants#NORTH
356
* @see SwingConstants#WEST
357
* @see SwingConstants#SOUTH
358
* @see SwingConstants#EAST
359
* @see SwingConstants#CENTER
361
public static BufferedImage getArrow(float width, float height,
362
float strokeWidth, int direction, SubstanceColorScheme scheme) {
363
BufferedImage arrowImage = SubstanceCoreUtilities.getBlankImage(
364
(int) width, (int) height);
366
// System.out.println(width + ":" + height + ":" + strokeWidth);
368
// get graphics and set hints
369
Graphics2D graphics = (Graphics2D) arrowImage.getGraphics();
371
// graphics.setColor(Color.red);
372
// graphics.fillRect(0, 0, width, height);
374
graphics.translate(1, 1);
377
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
378
RenderingHints.VALUE_ANTIALIAS_ON);
380
Color arrowColor = SubstanceColorUtilities.getMarkColor(scheme, true);
382
graphics.setColor(arrowColor);
383
int cap = (width < 15) ? BasicStroke.CAP_BUTT : BasicStroke.CAP_ROUND;
384
Stroke stroke = new BasicStroke(strokeWidth, cap,
385
BasicStroke.JOIN_MITER);
387
graphics.setStroke(stroke);
389
int cushion = (int) strokeWidth / 2;
390
if (direction == SwingConstants.CENTER) {
391
BufferedImage top = getArrow(width, height / 2, strokeWidth,
392
SwingConstants.NORTH, scheme);
393
BufferedImage bottom = getArrow(width, height / 2, strokeWidth,
394
SwingConstants.SOUTH, scheme);
395
graphics.drawImage(top, 0, 1, null);
396
graphics.drawImage(bottom, 0, (int) height / 2 - 1, null);
399
GeneralPath gp = new GeneralPath();
400
gp.moveTo(cushion, strokeWidth);
401
gp.lineTo((float) 0.5 * (width - 1), height - 1 - cushion);
402
gp.lineTo(width - 1 - cushion, strokeWidth);
405
// graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
406
// RenderingHints.VALUE_ANTIALIAS_OFF);
407
// graphics.setStroke(new BasicStroke(1.0f, cap,
408
// BasicStroke.JOIN_MITER));
409
// graphics.setColor(Color.red);
410
// graphics.drawRect(0, 0, (int)width - 1, (int)height - 1);
412
int quadrantCounterClockwise = 0;
414
case SwingConstants.NORTH:
415
quadrantCounterClockwise = 2;
417
case SwingConstants.WEST:
418
quadrantCounterClockwise = 1;
420
case SwingConstants.SOUTH:
421
quadrantCounterClockwise = 0;
423
case SwingConstants.EAST:
424
quadrantCounterClockwise = 3;
427
BufferedImage rotatedImage = SubstanceImageCreator.getRotated(
428
arrowImage, quadrantCounterClockwise);
435
* Returns double arrow icon for the specified parameters.
442
* Arrow height delta.
443
* @param deltaStrokeWidth
444
* Arrow stroke width delta.
448
* Color scheme for the arrow.
449
* @return Double arrow icon.
451
public static Icon getDoubleArrowIconDelta(int fontSize, float deltaWidth,
452
float deltaHeight, float deltaStrokeWidth, int direction,
453
SubstanceColorScheme colorScheme) {
454
float arrowWidth = SubstanceSizeUtils.getArrowIconWidth(fontSize)
456
float arrowHeight = SubstanceSizeUtils.getArrowIconHeight(fontSize)
458
float arrowStrokeWidth = SubstanceSizeUtils
459
.getDoubleArrowStrokeWidth(fontSize) + deltaStrokeWidth;
460
return getDoubleArrowIcon(fontSize, arrowWidth, arrowHeight,
461
arrowStrokeWidth, direction, colorScheme);
465
* Retrieves arrow icon.
476
* Color scheme for the arrow.
477
* @return Arrow image.
478
* @see SwingConstants#NORTH
479
* @see SwingConstants#WEST
480
* @see SwingConstants#SOUTH
481
* @see SwingConstants#EAST
483
public static Icon getDoubleArrowIcon(int fontSize, float width,
484
float height, float strokeWidth, int direction,
485
SubstanceColorScheme colorScheme) {
486
int delta = 3 + 2 * SubstanceSizeUtils.getExtraPadding(fontSize) / 3;
487
boolean toggle = (direction == SwingConstants.WEST)
488
|| (direction == SwingConstants.EAST);
494
BufferedImage downArrowImage = SubstanceCoreUtilities.getBlankImage(
495
(int) width, (int) height);
497
BufferedImage singleArrow = getArrow(width,
498
Math.max(1, height - delta), strokeWidth, SwingConstants.SOUTH,
501
// get graphics and set hints
502
Graphics2D graphics = (Graphics2D) downArrowImage.getGraphics();
503
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
504
RenderingHints.VALUE_ANTIALIAS_ON);
506
int arrowHeight = singleArrow.getHeight();
507
int arrowWidth = singleArrow.getWidth();
508
int offset = toggle ? (int) (height - arrowHeight - delta) / 2
509
: (int) (width - arrowWidth - delta) / 2;
510
graphics.drawImage(singleArrow, 0, offset, null);
511
graphics.drawImage(singleArrow, 0, offset + delta, null);
513
int quadrantCounterClockwise = 0;
515
case SwingConstants.NORTH:
516
quadrantCounterClockwise = 2;
518
case SwingConstants.WEST:
519
quadrantCounterClockwise = 1;
521
case SwingConstants.SOUTH:
522
quadrantCounterClockwise = 0;
524
case SwingConstants.EAST:
525
quadrantCounterClockwise = 3;
528
BufferedImage arrowImage = SubstanceImageCreator.getRotated(
529
downArrowImage, quadrantCounterClockwise);
531
return new ImageIcon(arrowImage);
535
* Returns rotated image.
539
* @param quadrantClockwise
540
* Amount of quadrants to rotate in clockwise directio. The
541
* rotation angle is 90 times this value.
542
* @return Rotated image.
544
public static BufferedImage getRotated(BufferedImage bi,
545
int quadrantClockwise) {
546
quadrantClockwise = quadrantClockwise % 4;
547
int width = bi.getWidth();
548
int height = bi.getHeight();
549
if ((quadrantClockwise == 1) || (quadrantClockwise == 3)) {
550
width = bi.getHeight();
551
height = bi.getWidth();
553
BufferedImage biRot = SubstanceCoreUtilities.getBlankImage(width,
555
AffineTransform at = null;
556
switch (quadrantClockwise) {
558
at = AffineTransform.getTranslateInstance(width, 0);
559
at.rotate(Math.PI / 2);
562
at = AffineTransform.getTranslateInstance(width, height);
566
at = AffineTransform.getTranslateInstance(0, height);
567
at.rotate(-Math.PI / 2);
569
Graphics2D rotg = biRot.createGraphics();
571
rotg.setTransform(at);
572
rotg.drawImage(bi, 0, 0, null);
578
* Returns rotated image.
582
* @param quadrantClockwise
583
* Amount of quadrants to rotate in clockwise directio. The
584
* rotation angle is 90 times this value.
585
* @return Rotated image.
587
public static VolatileImage getRotated(final VolatileImage bi,
588
int quadrantClockwise) {
589
quadrantClockwise = quadrantClockwise % 4;
590
int width = bi.getWidth();
591
int height = bi.getHeight();
592
if ((quadrantClockwise == 1) || (quadrantClockwise == 3)) {
593
width = bi.getHeight();
594
height = bi.getWidth();
596
VolatileImage biRot = SubstanceCoreUtilities.getBlankVolatileImage(
598
AffineTransform at = null;
599
switch (quadrantClockwise) {
601
at = AffineTransform.getTranslateInstance(width, 0);
602
at.rotate(Math.PI / 2);
605
at = AffineTransform.getTranslateInstance(width, height);
609
at = AffineTransform.getTranslateInstance(0, height);
610
at.rotate(-Math.PI / 2);
612
Graphics2D rotg = biRot.createGraphics();
614
rotg.setTransform(at);
615
rotg.drawImage(bi, 0, 0, null);
621
* Translated the specified icon to grey scale.
625
* @return Greyscale version of the specified icon.
627
public static Icon toGreyscale(Icon icon) {
632
int width = icon.getIconWidth();
633
int height = icon.getIconHeight();
635
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
638
icon.paintIcon(null, result.getGraphics(), 0, 0);
639
return new ImageIcon(new GrayscaleFilter().filter(result, null));
643
* Makes the specified icon transparent.
650
* The alpha of the resulting image. The closer this value is to
651
* 0.0, the more transparent resulting image will be.
652
* @return Transparent version of the specified icon.
654
public static Icon makeTransparent(Component c, Icon icon, double alpha) {
659
int width = icon.getIconWidth();
660
int height = icon.getIconHeight();
662
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
664
icon.paintIcon(c, result.getGraphics(), 0, 0);
665
return new ImageIcon(new TranslucentFilter(alpha).filter(result, null));
669
// * Retrieves radio button of the specified size that matches the specified
672
// * @param component
674
// * @param dimension
675
// * Radio button dimension.
676
// * @param componentState
677
// * Component state.
678
// * @param prevState
679
// * Previous component state.
681
// * Offset on X axis - should be positive in order to see the
682
// * entire radio button.
684
// * First color scheme.
686
// * Second color scheme.
687
// * @param interpolationCyclePos
688
// * Interpolation cycle.
689
// * @param checkMarkVisibility
690
// * Checkmark visibility in 0.0-1.0 range.
691
// * @return Radio button of the specified size that matches the specified
694
// public static BufferedImage getRadioButton(JComponent component,
695
// SubstanceFillPainter fillPainter,
696
// SubstanceBorderPainter borderPainter, int dimension,
697
// ComponentState componentState, ComponentState prevState,
698
// int offsetX, SubstanceColorScheme currFillColorScheme,
699
// SubstanceColorScheme prevFillColorScheme,
700
// SubstanceColorScheme currMarkColorScheme,
701
// SubstanceColorScheme prevMarkColorScheme,
702
// SubstanceColorScheme currBorderColorScheme,
703
// SubstanceColorScheme prevBorderColorScheme,
704
// float interpolationCyclePos, float checkMarkVisibility) {
706
// // ComponentState.ColorSchemeKind kind = componentState
707
// // .getColorSchemeKind();
709
// float cyclePos = (currFillColorScheme != prevFillColorScheme) ?
710
// interpolationCyclePos
711
// : componentState.getCyclePosition();
712
// float borderCyclePos = (currBorderColorScheme != prevBorderColorScheme) ?
713
// interpolationCyclePos
714
// : componentState.getCyclePosition();
715
// float markCyclePos = (currMarkColorScheme != prevMarkColorScheme) ?
716
// interpolationCyclePos
717
// : componentState.getCyclePosition();
719
// if (componentState.getColorSchemeKind() != ColorSchemeKind.CURRENT) {
720
// fillPainter = SimplisticSoftBorderReverseFillPainter.INSTANCE;
723
// float borderThickness = SubstanceSizeUtils
724
// .getBorderStrokeWidth(dimension);
725
// int delta = (int) (borderThickness - 0.6);
726
// // System.out.println(dimension + ":" + borderThickness + ":" + delta);
728
// // float fDelta = borderThickness / 2.0f;
729
// Shape contourBorder = new Ellipse2D.Float(delta, delta, dimension - 2
730
// * delta - 1, dimension - 2 * delta - 1);
732
// BufferedImage offBackground = SubstanceCoreUtilities.getBlankImage(
733
// dimension + offsetX, dimension);
734
// Graphics2D graphics = (Graphics2D) offBackground.getGraphics();
735
// float alpha = SubstanceColorSchemeUtilities.getAlpha(component,
737
// graphics.setComposite(AlphaComposite.getInstance(
738
// AlphaComposite.SRC_OVER, alpha));
740
// graphics.translate(offsetX, 0);
741
// fillPainter.paintContourBackground(graphics, component, dimension,
742
// dimension, contourBorder, false, currFillColorScheme,
743
// prevFillColorScheme, cyclePos, true,
744
// currFillColorScheme != prevFillColorScheme);
746
// Shape contourInner = new Ellipse2D.Float(delta + borderThickness, delta
747
// + borderThickness, dimension - 2 * delta - 2 * borderThickness,
748
// dimension - 2 * delta - 2 * borderThickness);
750
// borderPainter.paintBorder(graphics, component, dimension, dimension,
751
// contourBorder, contourInner, currBorderColorScheme,
752
// prevBorderColorScheme, borderCyclePos,
753
// currBorderColorScheme != prevBorderColorScheme);
754
// graphics.setComposite(AlphaComposite.SrcOver);
755
// // graphics.translate(-offsetX, 0);
757
// float rc = dimension / 2.0f;
758
// float radius = dimension / 4.5f;
759
// // graphics.translate(offsetX, 0);
761
// graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
762
// RenderingHints.VALUE_ANTIALIAS_ON);
764
// if (componentState.isFacetActive(AnimationFacet.SELECTION)
765
// || (checkMarkVisibility > 0.0)) {
767
// Shape markOval = new Ellipse2D.Double(rc - radius, rc - radius,
768
// 2 * radius, 2 * radius);
770
// graphics.setComposite(AlphaComposite.getInstance(
771
// AlphaComposite.SRC_OVER, alpha * checkMarkVisibility));
772
// drawRadioMark(graphics, SubstanceColorUtilities
773
// .getMarkColor(currMarkColorScheme, componentState
774
// .getColorSchemeKind() != ColorSchemeKind.DISABLED),
776
// graphics.setComposite(AlphaComposite.getInstance(
777
// AlphaComposite.SRC_OVER, alpha * checkMarkVisibility
779
// drawRadioMark(graphics, SubstanceColorUtilities
780
// .getMarkColor(prevMarkColorScheme, componentState
781
// .getColorSchemeKind() != ColorSchemeKind.DISABLED),
784
// // draw ghost mark holder
785
// graphics.setPaint(new GradientPaint(rc + radius, rc - radius,
786
// currFillColorScheme.getDarkColor(), rc - radius, rc
787
// + radius, currFillColorScheme.getLightColor()));
788
// Shape markOval = new Ellipse2D.Double(rc - radius, rc - radius,
789
// 2 * radius, 2 * radius);
790
// graphics.setComposite(AlphaComposite.getInstance(
791
// AlphaComposite.SRC_OVER, alpha * 0.3f));
792
// graphics.fill(markOval);
794
// graphics.translate(-offsetX, 0);
796
// return offBackground;
800
* Retrieves radio button of the specified size that matches the specified
806
* Radio button dimension.
807
* @param componentState
810
* Offset on X axis - should be positive in order to see the
811
* entire radio button.
812
* @param fillColorScheme
813
* Color scheme for the inner fill.
814
* @param markColorScheme
815
* Color scheme for the check mark.
816
* @param borderColorScheme
817
* Color scheme for the border.
818
* @param checkMarkVisibility
819
* Check mark visibility in 0.0-1.0 range.
820
* @return Radio button of the specified size that matches the specified
823
public static BufferedImage getRadioButton(JComponent component,
824
SubstanceFillPainter fillPainter,
825
SubstanceBorderPainter borderPainter, int dimension,
826
ComponentState componentState, int offsetX,
827
SubstanceColorScheme fillColorScheme,
828
SubstanceColorScheme markColorScheme,
829
SubstanceColorScheme borderColorScheme, float checkMarkVisibility) {
831
// ComponentState.ColorSchemeKind kind = componentState
832
// .getColorSchemeKind();
834
if (!componentState.isActive()) {
835
fillPainter = SimplisticSoftBorderReverseFillPainter.INSTANCE;
838
float borderThickness = SubstanceSizeUtils
839
.getBorderStrokeWidth(dimension);
840
int delta = (int) (borderThickness - 0.6);
841
// System.out.println(dimension + ":" + borderThickness + ":" + delta);
843
// float fDelta = borderThickness / 2.0f;
844
Shape contourBorder = new Ellipse2D.Float(delta, delta, dimension - 2
845
* delta - 1, dimension - 2 * delta - 1);
847
BufferedImage offBackground = SubstanceCoreUtilities.getBlankImage(
848
dimension + offsetX, dimension);
849
Graphics2D graphics = (Graphics2D) offBackground.getGraphics();
850
float alpha = SubstanceColorSchemeUtilities.getAlpha(component,
852
graphics.setComposite(AlphaComposite.getInstance(
853
AlphaComposite.SRC_OVER, alpha));
855
graphics.translate(offsetX, 0);
856
fillPainter.paintContourBackground(graphics, component, dimension,
857
dimension, contourBorder, false, fillColorScheme, true);
859
Shape contourInner = new Ellipse2D.Float(delta + borderThickness, delta
860
+ borderThickness, dimension - 2 * delta - 2 * borderThickness,
861
dimension - 2 * delta - 2 * borderThickness);
863
borderPainter.paintBorder(graphics, component, dimension, dimension,
864
contourBorder, contourInner, borderColorScheme);
865
graphics.setComposite(AlphaComposite.SrcOver);
866
// graphics.translate(-offsetX, 0);
868
float rc = dimension / 2.0f;
869
float radius = dimension / 4.5f;
870
// graphics.translate(offsetX, 0);
872
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
873
RenderingHints.VALUE_ANTIALIAS_ON);
875
if (checkMarkVisibility > 0.0) {
877
Shape markOval = new Ellipse2D.Double(rc - radius, rc - radius,
878
2 * radius, 2 * radius);
880
graphics.setComposite(AlphaComposite.getInstance(
881
AlphaComposite.SRC_OVER, alpha * checkMarkVisibility));
882
drawRadioMark(graphics, SubstanceColorUtilities.getMarkColor(
883
markColorScheme, !componentState.isDisabled()), markOval);
885
// draw ghost mark holder
886
graphics.setPaint(new GradientPaint(rc + radius, rc - radius,
887
fillColorScheme.getDarkColor(), rc - radius, rc + radius,
888
fillColorScheme.getLightColor()));
889
Shape markOval = new Ellipse2D.Double(rc - radius, rc - radius,
890
2 * radius, 2 * radius);
891
graphics.setComposite(AlphaComposite.getInstance(
892
AlphaComposite.SRC_OVER, alpha * 0.3f));
893
graphics.fill(markOval);
895
graphics.translate(-offsetX, 0);
897
return offBackground;
910
private static void drawRadioMark(Graphics2D graphics, Color color,
912
graphics.setColor(color);
913
graphics.fill(markOval);
917
* Retrieves check box of the specified size that matches the specified
921
* Button for the check mark.
924
* @param componentState
926
* @param fillColorScheme
927
* Color scheme for the inner fill.
928
* @param markColorScheme
929
* Color scheme for the check mark.
930
* @param borderColorScheme
931
* Color scheme for the border.
932
* @param checkMarkVisibility
933
* Check mark visibility in 0.0-1.0 range.
934
* @param isCheckMarkFadingOut
935
* if <code>true</code>, the value of
936
* <code>interpolationCyclePos10</code> is used as the alpha
938
* @return Check box of the specified size that matches the specified
941
public static BufferedImage getCheckBox(AbstractButton button,
942
SubstanceFillPainter fillPainter,
943
SubstanceBorderPainter borderPainter, int dimension,
944
ComponentState componentState,
945
SubstanceColorScheme fillColorScheme,
946
SubstanceColorScheme markColorScheme,
947
SubstanceColorScheme borderColorScheme, float checkMarkVisibility,
948
boolean isCheckMarkFadingOut) {
950
// int checkMarkSize = SubstanceSizeUtils
951
// .getCheckBoxMarkSize(SubstanceSizeUtils
952
// .getComponentFontSize(button));
953
int offset = SubstanceSizeUtils
955
SubstanceSizeUtils.getComponentFontSize(button), 3, 9,
958
float cornerRadius = SubstanceSizeUtils
959
.getClassicButtonCornerRadius(SubstanceSizeUtils
960
.getComponentFontSize(button));
961
if (dimension <= 10) {
966
int contourDim = dimension - delta;
967
int borderDelta = (int) Math.floor(SubstanceSizeUtils
968
.getBorderStrokeWidth(SubstanceSizeUtils
969
.getComponentFontSize(button)) / 2.0);
970
GeneralPath contour = SubstanceOutlineUtilities.getBaseOutline(
971
contourDim, contourDim, cornerRadius, null, borderDelta);
973
if (!componentState.isActive()) {
974
fillPainter = SimplisticSoftBorderReverseFillPainter.INSTANCE;
977
BufferedImage offBackground = SubstanceCoreUtilities.getBlankImage(
978
dimension, dimension);
979
Graphics2D graphics = (Graphics2D) offBackground.getGraphics();
980
float alpha = SubstanceColorSchemeUtilities.getAlpha(button,
982
graphics.setComposite(AlphaComposite.getInstance(
983
AlphaComposite.SRC_OVER, alpha));
985
graphics.translate(delta - 1, delta - 1);
986
fillPainter.paintContourBackground(graphics, button, contourDim,
987
contourDim, contour, false, fillColorScheme, true);
989
// graphics.drawImage(background, 0, 0, null);
990
int borderThickness = (int) SubstanceSizeUtils
991
.getBorderStrokeWidth(dimension);
992
GeneralPath contourInner = SubstanceOutlineUtilities.getBaseOutline(
993
contourDim, contourDim, cornerRadius - borderThickness, null,
994
borderThickness + borderDelta);
995
borderPainter.paintBorder(graphics, button, contourDim, contourDim,
996
contour, contourInner, borderColorScheme);
997
graphics.translate(-delta, 1 - delta);
998
if (checkMarkVisibility > 0.0) {
999
if (isCheckMarkFadingOut) {
1000
graphics.setComposite(AlphaComposite.getInstance(
1001
AlphaComposite.SRC_OVER, alpha * checkMarkVisibility));
1002
checkMarkVisibility = 1.0f;
1005
BufferedImage checkMark = SubstanceImageCreator.getCheckMark(
1006
dimension - 2 * offset / 3, !componentState.isDisabled(),
1007
markColorScheme, checkMarkVisibility);
1008
graphics.drawImage(checkMark, 1 + 2 * offset / 3,
1009
(dimension < 14) ? 0 : -1, null);
1012
return offBackground;
1016
* Retrieves composite background for the specified parameters. The
1017
* composite background consists of three layers:
1019
* <li>Layer that matches the <code>increased</code> state.
1020
* <li>Layer that matches the <code>decreased</code> state.
1021
* <li>Regular layer with rounded background.
1023
* The layers are drawn in the following order:
1025
* <li>The left half of the first layer
1026
* <li>The right half of the second layer
1027
* <li>The third layer
1029
* Combined together, the layers create the image for scrollbar track with
1030
* continuation of the arrow increase and decrease buttons.
1038
* @param cornerRadius
1041
* The <code>decrease</code> button.
1043
* The <code>increase</code> button.
1045
* If <code>true</code>, the drawn halves of the first and the
1046
* second layers above will be swapped.
1048
public static void paintCompositeRoundedBackground(JComponent component,
1049
Graphics g, int width, int height, int cornerRadius,
1050
AbstractButton decrButton, AbstractButton incrButton,
1051
boolean flipSides) {
1055
if (decrButton != null) {
1056
Graphics2D graphics = (Graphics2D) g.create();
1058
graphics.clip(new Rectangle(-delta, 0, width / 2, height));
1059
graphics.translate(-delta, 0);
1061
graphics.clip(new Rectangle(width / 2, 0, width / 2 + 1, height));
1063
PairwiseButtonBackgroundDelegate.updatePairwiseBackground(graphics,
1064
decrButton, width + 2 * delta, height,
1065
flipSides ? Side.RIGHT : Side.LEFT, true);
1069
if (incrButton != null) {
1070
Graphics2D graphics = (Graphics2D) g.create();
1072
graphics.clip(new Rectangle(width / 2, 0, width / 2 + 1, height));
1074
graphics.clip(new Rectangle(-delta, 0, width / 2, height));
1075
graphics.translate(-delta, 0);
1077
PairwiseButtonBackgroundDelegate.updatePairwiseBackground(graphics,
1078
incrButton, width + 2 * delta, height,
1079
flipSides ? Side.LEFT : Side.RIGHT, true);
1085
* Overlays light-colored echo below the specified image.
1090
* Alpha channel for the echo image.
1092
* X offset of the echo.
1094
* Y offset of the echo.
1095
* @return Image with overlayed echo.
1097
private static BufferedImage overlayEcho(BufferedImage image,
1098
float echoAlpha, int offsetX, int offsetY) {
1099
int width = image.getWidth();
1100
int height = image.getHeight();
1102
// blur the original image
1103
// ConvolveOp convolve = new ConvolveOp(new Kernel(3, 3, new float[] {
1104
// .4f, .4f, .4f, .4f, .0f, .4f, .4f, .4f, .4f }),
1105
// ConvolveOp.EDGE_NO_OP, null);
1106
offsetX = offsetY = 0;
1107
BufferedImage negated = getNegated(image);
1108
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
1110
Graphics2D graphics = (Graphics2D) result.getGraphics().create();
1111
graphics.setComposite(AlphaComposite.getInstance(
1112
AlphaComposite.SRC_OVER, 0.2f * echoAlpha * echoAlpha
1114
graphics.drawImage(negated, offsetX - 1, offsetY - 1, null);
1115
graphics.drawImage(negated, offsetX + 1, offsetY - 1, null);
1116
graphics.drawImage(negated, offsetX - 1, offsetY + 1, null);
1117
graphics.drawImage(negated, offsetX + 1, offsetY + 1, null);
1118
graphics.setComposite(AlphaComposite.getInstance(
1119
AlphaComposite.SRC_OVER, 0.7f * echoAlpha * echoAlpha
1121
graphics.drawImage(negated, offsetX, offsetY - 1, null);
1122
graphics.drawImage(negated, offsetX, offsetY + 1, null);
1123
graphics.drawImage(negated, offsetX - 1, offsetY, null);
1124
graphics.drawImage(negated, offsetX + 1, offsetY, null);
1126
graphics.setComposite(AlphaComposite.getInstance(
1127
AlphaComposite.SRC_OVER, 1.0f));
1128
graphics.drawImage(image, 0, 0, null);
1135
* Returns <code>minimize</code> icon.
1138
* Color scheme for the icon.
1139
* @return <code>Minimize</code> icon.
1141
public static Icon getMinimizeIcon(SubstanceColorScheme scheme,
1142
SubstanceColorScheme backgroundScheme) {
1143
int iSize = SubstanceSizeUtils.getTitlePaneIconSize();
1144
return getMinimizeIcon(iSize, scheme, backgroundScheme);
1148
* Returns <code>minimize</code> icon.
1153
* Color scheme for the icon.
1154
* @return <code>Minimize</code> icon.
1156
public static Icon getMinimizeIcon(int iSize, SubstanceColorScheme scheme,
1157
SubstanceColorScheme backgroundScheme) {
1158
BufferedImage image = SubstanceCoreUtilities
1159
.getBlankImage(iSize, iSize);
1160
Graphics2D graphics = (Graphics2D) image.getGraphics();
1161
int start = (iSize / 4) - 2;
1162
int end = (3 * iSize / 4);// - 1;
1163
int size = end - start - 3;
1164
Color color = SubstanceColorUtilities.getMarkColor(scheme, true);
1165
graphics.setColor(color);
1166
graphics.fillRect(start + 2, end - 2, size, 3);
1168
int fgStrength = SubstanceColorUtilities.getColorBrightness(color
1170
int fgNegativeStrength = SubstanceColorUtilities
1171
.getColorBrightness(SubstanceColorUtilities
1172
.getNegativeColor(color.getRGB()));
1173
int bgStrength = SubstanceColorUtilities
1174
.getColorBrightness(backgroundScheme.getLightColor().getRGB());
1175
boolean noEcho = (fgStrength > fgNegativeStrength)
1176
&& (fgStrength < bgStrength);
1178
return new ImageIcon(SubstanceImageCreator.overlayEcho(image,
1179
noEcho ? 0 : SubstanceColorUtilities.getColorStrength(color),
1184
* Returns <code>restore</code> icon.
1187
* Color scheme for the icon.
1188
* @return <code>Restore</code> icon.
1190
public static Icon getRestoreIcon(SubstanceColorScheme scheme,
1191
SubstanceColorScheme backgroundScheme) {
1192
int iSize = SubstanceSizeUtils.getTitlePaneIconSize();
1193
BufferedImage image = SubstanceCoreUtilities
1194
.getBlankImage(iSize, iSize);
1195
Graphics2D graphics = (Graphics2D) image.getGraphics();
1196
int start = (iSize / 4) - 2;
1197
int end = (3 * iSize / 4) - 1;
1198
int size = end - start - 3;
1199
Color color = SubstanceColorUtilities.getMarkColor(scheme, true);
1200
graphics.setColor(color);
1201
graphics.drawRect(start, end - size + 1, size, size);
1202
graphics.drawLine(start, end - size + 2, start + size, end - size + 2);
1203
graphics.fillRect(end - size, start + 1, size + 1, 2);
1204
graphics.drawLine(end, start + 1, end, start + size + 1);
1205
graphics.drawLine(start + size + 2, start + size + 1, end, start + size
1208
int fgStrength = SubstanceColorUtilities.getColorBrightness(color
1210
int fgNegativeStrength = SubstanceColorUtilities
1211
.getColorBrightness(SubstanceColorUtilities
1212
.getNegativeColor(color.getRGB()));
1213
int bgStrength = SubstanceColorUtilities
1214
.getColorBrightness(backgroundScheme.getLightColor().getRGB());
1215
boolean noEcho = (fgStrength > fgNegativeStrength)
1216
&& (fgStrength < bgStrength);
1218
return new ImageIcon(SubstanceImageCreator.overlayEcho(image,
1219
noEcho ? 0 : SubstanceColorUtilities.getColorStrength(color),
1224
* Returns <code>maximize</code> icon.
1227
* Color scheme for the icon.
1228
* @return <code>Maximize</code> icon.
1230
public static Icon getMaximizeIcon(SubstanceColorScheme scheme,
1231
SubstanceColorScheme backgroundScheme) {
1232
int iSize = SubstanceSizeUtils.getTitlePaneIconSize();
1233
return getMaximizeIcon(iSize, scheme, backgroundScheme);
1237
* Returns <code>maximize</code> icon.
1242
* Color scheme for the icon.
1243
* @return <code>Maximize</code> icon.
1245
public static Icon getMaximizeIcon(int iSize, SubstanceColorScheme scheme,
1246
SubstanceColorScheme backgroundScheme) {
1247
BufferedImage image = SubstanceCoreUtilities
1248
.getBlankImage(iSize, iSize);
1249
Graphics2D graphics = (Graphics2D) image.getGraphics();
1250
int start = (iSize / 4) - 1;
1251
int end = iSize - start - 1;// (3 * iSize / 4);
1252
Color color = SubstanceColorUtilities.getMarkColor(scheme, true);
1253
graphics.setColor(color);
1254
graphics.drawRect(start, start, end - start, end - start);
1255
graphics.drawLine(start, start + 1, end, start + 1);
1257
int fgStrength = SubstanceColorUtilities.getColorBrightness(color
1259
int fgNegativeStrength = SubstanceColorUtilities
1260
.getColorBrightness(SubstanceColorUtilities
1261
.getNegativeColor(color.getRGB()));
1262
int bgStrength = SubstanceColorUtilities
1263
.getColorBrightness(backgroundScheme.getLightColor().getRGB());
1264
boolean noEcho = (fgStrength > fgNegativeStrength)
1265
&& (fgStrength < bgStrength);
1267
return new ImageIcon(SubstanceImageCreator.overlayEcho(image,
1268
noEcho ? 0 : SubstanceColorUtilities.getColorStrength(color),
1273
* Returns <code>close</code> icon.
1276
* Color scheme for the icon.
1277
* @return <code>Close</code> icon.
1279
public static Icon getCloseIcon(SubstanceColorScheme scheme,
1280
SubstanceColorScheme backgroundScheme) {
1281
return SubstanceImageCreator.getCloseIcon(
1282
SubstanceSizeUtils.getTitlePaneIconSize(), scheme,
1287
* Returns <code>close</code> icon.
1291
* @param colorScheme
1292
* Color scheme for the icon.
1293
* @return <code>Close</code> icon.
1295
public static Icon getCloseIcon(int iSize,
1296
SubstanceColorScheme colorScheme,
1297
SubstanceColorScheme backgroundScheme) {
1298
BufferedImage image = SubstanceCoreUtilities
1299
.getBlankImage(iSize, iSize);
1300
Graphics2D graphics = (Graphics2D) image.getGraphics();
1302
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1303
RenderingHints.VALUE_ANTIALIAS_ON);
1305
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1306
RenderingHints.VALUE_ANTIALIAS_OFF);
1308
int start = (iSize / 4);// - 1;
1309
int end = (3 * iSize / 4);
1311
// System.out.println(iSize + ":" + start + ":" + end);
1313
Stroke stroke = new BasicStroke(
1314
SubstanceSizeUtils.getFocusStrokeWidth(iSize),
1315
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
1317
graphics.setStroke(stroke);
1318
Color color = SubstanceColorUtilities.getMarkColor(colorScheme, true);
1319
graphics.setColor(color);
1320
graphics.drawLine(start, start, end, end);
1321
graphics.drawLine(start, end, end, start);
1323
int fgStrength = SubstanceColorUtilities.getColorBrightness(color
1325
int fgNegativeStrength = SubstanceColorUtilities
1326
.getColorBrightness(SubstanceColorUtilities
1327
.getNegativeColor(color.getRGB()));
1328
int bgStrength = SubstanceColorUtilities
1329
.getColorBrightness(backgroundScheme.getLightColor().getRGB());
1330
boolean noEcho = (fgStrength > fgNegativeStrength)
1331
&& (fgStrength < bgStrength);
1332
// System.out.println(SubstanceColorUtilities.getColorBrightness(color
1335
// + SubstanceColorUtilities
1336
// .getColorBrightness(SubstanceColorUtilities
1337
// .getNegativeColor(color.getRGB()))
1339
// + SubstanceColorUtilities.getColorBrightness(backgroundScheme
1340
// .getLightColor().getRGB()));
1342
return new ImageIcon(SubstanceImageCreator.overlayEcho(image,
1343
noEcho ? 0 : SubstanceColorUtilities.getColorStrength(color),
1348
* Paints rectangular gradient background.
1353
* Background starting X coord.
1355
* Background starting Y coord.
1359
* Background height.
1360
* @param colorScheme
1361
* Color scheme for the background.
1362
* @param borderAlpha
1365
* if <code>true</code>, the gradient will be vertical, if
1366
* <code>false</code>, the gradient will be horizontal.
1368
public static void paintRectangularBackground(Component c, Graphics g,
1369
int startX, int startY, int width, int height,
1370
SubstanceColorScheme colorScheme, float borderAlpha,
1371
boolean isVertical) {
1372
Graphics2D graphics = (Graphics2D) g.create();
1373
graphics.translate(startX, startY);
1376
LinearGradientPaint paint = new LinearGradientPaint(0, 0, 0,
1377
height, new float[] { 0.0f, 0.4f, 0.5f, 1.0f },
1378
new Color[] { colorScheme.getUltraLightColor(),
1379
colorScheme.getLightColor(),
1380
colorScheme.getMidColor(),
1381
colorScheme.getUltraLightColor() },
1382
CycleMethod.REPEAT);
1383
graphics.setPaint(paint);
1384
graphics.fillRect(0, 0, width, height);
1386
LinearGradientPaint paint = new LinearGradientPaint(0, 0, width, 0,
1387
new float[] { 0.0f, 0.4f, 0.5f, 1.0f }, new Color[] {
1388
colorScheme.getUltraLightColor(),
1389
colorScheme.getLightColor(),
1390
colorScheme.getMidColor(),
1391
colorScheme.getUltraLightColor() },
1392
CycleMethod.REPEAT);
1393
graphics.setPaint(paint);
1394
graphics.fillRect(0, 0, width, height);
1397
if (borderAlpha > 0.0f) {
1398
Graphics2D g2d = (Graphics2D) graphics.create();
1399
g2d.setComposite(LafWidgetUtilities.getAlphaComposite(null,
1400
borderAlpha, graphics));
1402
paintSimpleBorderAliased(c, g2d, width, height, colorScheme);
1410
* Paints simple border.
1418
* @param borderColorScheme
1419
* Border color scheme.
1421
public static void paintSimpleBorder(Component c, Graphics2D g2d,
1422
int width, int height, SubstanceColorScheme borderColorScheme) {
1423
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
1424
// int borderDelta = (int) Math.floor(SubstanceSizeUtils
1425
// .getBorderStrokeWidth(componentFontSize) / 2.0);
1426
// int borderDelta2 = (int) Math.floor(SubstanceSizeUtils
1427
// .getBorderStrokeWidth(componentFontSize));
1428
float borderThickness = (float) Math.floor(SubstanceSizeUtils
1429
.getBorderStrokeWidth(componentFontSize));
1431
g2d.setColor(SubstanceColorUtilities
1432
.getMidBorderColor(borderColorScheme));
1433
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1434
RenderingHints.VALUE_ANTIALIAS_ON);
1435
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
1436
RenderingHints.VALUE_STROKE_NORMALIZE);
1437
int joinKind = BasicStroke.JOIN_ROUND;
1438
int capKind = BasicStroke.CAP_BUTT;
1439
g2d.setStroke(new BasicStroke(borderThickness, capKind, joinKind));
1440
g2d.draw(new Rectangle2D.Float((borderThickness - 1.0f) / 2.0f,
1441
(borderThickness - 1.0f) / 2.0f, width - 1
1442
- (borderThickness - 1.5f), height - 1
1443
- (borderThickness - 1.5f)));
1444
// g2d.drawRect(borderDelta, borderDelta, width - 1 - borderDelta2,
1446
// - 1 - borderDelta2);
1449
public static void paintSimpleBorderAliased(Component c, Graphics2D g2d,
1450
int width, int height, SubstanceColorScheme colorScheme) {
1451
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
1452
// int borderDelta = (int) Math.floor(SubstanceSizeUtils
1453
// .getBorderStrokeWidth(componentFontSize) / 2.0);
1454
// int borderDelta2 = (int) Math.floor(SubstanceSizeUtils
1455
// .getBorderStrokeWidth(componentFontSize));
1456
float borderThickness = (float) Math.floor(SubstanceSizeUtils
1457
.getBorderStrokeWidth(componentFontSize));
1459
g2d.setColor(SubstanceColorUtilities.getMidBorderColor(colorScheme));
1460
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1461
RenderingHints.VALUE_ANTIALIAS_OFF);
1462
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
1463
RenderingHints.VALUE_STROKE_NORMALIZE);
1464
int joinKind = BasicStroke.JOIN_MITER;
1465
int capKind = BasicStroke.CAP_SQUARE;
1466
g2d.setStroke(new BasicStroke(borderThickness, capKind, joinKind));
1467
g2d.draw(new Rectangle2D.Float(borderThickness / 2.0f,
1468
borderThickness / 2.0f, width - borderThickness, height
1469
- borderThickness));
1473
* Paints rectangular gradient background with spots and optional replicated
1479
* X start coordinate.
1481
* Y start coordinate.
1485
* Background height.
1486
* @param colorScheme
1487
* Color scheme for the background.
1488
* @param stripeImage
1489
* Stripe image to replicate.
1490
* @param stripeOffset
1491
* Offset of the first stripe replication.
1492
* @param borderAlpha
1495
* Indication of horizontal / vertical orientation.
1497
public static void paintRectangularStripedBackground(Component c,
1498
Graphics g, int startX, int startY, int width, int height,
1499
SubstanceColorScheme colorScheme, BufferedImage stripeImage,
1500
int stripeOffset, float borderAlpha, boolean isVertical) {
1501
Graphics2D graphics = (Graphics2D) g.create(startX, startY, width,
1504
LinearGradientPaint paint = new LinearGradientPaint(0, 0, 0,
1505
height, new float[] { 0.0f, 0.2f, 0.5f, 0.8f, 1.0f },
1506
new Color[] { colorScheme.getDarkColor(),
1507
colorScheme.getLightColor(),
1508
colorScheme.getMidColor(),
1509
colorScheme.getLightColor(),
1510
colorScheme.getDarkColor() }, CycleMethod.REPEAT);
1511
graphics.setPaint(paint);
1512
graphics.fillRect(0, 0, width, height);
1514
if (stripeImage != null) {
1515
int stripeSize = stripeImage.getHeight();
1516
int stripeCount = width / stripeSize;
1517
stripeOffset = stripeOffset % (2 * stripeSize);
1518
for (int stripe = -2; stripe <= stripeCount; stripe += 2) {
1519
int stripePos = stripe * stripeSize + stripeOffset;
1521
graphics.drawImage(stripeImage, stripePos, 0, null);
1525
LinearGradientPaint paint = new LinearGradientPaint(0, 0, width, 0,
1526
new float[] { 0.0f, 0.2f, 0.5f, 0.8f, 1.0f }, new Color[] {
1527
colorScheme.getDarkColor(),
1528
colorScheme.getLightColor(),
1529
colorScheme.getMidColor(),
1530
colorScheme.getLightColor(),
1531
colorScheme.getDarkColor() }, CycleMethod.REPEAT);
1532
graphics.setPaint(paint);
1533
graphics.fillRect(0, 0, width, height);
1535
if (stripeImage != null) {
1536
int stripeSize = stripeImage.getWidth();
1537
int stripeCount = height / stripeSize;
1538
stripeOffset = stripeOffset % (2 * stripeSize);
1539
for (int stripe = -2; stripe <= stripeCount; stripe += 2) {
1540
int stripePos = stripe * stripeSize + stripeOffset;
1542
graphics.drawImage(stripeImage, 0, stripePos, null);
1547
if (borderAlpha > 0.0f) {
1548
Graphics2D g2d = (Graphics2D) graphics.create();
1549
g2d.setComposite(LafWidgetUtilities.getAlphaComposite(null,
1550
borderAlpha, graphics));
1552
paintSimpleBorderAliased(c, g2d, width, height, colorScheme);
1559
* Returns diagonal stripe image.
1562
* Stripe base in pixels.
1565
* @return Diagonal stripe image.
1567
public static BufferedImage getStripe(int baseSize, Color color) {
1568
int width = (int) (1.8 * baseSize);
1569
int height = baseSize;
1570
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
1572
Graphics2D graphics = (Graphics2D) result.getGraphics();
1574
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1575
RenderingHints.VALUE_ANTIALIAS_ON);
1577
Polygon polygon = new Polygon();
1578
polygon.addPoint(0, 0);
1579
polygon.addPoint(width - 1 - baseSize, 0);
1580
polygon.addPoint(width - 1, height - 1);
1581
polygon.addPoint(baseSize, height - 1);
1583
graphics.setColor(color);
1584
graphics.fillPolygon(polygon);
1585
graphics.drawPolygon(polygon);
1587
float[] BLUR = { 0.10f, 0.10f, 0.10f, 0.10f, 0.30f, 0.10f, 0.10f,
1589
ConvolveOp vBlurOp = new ConvolveOp(new Kernel(3, 3, BLUR));
1590
BufferedImage blurred = vBlurOp.filter(result, null);
1596
* Returns drag bumps image.
1600
* @param colorScheme
1605
* Drag bumps height.
1606
* @param maxNumberOfStripes
1607
* The maximum number of bump stripes (rows or columns).
1608
* @return Drag bumps image.
1610
public static BufferedImage getDragImage(Component c,
1611
SubstanceColorScheme colorScheme, int width, int height,
1612
int maxNumberOfStripes) {
1613
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
1615
Graphics2D graphics = (Graphics2D) result.getGraphics();
1617
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1618
RenderingHints.VALUE_ANTIALIAS_ON);
1620
boolean isDark = colorScheme.isDark();
1621
Color back1 = isDark ? colorScheme.getLightColor()
1622
: SubstanceColorUtilities.getInterpolatedColor(
1623
colorScheme.getLightColor(),
1624
colorScheme.getDarkColor(), 0.8);
1625
Color back2 = isDark ? colorScheme.getExtraLightColor()
1626
: SubstanceColorUtilities.getInterpolatedColor(
1627
colorScheme.getMidColor(), colorScheme.getDarkColor(),
1629
Color fore = isDark ? colorScheme.getDarkColor() : colorScheme
1630
.getUltraLightColor();
1632
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
1633
int bumpDotDiameter = SubstanceSizeUtils
1634
.getDragBumpDiameter(componentFontSize);
1635
int bumpCellSize = (int) (1.5 * bumpDotDiameter + 1);
1636
int bumpRows = Math.max(1, height / bumpCellSize - 1);
1637
int bumpColumns = Math.max(1, (width - 2) / bumpCellSize);
1638
if (maxNumberOfStripes > 0) {
1640
bumpColumns = Math.min(bumpColumns, maxNumberOfStripes);
1642
bumpRows = Math.min(bumpRows, maxNumberOfStripes);
1645
int bumpRowOffset = (height - bumpCellSize * bumpRows) / 2;
1646
int bumpColOffset = 1 + (width - bumpCellSize * bumpColumns) / 2;
1648
for (int col = 0; col < bumpColumns; col++) {
1649
int cx = bumpColOffset + col * bumpCellSize;
1650
boolean isEvenCol = (col % 2 == 0);
1651
int offsetY = isEvenCol ? 0 : bumpDotDiameter;
1652
for (int row = 0; row < bumpRows; row++) {
1653
int cy = offsetY + bumpRowOffset + row * bumpCellSize;
1654
graphics.setColor(fore);
1655
graphics.fillOval(cx + 1, cy + 1, bumpDotDiameter,
1657
// graphics.setColor(back1);
1658
graphics.setPaint(new GradientPaint(cx, cy, back1, cx
1659
+ bumpDotDiameter - 1, cy + bumpDotDiameter - 1, back2));
1660
graphics.fillOval(cx, cy, bumpDotDiameter, bumpDotDiameter);
1667
* Paints the bump dots on the split pane dividers.
1672
* Split pane divider.
1674
* X coordinate of the bump dots.
1676
* Y coordinate of the bump dots.
1678
* Width of the bump dots area.
1680
* Height of the bump dots area.
1681
* @param isHorizontal
1682
* Indicates whether the dots are horizontal.
1683
* @param colorScheme
1684
* First color scheme.
1686
public static void paintSplitDividerBumpImage(Graphics g,
1687
SubstanceSplitPaneDivider divider, int x, int y, int width,
1688
int height, boolean isHorizontal, SubstanceColorScheme colorScheme) {
1689
Graphics2D graphics = (Graphics2D) g.create();
1690
graphics.translate(x, y);
1692
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1693
RenderingHints.VALUE_ANTIALIAS_ON);
1695
int componentFontSize = SubstanceSizeUtils
1696
.getComponentFontSize(divider);
1697
int bumpDotDiameter = SubstanceSizeUtils
1698
.getBigDragBumpDiameter(componentFontSize);
1699
int bumpCellSize = (int) (1.5 * bumpDotDiameter + 1);
1700
int bumpRows = isHorizontal ? 1 : Math
1701
.max(1, height / bumpCellSize - 1);
1702
int bumpColumns = isHorizontal ? Math
1703
.max(1, (width - 2) / bumpCellSize) : 1;
1705
int bumpRowOffset = (height - bumpCellSize * bumpRows) / 2;
1706
int bumpColOffset = 1 + (width - bumpCellSize * bumpColumns) / 2;
1708
BufferedImage singleDot = SubstanceCoreUtilities.getBlankImage(
1709
bumpDotDiameter, bumpDotDiameter);
1710
Graphics2D dotGraphics = (Graphics2D) singleDot.getGraphics();
1711
dotGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1712
RenderingHints.VALUE_ANTIALIAS_ON);
1714
Color markColor = SubstanceColorUtilities.getMarkColor(colorScheme,
1715
divider.isEnabled());
1716
dotGraphics.setColor(markColor);
1717
dotGraphics.fillOval(0, 0, bumpDotDiameter, bumpDotDiameter);
1719
dotGraphics.setComposite(AlphaComposite.getInstance(
1720
AlphaComposite.SRC_OVER, 0.4f));
1721
SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
1722
.getBorderPainter(divider);
1723
borderPainter.paintBorder(dotGraphics, divider, width, height,
1724
new Ellipse2D.Float(0, 0, bumpDotDiameter - 1,
1725
bumpDotDiameter - 1), null, colorScheme);
1727
graphics.setComposite(LafWidgetUtilities.getAlphaComposite(divider,
1729
for (int col = 0; col < bumpColumns; col++) {
1730
int cx = bumpColOffset + col * bumpCellSize;
1731
for (int row = 0; row < bumpRows; row++) {
1732
int cy = bumpRowOffset + row * bumpCellSize
1733
+ (bumpCellSize - bumpDotDiameter) / 2;
1734
graphics.drawImage(singleDot, cx, cy, null);
1741
* Returns resize grip image.
1745
* @param colorScheme
1748
* Resize grip width.
1750
* Indicates whether the grips should be painted closely.
1751
* @return Resize grip image.
1753
public static BufferedImage getResizeGripImage(Component c,
1754
SubstanceColorScheme colorScheme, int dimension, boolean isCrowded) {
1755
BufferedImage result = SubstanceCoreUtilities.getBlankImage(dimension,
1757
Graphics2D graphics = (Graphics2D) result.getGraphics();
1759
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1760
RenderingHints.VALUE_ANTIALIAS_ON);
1762
boolean isDark = colorScheme.isDark();
1763
// SubstanceCoreUtilities
1764
// .getActiveScheme(null) : SubstanceCoreUtilities
1765
// .getDefaultScheme(null);
1766
Color back1 = isDark ? colorScheme.getLightColor()
1767
: SubstanceColorUtilities.getInterpolatedColor(
1768
colorScheme.getLightColor(),
1769
colorScheme.getDarkColor(), 0.8);
1770
Color back2 = isDark ? colorScheme.getExtraLightColor()
1771
: SubstanceColorUtilities.getInterpolatedColor(
1772
colorScheme.getMidColor(), colorScheme.getDarkColor(),
1774
Color fore = isDark ? colorScheme.getDarkColor() : colorScheme
1775
.getUltraLightColor();
1777
int bumpDotDiameter = SubstanceSizeUtils
1778
.getDragBumpDiameter(SubstanceSizeUtils.getComponentFontSize(c));
1779
int bumpCellSize = (int) (1.5 * bumpDotDiameter + 1);
1782
int bumpLines = dimension / bumpCellSize;
1784
int bumpOffset = (dimension - bumpCellSize * bumpLines) / 2;
1786
for (int col = 0; col < bumpLines; col++) {
1787
int cx = bumpOffset + col * bumpCellSize;
1788
for (int row = (bumpLines - col - 1); row < bumpLines; row++) {
1789
int cy = bumpOffset + row * bumpCellSize;
1790
graphics.setColor(fore);
1791
graphics.fillOval(cx + 1, cy + 1, bumpDotDiameter,
1793
// graphics.setColor(back1);
1794
graphics.setPaint(new GradientPaint(cx, cy, back1, cx
1795
+ bumpDotDiameter - 1, cy + bumpDotDiameter - 1, back2));
1796
graphics.fillOval(cx, cy, bumpDotDiameter, bumpDotDiameter);
1803
* Retrieves tree icon.
1808
* Icon fill color scheme.
1809
* @param borderScheme
1810
* Icon border color scheme.
1811
* @param isCollapsed
1813
* @return Tree icon.
1815
public static BufferedImage getTreeIcon(JTree tree,
1816
SubstanceColorScheme fillScheme, SubstanceColorScheme borderScheme,
1817
boolean isCollapsed) {
1818
int fontSize = SubstanceSizeUtils.getComponentFontSize(tree);
1819
int dim = SubstanceSizeUtils.getTreeIconSize(fontSize);
1820
BufferedImage result = SubstanceCoreUtilities.getBlankImage(dim + 2,
1822
Graphics2D graphics = (Graphics2D) result.getGraphics();
1824
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1825
RenderingHints.VALUE_ANTIALIAS_OFF);
1827
Graphics2D g2 = (Graphics2D) graphics.create();
1828
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1829
RenderingHints.VALUE_ANTIALIAS_OFF);
1830
SimplisticFillPainter gradPainter = new SimplisticSoftBorderReverseFillPainter();
1831
FlatBorderPainter fbp = new FlatBorderPainter();
1833
int borderDelta = (int) Math.floor(SubstanceSizeUtils
1834
.getBorderStrokeWidth(fontSize) / 2.0);
1835
Shape contour = SubstanceOutlineUtilities.getBaseOutline(dim - 1,
1836
dim - 1, SubstanceSizeUtils.getClassicButtonCornerRadius(dim),
1841
boolean isDark = fillScheme.isDark();
1843
fillScheme = new ShiftColorScheme(fillScheme,
1844
fillScheme.getExtraLightColor(), 0.7);
1846
gradPainter.paintContourBackground(g2, tree, dim - 1, dim - 1, contour,
1847
false, fillScheme, false);
1848
borderScheme = new ShiftColorScheme(borderScheme,
1849
isDark ? borderScheme.getUltraLightColor()
1850
: borderScheme.getLightColor(), 0.5);
1851
fbp.paintBorder(g2, tree, dim - 1, dim - 1, contour, null, borderScheme);
1853
g2.translate(-1, -1);
1855
Color signColor = isDark ? borderScheme.getUltraLightColor().brighter()
1856
.brighter() : borderScheme.getUltraDarkColor();
1857
if ((tree != null) && !tree.isEnabled())
1858
signColor = borderScheme.getForegroundColor();
1859
g2.setColor(signColor);
1861
int length = 5 * dim / 12;
1862
g2.drawLine(mid - length / 2, dim / 2, mid + length / 2, dim / 2);
1864
g2.drawLine(dim / 2, mid - length / 2, dim / 2, mid + length / 2);
1872
* Retrieves a single crayon of the specified color and dimensions for the
1873
* crayon panel in color chooser.
1876
* Crayon main color.
1881
* @return Crayon image.
1883
public static BufferedImage getSingleCrayon(Color mainColor, int width,
1885
BufferedImage image = SubstanceCoreUtilities.getBlankImage(width,
1888
int baseTop = (int) (0.2 * height);
1890
Graphics2D graphics = (Graphics2D) image.getGraphics().create();
1891
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1892
RenderingHints.VALUE_ANTIALIAS_ON);
1894
int r = mainColor.getRed();
1895
int g = mainColor.getGreen();
1896
int b = mainColor.getBlue();
1897
// light coefficient
1899
int lr = (int) (r + (255 - r) * lc);
1900
int lg = (int) (g + (255 - g) * lc);
1901
int lb = (int) (b + (255 - b) * lc);
1904
int dr = (int) ((1.0 - dc) * r);
1905
int dg = (int) ((1.0 - dc) * g);
1906
int db = (int) ((1.0 - dc) * b);
1908
Color lightColor = new Color(lr, lg, lb);
1909
Color darkColor = new Color(dr, dg, db);
1911
LinearGradientPaint paint = new LinearGradientPaint(0, 0, width, 0,
1912
new float[] { 0.0f, 0.3f, 0.5f, 0.9f, 1.0f }, new Color[] {
1913
lightColor, darkColor, darkColor, lightColor,
1914
lightColor }, CycleMethod.REPEAT);
1915
graphics.setPaint(paint);
1916
graphics.fillRect(0, baseTop, width, height);
1921
int lbwr = 128 + dr / 4;
1922
int lbwg = 128 + dg / 4;
1923
int lbwb = 128 + db / 4;
1925
Color lightStripeColor = new Color(lbwr, lbwg, lbwb);
1926
Color darkStripeColor = new Color(dbwr, dbwg, dbwb);
1928
int stripeTop = (int) (0.35 * height);
1929
int stripeHeight = (int) (0.04 * height);
1930
LinearGradientPaint stripePaint = new LinearGradientPaint(0, 0, width,
1931
0, new float[] { 0.0f, 0.3f, 0.5f, 0.9f, 1.0f }, new Color[] {
1932
lightStripeColor, darkStripeColor, darkStripeColor,
1933
lightStripeColor, lightStripeColor },
1934
CycleMethod.REPEAT);
1935
graphics.setPaint(stripePaint);
1936
graphics.fillRect(0, stripeTop, width, stripeHeight);
1938
graphics.setColor(lightStripeColor);
1939
graphics.drawRect(0, stripeTop, width - 1, stripeHeight);
1942
GeneralPath capPath = new GeneralPath();
1943
capPath.moveTo(0.5f * width - 3, 4);
1944
capPath.quadTo(0.5f * width, 0, 0.5f * width + 3, 4);
1945
capPath.lineTo(width - 3, baseTop);
1946
capPath.lineTo(2, baseTop);
1947
capPath.lineTo(0.5f * width - 3, 4);
1949
graphics.setClip(capPath);
1951
graphics.setPaint(new GradientPaint(0, baseTop / 2, lightColor,
1952
(int) (0.6 * width), baseTop, mainColor));
1953
graphics.fillRect(0, 0, width / 2, baseTop);
1954
graphics.setPaint(new GradientPaint(width, baseTop / 2, lightColor,
1955
(int) (0.4 * width), baseTop, mainColor));
1956
graphics.fillRect(width / 2, 0, width / 2, baseTop);
1958
graphics.setStroke(new BasicStroke((float) 1.3, BasicStroke.CAP_ROUND,
1959
BasicStroke.JOIN_ROUND));
1961
graphics.setClip(null);
1962
graphics.setColor(new Color(64 + dr / 2, 64 + dg / 2, 64 + db / 2, 200));
1963
graphics.drawRect(0, baseTop, width - 1, height - baseTop - 1);
1964
graphics.draw(capPath);
1974
private final static int[] crayonColors = { 0x800000, // Cayenne
1975
0x808000, // Asparagus
1978
0x000080, // Midnight
1987
0x400080, // Eggplant
1990
0x999999, // Aluminium
1992
0xff0000, // Maraschino
1995
0x00ffff, // Turquoise
1996
0x0000ff, // Blueberry
1997
0xff00ff, // Magenta
1999
0xb3b3b3, // Magnesium
2001
0xff8000, // Tangerine
2003
0x00ff80, // Sea Foam
2006
0xff0080, // Strawberry
2007
0x333333, // Tungsten
2015
0xff66ff, // Bubblegum
2017
0xe6e6e6, // Mercury
2019
0xffcc66, // Cantaloupe
2020
0xccff66, // Honeydew
2021
0x66ffcc, // Spindrift
2023
0xcc66ff, // Lavender
2024
0xff6fcf, // Carnation
2025
0x000000, // Licorice
2030
* Retrieves crayon X offset.
2034
* @return Crayon X offset.
2036
private static int crayonX(int i) {
2037
return (i % 8) * 22 + 4 + ((i / 8) % 2) * 11;
2041
* Retrieves crayon Y offset.
2045
* @return Crayon Y offset.
2047
private static int crayonY(int i) {
2048
return (i / 8) * 20 + 23;
2052
* Retrieves crayons image for the crayon panel of color chooser.
2054
* @return Crayons image.
2056
public static Image getCrayonsImage() {
2059
Image image = SubstanceCoreUtilities.getBlankImage(iw, ih);
2060
Graphics2D graphics = (Graphics2D) image.getGraphics().create();
2061
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2062
RenderingHints.VALUE_ANTIALIAS_ON);
2064
graphics.setColor(new Color(240, 240, 240));
2065
graphics.fillRect(0, 0, iw, ih);
2067
for (int i = 0; i < SubstanceImageCreator.crayonColors.length; i++) {
2068
Color crayonColor = new Color(
2069
0xff000000 | SubstanceImageCreator.crayonColors[i]);
2070
Image crayonImage = SubstanceImageCreator.getSingleCrayon(
2071
crayonColor, 22, 120);
2072
graphics.drawImage(crayonImage, SubstanceImageCreator.crayonX(i),
2073
SubstanceImageCreator.crayonY(i), null);
2076
graphics.setColor(new Color(190, 190, 190));
2077
graphics.drawRoundRect(0, 1, iw - 1, ih - 2, 4, 4);
2084
* Returns small icon representation of the specified integer value. The
2085
* remainder of dividing the integer by 16 is translated to four circles
2086
* arranged in 2*2 grid.
2089
* Integer value to represent.
2090
* @param colorScheme
2091
* Icon color scheme.
2092
* @return Icon representation of the specified integer value.
2094
public static Icon getHexaMarker(int value, SubstanceColorScheme colorScheme) {
2095
BufferedImage result = SubstanceCoreUtilities.getBlankImage(9, 9);
2098
Color offColor = null;
2099
Color onColor = null;
2100
if (colorScheme == null) {
2101
return new ImageIcon(result);
2103
boolean isDark = colorScheme.isDark();
2104
offColor = isDark ? colorScheme.getMidColor() : colorScheme
2105
.getMidColor().darker();
2106
onColor = isDark ? SubstanceColorUtilities.getInterpolatedColor(
2107
colorScheme.getUltraLightColor(), Color.white, 0.2)
2108
: colorScheme.getUltraDarkColor().darker();
2110
boolean bit1 = ((value & 0x1) != 0);
2111
boolean bit2 = ((value & 0x2) != 0);
2112
boolean bit3 = ((value & 0x4) != 0);
2113
boolean bit4 = ((value & 0x8) != 0);
2115
Graphics2D graphics = (Graphics2D) result.getGraphics().create();
2116
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2117
RenderingHints.VALUE_ANTIALIAS_ON);
2119
graphics.setColor(bit1 ? onColor : offColor);
2120
graphics.fillOval(5, 5, 4, 4);
2121
graphics.setColor(bit2 ? onColor : offColor);
2122
graphics.fillOval(5, 0, 4, 4);
2123
graphics.setColor(bit3 ? onColor : offColor);
2124
graphics.fillOval(0, 5, 4, 4);
2125
graphics.setColor(bit4 ? onColor : offColor);
2126
graphics.fillOval(0, 0, 4, 4);
2129
return new ImageIcon(result);
2133
* Returns search icon.
2137
* @param colorScheme
2138
* Icon color scheme.
2139
* @param leftToRight
2140
* LTR indication of the resulting icon.
2141
* @return Search icon.
2143
public static Icon getSearchIcon(int dimension,
2144
SubstanceColorScheme colorScheme, boolean leftToRight) {
2145
BufferedImage result = SubstanceCoreUtilities.getBlankImage(dimension,
2148
Graphics2D graphics = (Graphics2D) result.getGraphics().create();
2149
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2150
RenderingHints.VALUE_ANTIALIAS_ON);
2152
Color color = SubstanceColorUtilities.getMarkColor(colorScheme, true);
2153
graphics.setColor(color);
2155
graphics.setStroke(new BasicStroke(1.5f));
2157
int xc = (int) (0.6 * dimension);
2158
int yc = (int) (0.45 * dimension);
2159
int r = (int) (0.3 * dimension);
2161
graphics.drawOval(xc - r, yc - r, 2 * r, 2 * r);
2163
graphics.setStroke(new BasicStroke(3.0f));
2164
GeneralPath handle = new GeneralPath();
2165
handle.moveTo((float) (xc - r / Math.sqrt(2.0)), (float) (yc + r
2167
handle.lineTo(1.8f, dimension - 2.2f);
2168
graphics.draw(handle);
2170
int xc = (int) (0.4 * dimension);
2171
int yc = (int) (0.45 * dimension);
2172
int r = (int) (0.3 * dimension);
2174
graphics.drawOval(xc - r, yc - r, 2 * r, 2 * r);
2176
graphics.setStroke(new BasicStroke(3.0f));
2177
GeneralPath handle = new GeneralPath();
2178
handle.moveTo((float) (xc + r / Math.sqrt(2.0)), (float) (yc + r
2180
handle.lineTo(dimension - 2.5f, dimension - 2.2f);
2181
graphics.draw(handle);
2185
return new ImageIcon(result);
2189
* Returns an icon that matches the specified watermark.
2192
* Watermark instance.
2193
* @return Icon that matches the specified watermark.
2195
public static Icon getWatermarkIcon(SubstanceWatermark watermark) {
2196
int iSize = SubstanceSizeUtils.getTitlePaneIconSize();
2197
BufferedImage result = SubstanceCoreUtilities.getBlankImage(iSize,
2199
Graphics2D graphics = (Graphics2D) result.getGraphics().create();
2200
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2201
RenderingHints.VALUE_ANTIALIAS_ON);
2204
.previewWatermark(graphics,
2205
SubstanceColorSchemeUtilities.METALLIC_SKIN, 0, 0,
2208
return new ImageIcon(result);
2212
* Returns a lock icon that matches the specified scheme.
2216
* @return Lock icon that matches the specified scheme.
2218
public static Icon getSmallLockIcon(SubstanceColorScheme scheme, Component c) {
2219
int componentFontSize = SubstanceSizeUtils.getComponentFontSize(c);
2220
int extraPadding = SubstanceSizeUtils
2221
.getExtraPadding(componentFontSize);
2222
int width = 6 + 2 * extraPadding;
2223
int height = 9 + 2 * extraPadding;
2224
BufferedImage result = SubstanceCoreUtilities.getBlankImage(width,
2227
Color fore = scheme.getForegroundColor();
2228
Color fill = new Color(208, 208, 48);
2230
Graphics2D graphics = (Graphics2D) result.getGraphics().create();
2231
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2232
RenderingHints.VALUE_ANTIALIAS_ON);
2234
float borderStrokeWidth = SubstanceSizeUtils
2235
.getBorderStrokeWidth(componentFontSize) / 1.2f;
2236
float extraInsets = borderStrokeWidth / 2.0f;
2237
graphics.setStroke(new BasicStroke(borderStrokeWidth,
2238
BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
2240
float lockPadTop = height / 3.0f;
2241
float lockPadBottom = height - extraInsets;
2242
float lockPadLeft = extraInsets;
2243
float lockPadRight = width - extraInsets;
2246
graphics.setColor(fill);
2247
graphics.fill(new Rectangle2D.Float(lockPadLeft, lockPadTop,
2248
lockPadRight - lockPadLeft, lockPadBottom - lockPadTop));
2250
graphics.setColor(fore);
2251
graphics.draw(new Rectangle2D.Float(lockPadLeft, lockPadTop,
2252
lockPadRight - lockPadLeft, lockPadBottom - lockPadTop));
2255
graphics.setColor(fore);
2256
float lockHandleLeft = width / 4.0f;
2257
float lockHandleRight = width - width / 4.0f;
2259
GeneralPath handle = new GeneralPath();
2260
handle.moveTo(lockHandleLeft, lockPadTop);
2262
handle.lineTo(lockHandleLeft, extraInsets);
2263
// right to top-right
2264
handle.lineTo(lockHandleRight, extraInsets);
2266
handle.lineTo(lockHandleRight, lockPadTop);
2268
graphics.draw(handle);
2271
graphics.setColor(fore);
2272
float lockKeyholeTop = lockPadTop + 2 * borderStrokeWidth;
2273
float lockKeyholeBottom = lockPadBottom - 2 * borderStrokeWidth + 1;
2274
float lockKeyholeLeft = lockHandleLeft + 1;
2275
float lockKeyholeRight = lockHandleRight;
2276
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2277
RenderingHints.VALUE_ANTIALIAS_OFF);
2278
graphics.setStroke(new BasicStroke(1.0f));
2279
graphics.fill(new Rectangle2D.Float(lockKeyholeLeft, lockKeyholeTop,
2280
lockKeyholeRight - lockKeyholeLeft, lockKeyholeBottom
2284
return new ImageIcon(result);
2288
* Returns the negative of the specified image.
2292
* @return The negative of the specified image.
2294
public static BufferedImage getNegated(BufferedImage bi) {
2295
return new NegatedFilter().filter(bi, null);
2299
* Creates a new version of the specified icon that is rendered in the
2300
* colors of the specified color scheme.
2305
* The original icon.
2306
* @param colorScheme
2308
* @return Scheme-based version of the original icon.
2310
public static BufferedImage getColorSchemeImage(Component comp,
2311
Icon original, SubstanceColorScheme colorScheme,
2312
float originalBrightnessFactor) {
2313
int w = original.getIconWidth();
2314
int h = original.getIconHeight();
2315
BufferedImage origImage = SubstanceCoreUtilities.getBlankImage(w, h);
2316
original.paintIcon(comp, origImage.getGraphics(), 0, 0);
2318
return getColorSchemeImage(origImage, colorScheme,
2319
originalBrightnessFactor);
2323
* Creates a new version of the specified image that is rendered in the
2324
* colors of the specified color scheme.
2327
* The original image.
2328
* @param colorScheme
2330
* @return Scheme-based version of the original icon.
2332
public static BufferedImage getColorSchemeImage(BufferedImage original,
2333
SubstanceColorScheme colorScheme, float originalBrightnessFactor) {
2334
return ColorSchemeFilter.getColorSchemeFilter(colorScheme,
2335
originalBrightnessFactor).filter(original, null);