diff --git a/.gitignore b/.gitignore
index 2a63085b..ff7680f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,14 @@
-build
-drop
-www/webstart/*.jar
-.gradle
-.idea
-*.iml
-*.iws
-*.ipr
-.classpath
-.project
-.settings
+build
+drop
+www/webstart/*.jar
+.gradle
+.idea
+*.iml
+*.iws
+*.ipr
+.classpath
+.project
+.settings
+# NetBeans files: .nb-gradle/ (directory) and .nb-gradle-properties
+**/.nb-gradle/
+**/.nb-gradle-properties
\ No newline at end of file
diff --git a/substance-flamingo/src/tools/java/tools/docrobot/skins/Cerulean.java b/substance-flamingo/src/tools/java/tools/docrobot/skins/Cerulean.java
index 299d3345..49dfdd41 100755
--- a/substance-flamingo/src/tools/java/tools/docrobot/skins/Cerulean.java
+++ b/substance-flamingo/src/tools/java/tools/docrobot/skins/Cerulean.java
@@ -35,7 +35,7 @@
/**
* Screenshot robot for {@link org.pushingpixels.substance.api.skin.CeruleanSkin}.
- *
+ *
* @author Kirill Grouchnikov
*/
public class Cerulean extends SkinRobot {
@@ -44,7 +44,7 @@ public class Cerulean extends SkinRobot {
*/
public Cerulean() {
super(
- new Cerulean(),
+ new CeruleanSkin(),
"/Users/kirillg/JProjects/substance-flamingo/www/images/screenshots/skins/cerulean");
}
}
diff --git a/substance/src/main/java/org/pushingpixels/substance/internal/animation/RootPaneDefaultButtonTracker.java b/substance/src/main/java/org/pushingpixels/substance/internal/animation/RootPaneDefaultButtonTracker.java
index 71052142..1ee9174b 100755
--- a/substance/src/main/java/org/pushingpixels/substance/internal/animation/RootPaneDefaultButtonTracker.java
+++ b/substance/src/main/java/org/pushingpixels/substance/internal/animation/RootPaneDefaultButtonTracker.java
@@ -1,31 +1,31 @@
/*
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * o Neither the name of Substance Kirill Grouchnikov nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * o Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * o Neither the name of Substance Kirill Grouchnikov nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.pushingpixels.substance.internal.animation;
@@ -45,7 +45,7 @@
/**
* Tracker for pulsating (default and focused) JButtons. This class
* is for internal use only.
- *
+ *
* @author Kirill Grouchnikov
*/
public class RootPaneDefaultButtonTracker extends
@@ -69,7 +69,7 @@ public class RootPaneDefaultButtonTracker extends
/**
* Simple constructor.
- *
+ *
* @param jbutton
*/
private RootPaneDefaultButtonTracker(JButton jbutton) {
@@ -85,7 +85,7 @@ private RootPaneDefaultButtonTracker(JButton jbutton) {
/**
* Recursively checks whether the specified component or one of its inner
* components has focus.
- *
+ *
* @param component
* Component to check.
* @return true if the specified component or one of its inner
@@ -115,7 +115,7 @@ private static boolean isInFocusedWindow(Component component) {
/**
* Recursively checks whether the specified component has visible glass
* pane.
- *
+ *
* @param component
* Component to check.
* @return true if the specified component has visible glass
@@ -170,9 +170,13 @@ void onTimelineEvent() {
if (!isPulsating(jButton)) {
// has since lost its default status
RootPaneDefaultButtonTracker tracker = trackers.get(jButton);
- tracker.stopTimer();
- tracker.buttonRef.clear();
- trackers.remove(jButton);
+ if (tracker != null) {
+ // value has been observed to be null in rare cases, so check for it;
+ // https://github.com/Insubstantial/insubstantial/issues/137
+ tracker.stopTimer();
+ tracker.buttonRef.clear();
+ trackers.remove(jButton);
+ }
} else {
if (!RootPaneDefaultButtonTracker.isInFocusedWindow(jButton
.getTopLevelAncestor())) {
@@ -228,7 +232,7 @@ private void stopTimer() {
/**
* Returns the status of the associated timer.
- *
+ *
* @return true is the associated timer is running,
* false otherwise.
*/
@@ -240,7 +244,7 @@ private boolean isRunning() {
/**
* Updates the state of the specified button which must be a default button
* in some window. The button state is determined based on focus ownership.
- *
+ *
* @param jButton
* Button.
*/
@@ -268,8 +272,8 @@ public static void update(JButton jButton) {
return;
}
tracker = new RootPaneDefaultButtonTracker(jButton);
- tracker.startTimer();
trackers.put(jButton, tracker);
+ tracker.startTimer();
// long initialCycle = isAttentionDrawingCloseButton(jButton) ? -80
// : 0;
// cycles.put(jButton, initialCycle);
@@ -279,7 +283,7 @@ public static void update(JButton jButton) {
/**
* Retrieves the current cycle count for the specified button.
- *
+ *
* @param jButton
* Button.
* @return Current cycle count for the specified button.
@@ -301,7 +305,7 @@ public static float getTimelinePosition(JButton jButton) {
/**
* Retrieves the animation state for the specified button.
- *
+ *
* @param jButton
* Button.
* @return true if the specified button is being animated,
@@ -317,7 +321,7 @@ public static boolean isAnimating(JButton jButton) {
/**
* Returns memory usage.
- *
+ *
* @return Memory usage string.
*/
static String getMemoryUsage() {
@@ -379,7 +383,7 @@ static String getMemoryUsage() {
/**
* Checks whether the specified button is pulsating.
- *
+ *
* @param jButton
* Button.
* @return true if the specified button is pulsating,
diff --git a/substance/src/main/java/org/pushingpixels/substance/internal/utils/SubstanceImageCreator.java b/substance/src/main/java/org/pushingpixels/substance/internal/utils/SubstanceImageCreator.java
index 2867ca48..d1f33364 100644
--- a/substance/src/main/java/org/pushingpixels/substance/internal/utils/SubstanceImageCreator.java
+++ b/substance/src/main/java/org/pushingpixels/substance/internal/utils/SubstanceImageCreator.java
@@ -51,14 +51,14 @@
/**
* Provides utility functions for creating various images for Substance
* look and feel. This class is for internal use only.
- *
+ *
* @author Kirill Grouchnikov
*/
public final class SubstanceImageCreator {
/**
* Custom fill painter for filling the checkmarks of checkboxes and radio
* buttons.
- *
+ *
* @author Kirill Grouchnikov
*/
public static class SimplisticSoftBorderReverseFillPainter extends
@@ -92,7 +92,7 @@ public Color getBottomFillColor(SubstanceColorScheme fillScheme) {
/**
* Paints border instance of specified dimensions and status.
- *
+ *
* @param c
* Component.
* @param graphics
@@ -139,7 +139,7 @@ public static void paintBorder(Component c, Graphics2D graphics, int x,
/**
* Paints border instance of specified dimensions and status.
- *
+ *
* @param c
* Component.
* @param graphics
@@ -243,7 +243,7 @@ public static void paintTextComponentBorder(JComponent c,
/**
* Retrieves check mark image.
- *
+ *
* @param dimension
* Check mark dimension.
* @param isEnabled
@@ -293,7 +293,7 @@ private static BufferedImage getCheckMark(int dimension, boolean isEnabled,
/**
* Returns arrow icon for the specified parameters.
- *
+ *
* @param fontSize
* Font size.
* @param direction
@@ -315,7 +315,7 @@ public static Icon getArrowIcon(int fontSize, int direction,
/**
* Retrieves arrow icon.
- *
+ *
* @param width
* Arrow width.
* @param height
@@ -340,7 +340,7 @@ public static Icon getArrowIcon(float width, float height,
/**
* Retrieves arrow image.
- *
+ *
* @param width
* Arrow width.
* @param height
@@ -433,7 +433,7 @@ public static BufferedImage getArrow(float width, float height,
/**
* Returns double arrow icon for the specified parameters.
- *
+ *
* @param fontSize
* Font size.
* @param deltaWidth
@@ -463,7 +463,7 @@ public static Icon getDoubleArrowIconDelta(int fontSize, float deltaWidth,
/**
* Retrieves arrow icon.
- *
+ *
* @param width
* Arrow width.
* @param height
@@ -533,7 +533,7 @@ public static Icon getDoubleArrowIcon(int fontSize, float width,
/**
* Returns rotated image.
- *
+ *
* @param bi
* Image to rotate.
* @param quadrantClockwise
@@ -576,7 +576,7 @@ public static BufferedImage getRotated(BufferedImage bi,
/**
* Returns rotated image.
- *
+ *
* @param bi
* Image to rotate.
* @param quadrantClockwise
@@ -619,7 +619,7 @@ public static VolatileImage getRotated(final VolatileImage bi,
/**
* Translated the specified icon to grey scale.
- *
+ *
* @param icon
* Icon.
* @return Greyscale version of the specified icon.
@@ -641,7 +641,7 @@ public static Icon toGreyscale(Icon icon) {
/**
* Makes the specified icon transparent.
- *
+ *
* @param c
* Component.
* @param icon
@@ -799,7 +799,7 @@ public static Icon makeTransparent(Component c, Icon icon, double alpha) {
/**
* Retrieves radio button of the specified size that matches the specified
* parameters.
- *
+ *
* @param component
* Component.
* @param dimension
@@ -877,8 +877,12 @@ public static BufferedImage getRadioButton(JComponent component,
Shape markOval = new Ellipse2D.Double(rc - radius, rc - radius,
2 * radius, 2 * radius);
+ // Avoid exception by making sure the alpha value is in the correct range.
+ // https://github.com/Insubstantial/insubstantial/issues/138
+ float alphaTimesVisibility = Math.max(0.0f, Math.min(1.0f, alpha * checkMarkVisibility));
+
graphics.setComposite(AlphaComposite.getInstance(
- AlphaComposite.SRC_OVER, alpha * checkMarkVisibility));
+ AlphaComposite.SRC_OVER, alphaTimesVisibility));
drawRadioMark(graphics, SubstanceColorUtilities.getMarkColor(
markColorScheme, !componentState.isDisabled()), markOval);
} else {
@@ -899,7 +903,7 @@ public static BufferedImage getRadioButton(JComponent component,
/**
* Draws radio mark.
- *
+ *
* @param graphics
* Graphics context.
* @param color
@@ -916,7 +920,7 @@ private static void drawRadioMark(Graphics2D graphics, Color color,
/**
* Retrieves check box of the specified size that matches the specified
* component state.
- *
+ *
* @param button
* Button for the check mark.
* @param dimension
@@ -1028,7 +1032,7 @@ public static BufferedImage getCheckBox(AbstractButton button,
*
* Combined together, the layers create the image for scrollbar track with
* continuation of the arrow increase and decrease buttons.
- *
+ *
* @param component
* Component.
* @param width
@@ -1083,7 +1087,7 @@ public static void paintCompositeRoundedBackground(JComponent component,
/**
* Overlays light-colored echo below the specified image.
- *
+ *
* @param image
* The input image.
* @param echoAlpha
@@ -1133,7 +1137,7 @@ private static BufferedImage overlayEcho(BufferedImage image,
/**
* Returns minimize icon.
- *
+ *
* @param scheme
* Color scheme for the icon.
* @return Minimize icon.
@@ -1146,7 +1150,7 @@ public static Icon getMinimizeIcon(SubstanceColorScheme scheme,
/**
* Returns minimize icon.
- *
+ *
* @param iSize
* Icon dimension.
* @param scheme
@@ -1182,7 +1186,7 @@ public static Icon getMinimizeIcon(int iSize, SubstanceColorScheme scheme,
/**
* Returns restore icon.
- *
+ *
* @param scheme
* Color scheme for the icon.
* @return Restore icon.
@@ -1222,7 +1226,7 @@ public static Icon getRestoreIcon(SubstanceColorScheme scheme,
/**
* Returns maximize icon.
- *
+ *
* @param scheme
* Color scheme for the icon.
* @return Maximize icon.
@@ -1235,7 +1239,7 @@ public static Icon getMaximizeIcon(SubstanceColorScheme scheme,
/**
* Returns maximize icon.
- *
+ *
* @param iSize
* Icon dimension.
* @param scheme
@@ -1271,7 +1275,7 @@ public static Icon getMaximizeIcon(int iSize, SubstanceColorScheme scheme,
/**
* Returns close icon.
- *
+ *
* @param scheme
* Color scheme for the icon.
* @return Close icon.
@@ -1285,7 +1289,7 @@ public static Icon getCloseIcon(SubstanceColorScheme scheme,
/**
* Returns close icon.
- *
+ *
* @param iSize
* Icon dimension.
* @param colorScheme
@@ -1346,7 +1350,7 @@ public static Icon getCloseIcon(int iSize,
/**
* Paints rectangular gradient background.
- *
+ *
* @param g
* Graphic context.
* @param startX
@@ -1408,7 +1412,7 @@ public static void paintRectangularBackground(Component c, Graphics g,
/**
* Paints simple border.
- *
+ *
* @param g2d
* Graphics context.
* @param width
@@ -1472,7 +1476,7 @@ public static void paintSimpleBorderAliased(Component c, Graphics2D g2d,
/**
* Paints rectangular gradient background with spots and optional replicated
* stripe image.
- *
+ *
* @param g
* Graphics context.
* @param startX
@@ -1557,7 +1561,7 @@ public static void paintRectangularStripedBackground(Component c,
/**
* Returns diagonal stripe image.
- *
+ *
* @param baseSize
* Stripe base in pixels.
* @param color
@@ -1594,7 +1598,7 @@ public static BufferedImage getStripe(int baseSize, Color color) {
/**
* Returns drag bumps image.
- *
+ *
* @param c
* Component.
* @param colorScheme
@@ -1665,7 +1669,7 @@ public static BufferedImage getDragImage(Component c,
/**
* Paints the bump dots on the split pane dividers.
- *
+ *
* @param g
* Graphics context.
* @param divider
@@ -1739,7 +1743,7 @@ public static void paintSplitDividerBumpImage(Graphics g,
/**
* Returns resize grip image.
- *
+ *
* @param c
* Component.
* @param colorScheme
@@ -1801,7 +1805,7 @@ public static BufferedImage getResizeGripImage(Component c,
/**
* Retrieves tree icon.
- *
+ *
* @param tree
* Tree.
* @param fillScheme
@@ -1871,7 +1875,7 @@ public static BufferedImage getTreeIcon(JTree tree,
/**
* Retrieves a single crayon of the specified color and dimensions for the
* crayon panel in color chooser.
- *
+ *
* @param mainColor
* Crayon main color.
* @param width
@@ -2028,7 +2032,7 @@ public static BufferedImage getSingleCrayon(Color mainColor, int width,
/**
* Retrieves crayon X offset.
- *
+ *
* @param i
* Crayon index.
* @return Crayon X offset.
@@ -2039,7 +2043,7 @@ private static int crayonX(int i) {
/**
* Retrieves crayon Y offset.
- *
+ *
* @param i
* Crayon index.
* @return Crayon Y offset.
@@ -2050,7 +2054,7 @@ private static int crayonY(int i) {
/**
* Retrieves crayons image for the crayon panel of color chooser.
- *
+ *
* @return Crayons image.
*/
public static Image getCrayonsImage() {
@@ -2084,7 +2088,7 @@ public static Image getCrayonsImage() {
* Returns small icon representation of the specified integer value. The
* remainder of dividing the integer by 16 is translated to four circles
* arranged in 2*2 grid.
- *
+ *
* @param value
* Integer value to represent.
* @param colorScheme
@@ -2131,7 +2135,7 @@ public static Icon getHexaMarker(int value, SubstanceColorScheme colorScheme) {
/**
* Returns search icon.
- *
+ *
* @param dimension
* Icon dimension.
* @param colorScheme
@@ -2187,7 +2191,7 @@ public static Icon getSearchIcon(int dimension,
/**
* Returns an icon that matches the specified watermark.
- *
+ *
* @param watermark
* Watermark instance.
* @return Icon that matches the specified watermark.
@@ -2210,7 +2214,7 @@ public static Icon getWatermarkIcon(SubstanceWatermark watermark) {
/**
* Returns a lock icon that matches the specified scheme.
- *
+ *
* @param scheme
* Scheme instance.
* @return Lock icon that matches the specified scheme.
@@ -2286,7 +2290,7 @@ public static Icon getSmallLockIcon(SubstanceColorScheme scheme, Component c) {
/**
* Returns the negative of the specified image.
- *
+ *
* @param bi
* Image.
* @return The negative of the specified image.
@@ -2298,7 +2302,7 @@ public static BufferedImage getNegated(BufferedImage bi) {
/**
* Creates a new version of the specified icon that is rendered in the
* colors of the specified color scheme.
- *
+ *
* @param comp
* Component.
* @param original
@@ -2322,7 +2326,7 @@ public static BufferedImage getColorSchemeImage(Component comp,
/**
* Creates a new version of the specified image that is rendered in the
* colors of the specified color scheme.
- *
+ *
* @param original
* The original image.
* @param colorScheme