< prev index next >

modules/controls/src/main/java/javafx/scene/control/PopupControl.java

Print this page




  32 import javafx.application.Application;
  33 import javafx.beans.property.DoubleProperty;
  34 import javafx.beans.property.DoublePropertyBase;
  35 import javafx.beans.property.ObjectProperty;
  36 import javafx.beans.property.ObjectPropertyBase;
  37 import javafx.beans.property.StringProperty;
  38 import javafx.beans.value.WritableValue;
  39 import javafx.collections.FXCollections;
  40 import javafx.collections.ObservableList;
  41 import javafx.collections.ObservableSet;
  42 import javafx.css.CssParser;
  43 import javafx.scene.Node;
  44 import javafx.scene.Parent;
  45 import javafx.scene.Scene;
  46 import javafx.scene.layout.Pane;
  47 import javafx.stage.PopupWindow;
  48 import com.sun.javafx.application.PlatformImpl;
  49 import javafx.css.CssMetaData;
  50 import javafx.css.PseudoClass;
  51 import com.sun.javafx.css.StyleManager;


  52 import javafx.css.Styleable;
  53 import javafx.css.StyleableStringProperty;
  54 import javafx.css.converter.StringConverter;
  55 import com.sun.javafx.scene.control.Logging;

  56 import com.sun.javafx.stage.PopupWindowHelper;

  57 import javafx.css.StyleableProperty;
  58 import javafx.stage.Window;
  59 import sun.util.logging.PlatformLogger;
  60 import sun.util.logging.PlatformLogger.Level;
  61 
  62 /**
  63  * An extension of PopupWindow that allows for CSS styling.
  64  * @since JavaFX 2.0
  65  */
  66 public class PopupControl extends PopupWindow implements Skinnable, Styleable {
  67 
  68     /**
  69      * Sentinel value which can be passed to a control's setMinWidth(), setMinHeight(),
  70      * setMaxWidth() or setMaxHeight() methods to indicate that the preferred dimension
  71      * should be used for that max and/or min constraint.
  72      */
  73     public static final double USE_PREF_SIZE = Double.NEGATIVE_INFINITY;
  74 
  75      /**
  76       * Sentinel value which can be passed to a control's setMinWidth(), setMinHeight(),


 253             }
 254 
 255             // Get the new value, and save it off as the new oldValue
 256             oldValue = getValue();
 257 
 258             prefWidthCache = -1;
 259             prefHeightCache = -1;
 260             minWidthCache = -1;
 261             minHeightCache = -1;
 262             maxWidthCache = -1;
 263             maxHeightCache = -1;
 264             skinSizeComputed = false;
 265 
 266             final Node n = getSkinNode();
 267             if (n != null) {
 268                 bridge.getChildren().setAll(n);
 269             } else {
 270                 bridge.getChildren().clear();
 271             }
 272 
 273             // calling impl_reapplyCSS() as the styleable properties may now
 274             // be different, as we will now be able to return styleable properties
 275             // belonging to the skin. If impl_reapplyCSS() is not called, the
 276             // getCssMetaData() method is never called, so the
 277             // skin properties are never exposed.
 278             bridge.impl_reapplyCSS();
 279 
 280             // DEBUG: Log that we've changed the skin
 281             final PlatformLogger logger = Logging.getControlsLogger();
 282             if (logger.isLoggable(Level.FINEST)) {
 283                 logger.finest("Stored skin[" + getValue() + "] on " + this);
 284             }
 285         }
 286 
 287         @Override
 288         public Object getBean() {
 289             return PopupControl.this;
 290         }
 291 
 292         @Override
 293         public String getName() {
 294             return "skin";
 295         }
 296     };
 297     /**
 298      * Keeps a reference to the name of the class currently acting as the skin.


1091      * @since JavaFX 8.0
1092      */
1093     public final ObservableSet<PseudoClass> getPseudoClassStates() {
1094         return FXCollections.emptyObservableSet();
1095     }
1096 
1097     /** {@inheritDoc} */
1098     @Override public Node getStyleableNode() {
1099         return bridge;
1100     }
1101 
1102     /**
1103      * The link between the popup window and the scenegraph.
1104      *
1105      * @since JavaFX 2.1
1106      */
1107     protected class CSSBridge extends Pane {
1108 
1109         private final PopupControl popupControl = PopupControl.this;
1110 





1111         /**
1112          * Requests a layout pass to be performed before the next scene is
1113          * rendered. This is batched up asynchronously to happen once per
1114          * "pulse", or frame of animation.
1115          * <p/>
1116          * If this parent is either a layout root or unmanaged, then it will be
1117          * added directly to the scene's dirty layout list, otherwise requestLayout
1118          * will be invoked on its parent.
1119          */
1120         @Override public void requestLayout() {
1121             prefWidthCache = -1;
1122             prefHeightCache = -1;
1123             minWidthCache = -1;
1124             minHeightCache = -1;
1125             maxWidthCache = -1;
1126             maxHeightCache = -1;
1127             //skinSizeComputed = false; -- RT-33073 disabled this
1128             super.requestLayout();
1129         }
1130 
1131         /**
1132          * This method should be treated as final and should not be overridden by any subclasses of CSSBridge.
1133          */
1134         @Override
1135         public Styleable getStyleableParent() {
1136             return PopupControl.this.getStyleableParent();
1137         }
1138 
1139         /**
1140          * @treatAsPrivate implementation detail
1141          * @deprecated This is an internal API that is not intended for use and will be removed in the next version
1142          */
1143         @Deprecated
1144         protected void setSkinClassName(String skinClassName) { /* no-op - retain for binary compatibility */ }
1145 
1146         @Override
1147         public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
1148             return PopupControl.this.getCssMetaData();
1149         }
1150 
1151         /**
1152          * @treatAsPrivate implementation detail
1153          * @deprecated This is an internal API that is not intended for use and will be removed in the next version
1154          */
1155         @Deprecated
1156         @Override public List<String> impl_getAllParentStylesheets() {
1157             Styleable styleable = getStyleableParent();
1158             if (styleable instanceof Parent) {
1159                 return ((Parent)styleable).impl_getAllParentStylesheets();
1160             }
1161             return null;
1162         }
1163 
1164         /**
1165          * @treatAsPrivate implementation detail
1166          * @deprecated This is an internal API that is not intended for use and will be removed in the next version
1167          */
1168         @Deprecated
1169         @Override protected void impl_processCSS() {
1170             super.impl_processCSS();
1171 
1172             if (getSkin() == null) {
1173                 // try to create default skin
1174                 final Skin<?> defaultSkin = createDefaultSkin();
1175                 if (defaultSkin != null) {
1176                     skinProperty().set(defaultSkin);
1177                     super.impl_processCSS();
1178                 } else {
1179                     final String msg = "The -fx-skin property has not been defined in CSS for " + this +
1180                             " and createDefaultSkin() returned null.";
1181                     final List<CssParser.ParseError> errors = StyleManager.getErrors();
1182                     if (errors != null) {
1183                         CssParser.ParseError error = new CssParser.ParseError(msg);
1184                         errors.add(error); // RT-19884
1185                     }
1186                     Logging.getControlsLogger().severe(msg);
1187                 }
1188             }
































1189         }
1190 
1191     }
1192 
1193 }


  32 import javafx.application.Application;
  33 import javafx.beans.property.DoubleProperty;
  34 import javafx.beans.property.DoublePropertyBase;
  35 import javafx.beans.property.ObjectProperty;
  36 import javafx.beans.property.ObjectPropertyBase;
  37 import javafx.beans.property.StringProperty;
  38 import javafx.beans.value.WritableValue;
  39 import javafx.collections.FXCollections;
  40 import javafx.collections.ObservableList;
  41 import javafx.collections.ObservableSet;
  42 import javafx.css.CssParser;
  43 import javafx.scene.Node;
  44 import javafx.scene.Parent;
  45 import javafx.scene.Scene;
  46 import javafx.scene.layout.Pane;
  47 import javafx.stage.PopupWindow;
  48 import com.sun.javafx.application.PlatformImpl;
  49 import javafx.css.CssMetaData;
  50 import javafx.css.PseudoClass;
  51 import com.sun.javafx.css.StyleManager;
  52 import com.sun.javafx.scene.NodeHelper;
  53 import com.sun.javafx.scene.ParentHelper;
  54 import javafx.css.Styleable;
  55 import javafx.css.StyleableStringProperty;
  56 import javafx.css.converter.StringConverter;
  57 import com.sun.javafx.scene.control.Logging;
  58 import com.sun.javafx.scene.layout.PaneHelper;
  59 import com.sun.javafx.stage.PopupWindowHelper;
  60 import com.sun.javafx.util.Utils;
  61 import javafx.css.StyleableProperty;
  62 import javafx.stage.Window;
  63 import sun.util.logging.PlatformLogger;
  64 import sun.util.logging.PlatformLogger.Level;
  65 
  66 /**
  67  * An extension of PopupWindow that allows for CSS styling.
  68  * @since JavaFX 2.0
  69  */
  70 public class PopupControl extends PopupWindow implements Skinnable, Styleable {
  71 
  72     /**
  73      * Sentinel value which can be passed to a control's setMinWidth(), setMinHeight(),
  74      * setMaxWidth() or setMaxHeight() methods to indicate that the preferred dimension
  75      * should be used for that max and/or min constraint.
  76      */
  77     public static final double USE_PREF_SIZE = Double.NEGATIVE_INFINITY;
  78 
  79      /**
  80       * Sentinel value which can be passed to a control's setMinWidth(), setMinHeight(),


 257             }
 258 
 259             // Get the new value, and save it off as the new oldValue
 260             oldValue = getValue();
 261 
 262             prefWidthCache = -1;
 263             prefHeightCache = -1;
 264             minWidthCache = -1;
 265             minHeightCache = -1;
 266             maxWidthCache = -1;
 267             maxHeightCache = -1;
 268             skinSizeComputed = false;
 269 
 270             final Node n = getSkinNode();
 271             if (n != null) {
 272                 bridge.getChildren().setAll(n);
 273             } else {
 274                 bridge.getChildren().clear();
 275             }
 276 
 277             // calling NodeHelper.reapplyCSS() as the styleable properties may now
 278             // be different, as we will now be able to return styleable properties
 279             // belonging to the skin. If NodeHelper.reapplyCSS() is not called, the
 280             // getCssMetaData() method is never called, so the
 281             // skin properties are never exposed.
 282             NodeHelper.reapplyCSS(bridge);
 283 
 284             // DEBUG: Log that we've changed the skin
 285             final PlatformLogger logger = Logging.getControlsLogger();
 286             if (logger.isLoggable(Level.FINEST)) {
 287                 logger.finest("Stored skin[" + getValue() + "] on " + this);
 288             }
 289         }
 290 
 291         @Override
 292         public Object getBean() {
 293             return PopupControl.this;
 294         }
 295 
 296         @Override
 297         public String getName() {
 298             return "skin";
 299         }
 300     };
 301     /**
 302      * Keeps a reference to the name of the class currently acting as the skin.


1095      * @since JavaFX 8.0
1096      */
1097     public final ObservableSet<PseudoClass> getPseudoClassStates() {
1098         return FXCollections.emptyObservableSet();
1099     }
1100 
1101     /** {@inheritDoc} */
1102     @Override public Node getStyleableNode() {
1103         return bridge;
1104     }
1105 
1106     /**
1107      * The link between the popup window and the scenegraph.
1108      *
1109      * @since JavaFX 2.1
1110      */
1111     protected class CSSBridge extends Pane {
1112 
1113         private final PopupControl popupControl = PopupControl.this;
1114 
1115         {
1116             // To initialize the class helper at the begining each constructor of this class
1117             CSSBridgeHelper.initHelper(this);
1118         }
1119 
1120         /**
1121          * Requests a layout pass to be performed before the next scene is
1122          * rendered. This is batched up asynchronously to happen once per
1123          * "pulse", or frame of animation.
1124          * <p/>
1125          * If this parent is either a layout root or unmanaged, then it will be
1126          * added directly to the scene's dirty layout list, otherwise requestLayout
1127          * will be invoked on its parent.
1128          */
1129         @Override public void requestLayout() {
1130             prefWidthCache = -1;
1131             prefHeightCache = -1;
1132             minWidthCache = -1;
1133             minHeightCache = -1;
1134             maxWidthCache = -1;
1135             maxHeightCache = -1;
1136             //skinSizeComputed = false; -- RT-33073 disabled this
1137             super.requestLayout();
1138         }
1139 
1140         /**
1141          * This method should be treated as final and should not be overridden by any subclasses of CSSBridge.
1142          */
1143         @Override
1144         public Styleable getStyleableParent() {
1145             return PopupControl.this.getStyleableParent();
1146         }
1147 







1148         @Override
1149         public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
1150             return PopupControl.this.getCssMetaData();
1151         }
1152 
1153         List<String> getAllParentStylesheets() {





1154             Styleable styleable = getStyleableParent();
1155             if (styleable instanceof Parent) {
1156                 return ParentHelper.getAllParentStylesheets((Parent)styleable);
1157             }
1158             return null;
1159         }
1160 
1161         /*
1162          * Note: This method MUST only be called via its accessor method.

1163          */
1164         private void doProcessCSS() {
1165             CSSBridgeHelper.superProcessCSS(this);

1166 
1167             if (getSkin() == null) {
1168                 // try to create default skin
1169                 final Skin<?> defaultSkin = createDefaultSkin();
1170                 if (defaultSkin != null) {
1171                     skinProperty().set(defaultSkin);
1172                     CSSBridgeHelper.superProcessCSS(this);
1173                 } else {
1174                     final String msg = "The -fx-skin property has not been defined in CSS for " + this +
1175                             " and createDefaultSkin() returned null.";
1176                     final List<CssParser.ParseError> errors = StyleManager.getErrors();
1177                     if (errors != null) {
1178                         CssParser.ParseError error = new CssParser.ParseError(msg);
1179                         errors.add(error); // RT-19884
1180                     }
1181                     Logging.getControlsLogger().severe(msg);
1182                 }
1183             }
1184         }
1185 
1186     }
1187 
1188     /*
1189      * Used to access internal methods of CSSBridge.
1190      */
1191     static final class CSSBridgeHelper extends PaneHelper {
1192         private static final CSSBridgeHelper theInstance;
1193 
1194         static {
1195             theInstance = new CSSBridgeHelper();
1196         }
1197 
1198         private static CSSBridgeHelper getInstance() {
1199             return theInstance;
1200         }
1201 
1202         public static void initHelper(CSSBridge cssBridge) {
1203             setHelper(cssBridge, getInstance());
1204         }
1205 
1206         public static void superProcessCSS(Node node) {
1207             ((CSSBridgeHelper) getHelper(node)).superProcessCSSImpl(node);
1208         }
1209 
1210         void superProcessCSSImpl(Node node) {
1211             super.processCSSImpl(node);
1212         }
1213 
1214         protected void processCSSImpl(Node node) {
1215             ((CSSBridge) node).doProcessCSS();
1216         }
1217 
1218     }
1219 
1220 }
< prev index next >