< prev index next >

src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java

Print this page




  84  * <p>The values are only read out of UIManager once, and then cached. If
  85  * you need to read the values again (for example, if the UI is being reloaded),
  86  * then discard this NimbusStyle and read a new one from NimbusLookAndFeel
  87  * using NimbusLookAndFeel.getStyle.</p>
  88  *
  89  * <p>The primary API of interest in this class for 3rd party component authors
  90  * are the three methods which retrieve painters: #getBackgroundPainter,
  91  * #getForegroundPainter, and #getBorderPainter.</p>
  92  *
  93  * <p>NimbusStyle allows you to specify custom states, or modify the order of
  94  * states. Synth (and thus Nimbus) has the concept of a "state". For example,
  95  * a JButton might be in the "MOUSE_OVER" state, or the "ENABLED" state, or the
  96  * "DISABLED" state. These are all "standard" states which are defined in synth,
  97  * and which apply to all synth Regions.</p>
  98  *
  99  * <p>Sometimes, however, you need to have a custom state. For example, you
 100  * want JButton to render differently if it's parent is a JToolbar. In Nimbus,
 101  * you specify these custom states by including a special key in UIDefaults.
 102  * The following UIDefaults entries define three states for this button:</p>
 103  *
 104  * <pre><code>
 105  *     JButton.States = Enabled, Disabled, Toolbar
 106  *     JButton[Enabled].backgroundPainter = somePainter
 107  *     JButton[Disabled].background = BLUE
 108  *     JButton[Toolbar].backgroundPainter = someOtherPaint
 109  * </code></pre>
 110  *
 111  * <p>As you can see, the <code>JButton.States</code> entry lists the states
 112  * that the JButton style will support. You then specify the settings for
 113  * each state. If you do not specify the <code>JButton.States</code> entry,
 114  * then the standard Synth states will be assumed. If you specify the entry
 115  * but the list of states is empty or null, then the standard synth states
 116  * will be assumed.</p>
 117  *
 118  * @author Richard Bair
 119  * @author Jasper Potts
 120  */
 121 public final class NimbusStyle extends SynthStyle {
 122     /* Keys and scales for large/small/mini components, based on Apples sizes */
 123     /** Large key */
 124     public static final String LARGE_KEY = "large";
 125     /** Small key */
 126     public static final String SMALL_KEY = "small";
 127     /** Mini key */
 128     public static final String MINI_KEY = "mini";
 129     /** Large scale */
 130     public static final double LARGE_SCALE = 1.15;
 131     /** Small scale */
 132     public static final double SMALL_SCALE = 0.857;
 133     /** Mini scale */
 134     public static final double MINI_SCALE = 0.714;
 135 
 136     /**
 137      * Special constant used for performance reasons during the get() method.
 138      * If get() runs through all of the search locations and determines that
 139      * there is no value, then NULL will be placed into the values map. This way
 140      * on subsequent lookups it will simply extract NULL, see it, and return
 141      * null rather than continuing the lookup procedure.
 142      */
 143     private static final Object NULL = '\0';
 144     /**
 145      * <p>The Color to return from getColorForState if it would otherwise have
 146      * returned null.</p>
 147      *
 148      * <p>Returning null from getColorForState is a very bad thing, as it causes
 149      * the AWT peer for the component to install a SystemColor, which is not a
 150      * UIResource. As a result, if <code>null</code> is returned from
 151      * getColorForState, then thereafter the color is not updated for other
 152      * states or on LAF changes or updates. This DEFAULT_COLOR is used to
 153      * ensure that a ColorUIResource is always returned from
 154      * getColorForState.</p>
 155      */
 156     private static final Color DEFAULT_COLOR = new ColorUIResource(Color.BLACK);
 157     /**
 158      * Simple Comparator for ordering the RuntimeStates according to their
 159      * rank.
 160      */
 161     private static final Comparator<RuntimeState> STATE_COMPARATOR =
 162         new Comparator<RuntimeState>() {
 163             @Override
 164             public int compare(RuntimeState a, RuntimeState b) {
 165                 return a.state - b.state;
 166             }
 167         };
 168     /**
 169      * The prefix for the component or region that this NimbusStyle
 170      * represents. This prefix is used to lookup state in the UIManager.


 906                     xstate |= mask;
 907                 }
 908                 mask <<= 1;
 909             }
 910         }
 911         return xstate;
 912     }
 913 
 914     /**
 915      * <p>Gets the RuntimeState that most closely matches the state in the given
 916      * context, but is less specific than the given "lastState". Essentially,
 917      * this allows you to search for the next best state.</p>
 918      *
 919      * <p>For example, if you had the following three states:
 920      * <pre>
 921      * Enabled
 922      * Enabled+Pressed
 923      * Disabled
 924      * </pre>
 925      * And you wanted to find the state that best represented
 926      * ENABLED+PRESSED+FOCUSED and <code>lastState</code> was null (or an
 927      * empty array, or an array with a single int with index == -1), then
 928      * Enabled+Pressed would be returned. If you then call this method again but
 929      * pass the index of Enabled+Pressed as the "lastState", then
 930      * Enabled would be returned. If you call this method a third time and pass
 931      * the index of Enabled in as the <code>lastState</code>, then null would be
 932      * returned.</p>
 933      *
 934      * <p>The actual code path for determining the proper state is the same as
 935      * in Synth.</p>
 936      *
 937      * @param ctx
 938      * @param lastState a 1 element array, allowing me to do pass-by-reference.
 939      * @return
 940      */
 941     private RuntimeState getNextState(RuntimeState[] states,
 942                                       int[] lastState,
 943                                       int xstate) {
 944         // Use the StateInfo with the most bits that matches that of state.
 945         // If there are none, then fallback to
 946         // the StateInfo with a state of 0, indicating it'll match anything.
 947 
 948         // Consider if we have 3 StateInfos a, b and c with states:
 949         // SELECTED, SELECTED | ENABLED, 0
 950         //
 951         // Input                          Return Value


1009                         bestIndex = counter;
1010                         bestCount = bitCount;
1011                     }
1012                 }
1013             }
1014             if (bestIndex != -1) {
1015                 lastState[0] = bestIndex;
1016                 return states[bestIndex];
1017             }
1018             if (wildIndex != -1) {
1019                 lastState[0] = wildIndex;
1020                 return states[wildIndex];
1021             }
1022         }
1023         lastState[0] = -1;
1024         return null;
1025     }
1026 
1027     /**
1028      * Contains values such as the UIDefaults and painters associated with
1029      * a state. Whereas <code>State</code> represents a distinct state that a
1030      * component can be in (such as Enabled), this class represents the colors,
1031      * fonts, painters, etc associated with some state for this
1032      * style.
1033      */
1034     private final class RuntimeState implements Cloneable {
1035         int state;
1036         Painter<Object> backgroundPainter;
1037         Painter<Object> foregroundPainter;
1038         Painter<Object> borderPainter;
1039         String stateName;
1040         UIDefaults defaults = new UIDefaults(10, .7f);
1041 
1042         private RuntimeState(int state, String stateName) {
1043             this.state = state;
1044             this.stateName = stateName;
1045         }
1046 
1047         @Override
1048         public String toString() {
1049             return stateName;




  84  * <p>The values are only read out of UIManager once, and then cached. If
  85  * you need to read the values again (for example, if the UI is being reloaded),
  86  * then discard this NimbusStyle and read a new one from NimbusLookAndFeel
  87  * using NimbusLookAndFeel.getStyle.</p>
  88  *
  89  * <p>The primary API of interest in this class for 3rd party component authors
  90  * are the three methods which retrieve painters: #getBackgroundPainter,
  91  * #getForegroundPainter, and #getBorderPainter.</p>
  92  *
  93  * <p>NimbusStyle allows you to specify custom states, or modify the order of
  94  * states. Synth (and thus Nimbus) has the concept of a "state". For example,
  95  * a JButton might be in the "MOUSE_OVER" state, or the "ENABLED" state, or the
  96  * "DISABLED" state. These are all "standard" states which are defined in synth,
  97  * and which apply to all synth Regions.</p>
  98  *
  99  * <p>Sometimes, however, you need to have a custom state. For example, you
 100  * want JButton to render differently if it's parent is a JToolbar. In Nimbus,
 101  * you specify these custom states by including a special key in UIDefaults.
 102  * The following UIDefaults entries define three states for this button:</p>
 103  *
 104  * <pre>{@code
 105  *     JButton.States = Enabled, Disabled, Toolbar
 106  *     JButton[Enabled].backgroundPainter = somePainter
 107  *     JButton[Disabled].background = BLUE
 108  *     JButton[Toolbar].backgroundPainter = someOtherPaint
 109  * }</pre>
 110  *
 111  * <p>As you can see, the {@code JButton.States} entry lists the states
 112  * that the JButton style will support. You then specify the settings for
 113  * each state. If you do not specify the {@code JButton.States} entry,
 114  * then the standard Synth states will be assumed. If you specify the entry
 115  * but the list of states is empty or null, then the standard synth states
 116  * will be assumed.</p>
 117  *
 118  * @author Richard Bair
 119  * @author Jasper Potts
 120  */
 121 public final class NimbusStyle extends SynthStyle {
 122     /* Keys and scales for large/small/mini components, based on Apples sizes */
 123     /** Large key */
 124     public static final String LARGE_KEY = "large";
 125     /** Small key */
 126     public static final String SMALL_KEY = "small";
 127     /** Mini key */
 128     public static final String MINI_KEY = "mini";
 129     /** Large scale */
 130     public static final double LARGE_SCALE = 1.15;
 131     /** Small scale */
 132     public static final double SMALL_SCALE = 0.857;
 133     /** Mini scale */
 134     public static final double MINI_SCALE = 0.714;
 135 
 136     /**
 137      * Special constant used for performance reasons during the get() method.
 138      * If get() runs through all of the search locations and determines that
 139      * there is no value, then NULL will be placed into the values map. This way
 140      * on subsequent lookups it will simply extract NULL, see it, and return
 141      * null rather than continuing the lookup procedure.
 142      */
 143     private static final Object NULL = '\0';
 144     /**
 145      * <p>The Color to return from getColorForState if it would otherwise have
 146      * returned null.</p>
 147      *
 148      * <p>Returning null from getColorForState is a very bad thing, as it causes
 149      * the AWT peer for the component to install a SystemColor, which is not a
 150      * UIResource. As a result, if {@code null} is returned from
 151      * getColorForState, then thereafter the color is not updated for other
 152      * states or on LAF changes or updates. This DEFAULT_COLOR is used to
 153      * ensure that a ColorUIResource is always returned from
 154      * getColorForState.</p>
 155      */
 156     private static final Color DEFAULT_COLOR = new ColorUIResource(Color.BLACK);
 157     /**
 158      * Simple Comparator for ordering the RuntimeStates according to their
 159      * rank.
 160      */
 161     private static final Comparator<RuntimeState> STATE_COMPARATOR =
 162         new Comparator<RuntimeState>() {
 163             @Override
 164             public int compare(RuntimeState a, RuntimeState b) {
 165                 return a.state - b.state;
 166             }
 167         };
 168     /**
 169      * The prefix for the component or region that this NimbusStyle
 170      * represents. This prefix is used to lookup state in the UIManager.


 906                     xstate |= mask;
 907                 }
 908                 mask <<= 1;
 909             }
 910         }
 911         return xstate;
 912     }
 913 
 914     /**
 915      * <p>Gets the RuntimeState that most closely matches the state in the given
 916      * context, but is less specific than the given "lastState". Essentially,
 917      * this allows you to search for the next best state.</p>
 918      *
 919      * <p>For example, if you had the following three states:
 920      * <pre>
 921      * Enabled
 922      * Enabled+Pressed
 923      * Disabled
 924      * </pre>
 925      * And you wanted to find the state that best represented
 926      * ENABLED+PRESSED+FOCUSED and {@code lastState} was null (or an
 927      * empty array, or an array with a single int with index == -1), then
 928      * Enabled+Pressed would be returned. If you then call this method again but
 929      * pass the index of Enabled+Pressed as the "lastState", then
 930      * Enabled would be returned. If you call this method a third time and pass
 931      * the index of Enabled in as the {@code lastState}, then null would be
 932      * returned.</p>
 933      *
 934      * <p>The actual code path for determining the proper state is the same as
 935      * in Synth.</p>
 936      *
 937      * @param ctx
 938      * @param lastState a 1 element array, allowing me to do pass-by-reference.
 939      * @return
 940      */
 941     private RuntimeState getNextState(RuntimeState[] states,
 942                                       int[] lastState,
 943                                       int xstate) {
 944         // Use the StateInfo with the most bits that matches that of state.
 945         // If there are none, then fallback to
 946         // the StateInfo with a state of 0, indicating it'll match anything.
 947 
 948         // Consider if we have 3 StateInfos a, b and c with states:
 949         // SELECTED, SELECTED | ENABLED, 0
 950         //
 951         // Input                          Return Value


1009                         bestIndex = counter;
1010                         bestCount = bitCount;
1011                     }
1012                 }
1013             }
1014             if (bestIndex != -1) {
1015                 lastState[0] = bestIndex;
1016                 return states[bestIndex];
1017             }
1018             if (wildIndex != -1) {
1019                 lastState[0] = wildIndex;
1020                 return states[wildIndex];
1021             }
1022         }
1023         lastState[0] = -1;
1024         return null;
1025     }
1026 
1027     /**
1028      * Contains values such as the UIDefaults and painters associated with
1029      * a state. Whereas {@code State} represents a distinct state that a
1030      * component can be in (such as Enabled), this class represents the colors,
1031      * fonts, painters, etc associated with some state for this
1032      * style.
1033      */
1034     private final class RuntimeState implements Cloneable {
1035         int state;
1036         Painter<Object> backgroundPainter;
1037         Painter<Object> foregroundPainter;
1038         Painter<Object> borderPainter;
1039         String stateName;
1040         UIDefaults defaults = new UIDefaults(10, .7f);
1041 
1042         private RuntimeState(int state, String stateName) {
1043             this.state = state;
1044             this.stateName = stateName;
1045         }
1046 
1047         @Override
1048         public String toString() {
1049             return stateName;


< prev index next >