changeset 1401:bc2e7244d877 2.2-b16

Merge
author igor
date Tue, 03 Jul 2012 16:18:42 -0700
parents 7f0d5537b52a 6b0866a7c08c
children 554e78523bab
files
diffstat 25 files changed, 381 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jun 29 21:46:13 2012 -0700
+++ b/.hgtags	Tue Jul 03 16:18:42 2012 -0700
@@ -33,3 +33,4 @@
 348de34f8273c417ecd0131e958c8c4fea6af8a7 2.2-b12
 00a63ce77e97aa5c1e15a3c150a44dd5cce82bf5 2.2-b13
 f026710b45cb770ce8dcc9aa9455f5b1d489a0df 2.2-b14
+8dc3a4c1f7fb90b65434246147fedaddf50b6589 2.2-b15
--- a/javafx-ui-charts/src/javafx/scene/chart/PieChart.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-charts/src/javafx/scene/chart/PieChart.java	Tue Jul 03 16:18:42 2012 -0700
@@ -335,6 +335,7 @@
         // check if symbol has already been created
         if (arcRegion == null) {
             arcRegion = new Region();
+            arcRegion.setPickOnBounds(false); 
             item.setNode(arcRegion);
         }
         // Note: not sure if we want to add or check, ie be more careful and efficient here
--- a/javafx-ui-charts/test/javafx/scene/chart/StackedAreaChartTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-charts/test/javafx/scene/chart/StackedAreaChartTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -63,7 +63,7 @@
         return sb;
     }
     
-    @Ignore @Test
+    @Test
     public void testSeriesAdd() {
         startApp();
         ac.getData().addAll(series1);
--- a/javafx-ui-charts/test/javafx/scene/chart/StackedBarChartTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-charts/test/javafx/scene/chart/StackedBarChartTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -54,7 +54,7 @@
         return sbc;
     }
     
-    @Ignore @Test
+    @Test
     public void testSeriesAdd() {
         startApp();
         sbc.getData().addAll(series1, series2, series3);
--- a/javafx-ui-charts/test/javafx/scene/chart/XYChartTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-charts/test/javafx/scene/chart/XYChartTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -44,7 +44,7 @@
     }
     
     // RT-22166
-    @Ignore @Test public void testTickLabelFont() {
+    @Test public void testTickLabelFont() {
         startApp();
         Font f = yaxis.getTickLabelFont();
         // default caspian value for font size = 10
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue Jul 03 16:18:42 2012 -0700
@@ -136,44 +136,163 @@
     }
 
     /**
-     * called from Parent's stylesheets onChanged method
+     * A container for Parent stylesheets and the Parents that use them.
+     * If a Parent stylesheet is removed by one parent, then all other
+     * parents that use that stylesheet should get new styles if the 
+     * stylesheet is added back in (typical of SceneBuilder). This container
+     * provides the hooks to get back to those parents.
+     * 
+     * ParentStylesheetContainers are created and added to parentStylesheetMap
+     * in the StylesheetContainer method gatherParentStylesheets
      */
-    public void parentStylesheetsChanged(Scene scene, Change c) {
+    private static class ParentStylesheetContainer {
+        // the stylesheet url
+        private final String fname;
+        // the parsed stylesheet so we don't reparse for every parent that uses it
+        private final Stylesheet stylesheet;
+        // the parents that use this stylesheet. Typically, this list should
+        // be very small.
+        private final RefList<Parent> parents;
+        // the keys for finding Cache entries that use this stylesheet. 
+        // This list should also be fairly small
+        private final RefList<Key> keys;
+
+        private ParentStylesheetContainer(String fname, Stylesheet stylesheet) {
+            this.fname = fname;
+            this.stylesheet = stylesheet;
+            this.parents = new RefList<Parent>();
+            this.keys = new RefList<Key>();
+        }
+    }
+    
+    private static class RefList<K> {
         
+        private final List<Reference<K>> list = new ArrayList<Reference<K>>();
+        
+        private void add(K key) {
+
+            for (int n=list.size()-1; 0<=n; --n) {
+                final Reference<K> ref = list.get(n);
+                final K k = ref.get();
+                if (k == null) {
+                    // stale reference, remove it.
+                    list.remove(n);
+                } else {
+                    // already have it, bail
+                    if (k == key) return;
+                }
+            }
+            // not found, add it.
+            list.add(new WeakReference<K>(key));
+        }
+        
+    }
+    
+    /**
+    * Another map from String => Stylesheet. This one is for stylesheets that
+    * hang off a Parent. These are considered "author" stylesheets but are not
+    * added to the authorStylesheetMap because we don't want the scene's
+    * list of stylesheets in the container to be updated.
+    */
+    private static Map<String,ParentStylesheetContainer> parentStylesheetMap =
+            new HashMap<String,ParentStylesheetContainer>();
+
+    
+
+    /**
+     * called from Parent's stylesheets property's onChanged method
+     */
+    public void parentStylesheetsChanged(Parent parent, Change<String> c) {
+        
+        final Scene scene = parent.getScene();
         if (scene == null) return;
 
-        if (containerMap == null) {
-            containerMap = new HashMap<WeakReference<Scene>,StylesheetContainer>(); 
-        }
-        StylesheetContainer container = containerMap.get(scene);
-        if (container == null) {
-            container = new StylesheetContainer(null);
-            put(containerMap, scene, container);
-        }
-        
+        boolean wasRemoved = false;
+                
         while (c.next()) {
             
-            List<String> list = null;
-            // If the String was removed, remove it from parentStylesheetMap since
-            // it isn't referenced any more. It may be referenced by some other
-            // parent, in which case the stylesheet will be reparsed and added
+            // RT-22565
+            // If the String was removed, remove it from parentStylesheetMap
+            // and remove all Caches that got styles from the stylesheet. 
+            // The stylesheet may still be referenced by some other parent, 
+            // in which case the stylesheet will be reparsed and added
             // back to parentStylesheetMap when the StyleHelper is recreated.
-            if (c.wasRemoved()) list = c.getRemoved();
-            // If the String was added, remove it from parentStylesheetMap. When
-            // the StyleHelper is recreated, the stylesheet will be reparsed
-            // and added back to the parentStyleMap.
-            else if (c.wasAdded()) list = c.getAddedSubList();
+            // This incurs a some overhead since the stylesheet has to be
+            // reparsed, but this keeps the other Parents that use this
+            // in sync. For example, SceneBuilder will remove and then add
+            // a stylesheet after it has been edited and all Parents that use
+            // that stylesheet should get the new values. 
+            // 
+            if (c.wasRemoved()) {
+                
+                final List<String> list = c.getRemoved();
+                int nMax = list != null ? list.size() : 0;
+                for (int n=0; n<nMax; n++) {                
+                    final String fname = list.get(n);
+                    
+                    // remove this parent from the container and clear
+                    // all caches used by this stylesheet
+                    ParentStylesheetContainer psc = parentStylesheetMap.remove(fname);
+                    if (psc != null) {
+                        clearParentCache(psc);
+                    }
+                }                
+            }
             
-            // must have been a permutation. continue on to the next change.
-            if (list == null) continue;
+            // RT-22565: only wasRemoved matters. If the logic was applied to
+            // wasAdded, then the stylesheet would be reparsed each time a
+            // a Parent added it. 
             
-            for (int n=0, nMax=list.size(); n<nMax; n++) {
-                container.parentStylesheetMap.remove(list.get(n));
-            }                
         }
+        // parent uses change also
+        c.reset();
+    }
+
+    // RT-22565: Called from parentStylesheetsChanged to clear the cache entries
+    // for parents that use the same stylesheet
+    private void clearParentCache(ParentStylesheetContainer psc) {
         
-        container.clearCaches();        
+        final List<Reference<Parent>> parentList = psc.parents.list;
+        final List<Reference<Key>>    keyList    = psc.keys.list;
+        for (int n=parentList.size()-1; 0<=n; --n) {
+            
+            final Reference<Parent> ref = parentList.get(n);
+            final Parent parent = ref.get();
+            if (parent == null) continue;
+            
+            final Scene scene = parent.getScene();
+            if (scene == null) continue;
+
+            StylesheetContainer container = null;            
+            if (containerMap != null 
+                && (container = get(containerMap, scene)) != null) {
+                clearParentCache(container, keyList);
+            }
+
+            if (defaultContainer != null) {
+                clearParentCache(defaultContainer, keyList);
+            }
+            
+            // tell parent it needs to reapply css
+            parent.impl_reapplyCSS();
+        }
     }
+    
+    // RT-22565: Called from clearParentCache to clear the cache entries.
+    private void clearParentCache(StylesheetContainer container, List<Reference<Key>> keyList) {
+        
+        if (container.cacheMap.isEmpty()) return;
+        
+        for (int n=keyList.size()-1; 0<=n; --n) {
+            
+            final Reference<Key> ref = keyList.get(n);
+            final Key key = ref.get();
+            if (key == null) continue;
+            
+            final Cache cache = container.cacheMap.remove(key);
+        }
+    }
+    
     /**
      * A map from Scene => StylesheetContainer. This provides us a way to find
      * the stylesheets which apply to any given scene.
@@ -884,15 +1003,6 @@
         private final List<Stylesheet> stylesheets;
 
         /**
-        * Another map from String => Stylesheet. This one is for stylesheets that
-        * hang off a Parent. These are considered "author" stylesheets but are not
-        * added to the authorStylesheetMap because we don't want the scene's
-        * list of stylesheets in the container to be updated.
-        */
-        private static Map<String,Stylesheet> parentStylesheetMap =
-                new HashMap<String,Stylesheet>();
-
-        /**
          * The map of Caches, key'd by a combination of class name, style class,
          * and id.
          */
@@ -988,7 +1098,7 @@
         // stylesheets further down the tree (closer to the leaf) have
         // a higer ordinal in the cascade.
         //
-        private List<Stylesheet> gatherParentStylesheets(Parent parent) {
+        private List<ParentStylesheetContainer> gatherParentStylesheets(Parent parent) {
             
             if (parent == null) return null; 
             
@@ -996,22 +1106,33 @@
             
             if (parentStylesheets == null || parentStylesheets.isEmpty()) return null;
             
-            final List<Stylesheet> list = new ArrayList<Stylesheet>();
+            final List<ParentStylesheetContainer> list = new ArrayList<ParentStylesheetContainer>();
             
             for (int n=0, nMax=parentStylesheets.size(); n<nMax; n++) {
                 final String fname = parentStylesheets.get(n);
-                Stylesheet stylesheet = null;
+                ParentStylesheetContainer container = null;
                 if (parentStylesheetMap.containsKey(fname)) {
-                    stylesheet = parentStylesheetMap.get(fname);
+                    container = parentStylesheetMap.get(fname);
+                    // RT-22565: remember that this parent uses this stylesheet.
+                    // Later, if the cache is cleared, the parent is told to 
+                    // reapply css.
+                    container.parents.add(parent);
                 } else {
-                    stylesheet = StyleManager.getInstance().loadStylesheet(fname);
+                    final Stylesheet stylesheet = 
+                        StyleManager.getInstance().loadStylesheet(fname);
                     // stylesheet may be null which would mean that some IOException
                     // was thrown while trying to load it. Add it to the 
                     // parentStylesheetMap anyway as this will prevent further
-                    // attempts to parse the file. 
-                    parentStylesheetMap.put(fname, stylesheet);
+                    // attempts to parse the file
+                    container =
+                            new ParentStylesheetContainer(fname, stylesheet);
+                    // RT-22565: remember that this parent uses this stylesheet.
+                    // Later, if the cache is cleared, the parent is told to 
+                    // reapply css.
+                    container.parents.add(parent);
+                    parentStylesheetMap.put(fname, container);
                 }
-                if (stylesheet != null) list.add(stylesheet);
+                if (container != null) list.add(container);
             }
             
             return list;
@@ -1049,14 +1170,14 @@
             key.id = id;
             key.styleClass = styleClass;
             key.indices = hasParentStylesheets ? indicesOfParentsWithStylesheets : null;
- 
+            
             Cache cache = cacheMap.get(key);
 
             // the key is an instance variable and so we need to null the
             // key.styleClass to prevent holding a hard reference to the
             // styleClass (and its Node)
             key.styleClass = null;
-
+            
             // If the cache is null, then we need to create a new Cache and
             // add it to the cache map
             if (cache == null) {
@@ -1080,7 +1201,7 @@
                 // then the selector impacts its children.
                 boolean impactsChildren = false;
                 
-                final List<Stylesheet> parentStylesheets = 
+                final List<ParentStylesheetContainer> parentStylesheets = 
                     hasParentStylesheets 
                         ? gatherParentStylesheets(
                             ((node instanceof Parent) ? (Parent)node : node.getParent())
@@ -1102,13 +1223,20 @@
                     
                     // scene stylesheets come first since declarations from
                     // Parent stylesheets should take precedence.
-                    stylesheetsToProcess = parentStylesheets;
+                    stylesheetsToProcess = new ArrayList<Stylesheet>(parentStylesheets.size());
+                    for (int n=0, nMax=parentStylesheets.size(); n<nMax; n++) {
+                        final ParentStylesheetContainer psc = parentStylesheets.get(n);
+                        stylesheetsToProcess.add(psc.stylesheet);
+                    }
                     stylesheetsToProcess.addAll(0,stylesheets);
                 }                    
 
                 for (int i = 0, imax = stylesheetsToProcess.size(); i < imax; i++) {
-                    final Stylesheet ss = stylesheetsToProcess.get(i);
-                    final List<Rule> stylesheetRules = ss.getRules();
+                    final Stylesheet ss = stylesheetsToProcess.get(i); 
+                    
+                    final List<Rule> stylesheetRules = ss != null ? ss.getRules() : null;
+                    if (stylesheetRules == null || stylesheetRules.isEmpty()) continue;
+
                     for (int j = 0, jmax = stylesheetRules.size(); j < jmax; j++) {
                         Rule rule = stylesheetRules.get(j);
                         boolean mightApply = rule.mightApply(className, id, styleClass);
@@ -1146,7 +1274,8 @@
                         // For each selector, rule, stylesheet look for whether this Node
                         // is referenced in the ancestor part of the selector, and whether or
                         // not it also has pseudoclasses specified
-                        for (int s = 0, smax = rule.selectors.size(); s < smax; s++) {
+                        final int smax = rule.selectors != null ? rule.selectors.size() : 0;
+                        for (int s = 0; s < smax; s++) {
                             final Selector selector = rule.selectors.get(s);
                             if (selector instanceof CompoundSelector) {
 
@@ -1199,7 +1328,6 @@
                 // regardless of whether or not the cache is shared, a Cache
                 // object is still needed in order to do the lookup.
                 //
-                cache = new Cache(this, rules, pseudoclassStateMask, impactsChildren);
                 final Key newKey = new Key();
                 newKey.className = className;
                 newKey.id = id;
@@ -1211,7 +1339,18 @@
                 for(int n=0; n<nElements; n++) newKey.styleClass.add(styleClass.get(n));
                 newKey.indices = hasParentStylesheets ? indicesOfParentsWithStylesheets : null;
                 
+                cache = new Cache(this, rules, pseudoclassStateMask, impactsChildren);
                 cacheMap.put(newKey, cache);
+                
+                // RT-22565: remember where this cache is used if there are 
+                // parent stylesheets involve so the cache can be cleared later
+                // from the parentStylesheetsChanged method.
+                final int nMax = parentStylesheets != null ? parentStylesheets.size() : 0;
+                for (int n=0; n<nMax; n++) {
+                    final ParentStylesheetContainer psc = parentStylesheets.get(n);
+                    psc.keys.add(newKey);
+                }
+                
             }
             // Return the style helper looked up by the cache. The cache will
             // create a style helper if necessary (and possible), so we don't
@@ -1268,6 +1407,7 @@
         private final long pseudoclassStateMask;
         private final boolean impactsChildren;
         private final Map<Long, StyleMap> cache;
+        
         Cache(StylesheetContainer owner, List<Rule> rules, long pseudoclassStateMask, boolean impactsChildren) {
             this.owner = owner;
             this.rules = rules;
--- a/javafx-ui-common/src/javafx/scene/Parent.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/Parent.java	Tue Jul 03 16:18:42 2012 -0700
@@ -1074,7 +1074,7 @@
     private final ObservableList<String> stylesheets = new TrackableObservableList<String>() {
         @Override
         protected void onChanged(Change<String> c) {
-            StyleManager.getInstance().parentStylesheetsChanged(getScene(), c);
+            StyleManager.getInstance().parentStylesheetsChanged(Parent.this, c);
             // RT-9784 - if stylesheet is removed, reset styled properties to 
             // their initial value.
             while(c.next()) {
--- a/javafx-ui-common/src/javafx/scene/Scene.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/Scene.java	Tue Jul 03 16:18:42 2012 -0700
@@ -1514,6 +1514,7 @@
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
      */
+    // SB-dependency: RT-22747 has been filed to track this
     @Deprecated
     public void impl_processMouseEvent(MouseEvent e) {
         if (e.getEventType() == MouseEvent.MOUSE_CLICKED) {
--- a/javafx-ui-common/src/javafx/scene/canvas/Canvas.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/canvas/Canvas.java	Tue Jul 03 16:18:42 2012 -0700
@@ -95,6 +95,7 @@
     }
 
     GrowableDataBuffer<Object> getBuffer() {
+        impl_markDirty(DirtyBits.NODE_CONTENTS);
         if (theBuffer == null) {
             theBuffer = new GrowableDataBuffer<Object>(DEFAULT_BUF_SIZE);
         }
@@ -111,12 +112,6 @@
         return theContext;
     }
 
-    void markBufferDirty() {
-        if (theBuffer == null || theBuffer.position() == 0) {
-            impl_markDirty(DirtyBits.NODE_CONTENTS);
-        }
-    }
-
     /**
      * Defines the width of the canvas.
      *
--- a/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/canvas/GraphicsContext.java	Tue Jul 03 16:18:42 2012 -0700
@@ -211,7 +211,6 @@
     }
 
     private GrowableDataBuffer getBuffer() {
-        theCanvas.markBufferDirty();
         return theCanvas.getBuffer();
     }
 
--- a/javafx-ui-common/src/javafx/scene/doc-files/cssref.html	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/doc-files/cssref.html	Tue Jul 03 16:18:42 2012 -0700
@@ -1,9 +1,9 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html lang="en-US">
   <head>
-    <meta name="description" content="This document describes the JavaFX 
+    <meta name="description" content="This document describes the JavaFX
               Cascading Style Sheets (CSS) for JavaFX 2 and explains the              styles, values, properties and associated grammar.">
-    <meta name="keywords" content="JavaFX 2, JavaFX CSS, JavaFX CSS 
+    <meta name="keywords" content="JavaFX 2, JavaFX CSS, JavaFX CSS
               reference, JavaFX styling, CSS styles, CSS, cascading style sheets,              JavaFX GUI development, JavaFX application development">
     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
     <title>JavaFX CSS Reference Guide</title>
@@ -295,6 +295,7 @@
               <li><a href="#menubutton">MenuButton</a></li>
               <li><a href="#menuitem">MenuItem</a></li>
               <li><a href="#menuitembase">MenuItemBase</a></li>
+              <li><a href="#pagination">Pagination</a></li>
               <li><a href="#passwordfield">PasswordField</a></li>
               <li><a href="#progressbar">ProgressBar</a></li>
               <li><a href="#progressindicator">ProgressIndicator</a></li>
@@ -3050,7 +3051,7 @@
         </tr>
       </tbody>
     </table>
-    <!-- 
+    <!--
         --        --        -- Controls        --        -->
     <table summary="property table" class="package" width="100%">
       <tbody>
@@ -3577,6 +3578,72 @@
     </table>
     <h4><a name="menuitem" id="menuitem">MenuItem</a></h4>
     <p class="styleclass">Style class: menu-item</p>
+    <h4><a name="pagination" id="pagination">Pagination</a></h4>
+    <p class="styleclass">Style class: pagination</p>
+	<p>Pagination has all the pseudo-class states of <a href="#control">Control</a></p>
+    <table summary="property table" class="csspropertytable" cellpadding="2" cellspacing="1">
+      <thead>
+        <tr>
+          <th class="propertyname">CSS Property</th>
+          <th class="value">Values</th>
+          <th>Default</th>
+          <th>Comments</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td class="propertyname">-fx-max-page-indicator-count</td>
+          <td class="value"><a href="#typesize" class="typelink">&lt;number&gt;</a></td>
+          <td>10</td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td class="propertyname">-fx-arrows-visible</td>
+          <td class="value"><a href="#typesize" class="typelink">&lt;boolean&gt;</a></td>
+          <td>true</td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td class="propertyname">-fx-tooltip-visible</td>
+          <td class="value"><a href="#typesize" class="typelink">&lt;boolean&gt;</a></td>
+          <td>true</td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td class="propertyname">fx-page-information-visible:</td>
+          <td class="value"><a href="#typesize" class="typelink">&lt;boolean&gt;</a></td>
+          <td>true</td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td class="propertyname">-fx-page-information-alignment</td>
+          <td class="value">[ top | bottom | left | right ]</td>
+          <td>bottom</td>
+          <td>&nbsp;</td>
+        </tr>
+        <tr>
+          <td colspan="4" class="parents">Also has all properties of <a href="#control">Control</a></td>
+        </tr>
+      </tbody>
+    </table>
+    <h4>Substructure</h4>
+    <ul>
+	  <li>page &mdash; StackPane</li>
+      <li>pagination-control &mdash; StackPane</li>
+        <ul>
+          <li>leftArrowButton - Button</li>
+	    <ul>
+		  <li>leftArrow &mdash; StackPane</li>
+	    </ul>
+	    <li>rightArrowButton - Button</li>
+	    <ul>
+		  <li>rightArrow &mdash; StackPane</li>
+	    </ul>
+	    <li>bullet-button - ToggleButton</li>
+	    <li>number-button - ToogleButton</li>
+	    <li>page-information - Label</li>
+	  </ul>
+    </ul>
     <h4><a name="passwordfield" id="passwordfield">PasswordField</a></h4>
     <p class="styleclass">Style class: password-field</p>
     <p>The PasswordField control has all the properties of <a href="#textfield">TextField</a></p>
@@ -4561,7 +4628,7 @@
     <h4><a name="treeview" id="treeview">TreeView</a></h4>
     <p class="styleclass">Style class: tree-view</p>
     <p>TreeView has all the properites and pseudo-class state of <a href="#control">Control</a></p>
-    <!-- 
+    <!--
         --        --        -- Charts        --        -->
     <h2><a name="charts" id="charts">Charts</a></h2>
     <table summary="property table" class="package" width="100%">
--- a/javafx-ui-common/src/javafx/scene/input/KeyCode.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/input/KeyCode.java	Tue Jul 03 16:18:42 2012 -0700
@@ -1297,6 +1297,7 @@
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
      */
+    // SB-dependency: RT-22749 has been filed to track this
     @Deprecated
     public int impl_getCode() {
         return code;
--- a/javafx-ui-common/src/javafx/scene/layout/HBox.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/layout/HBox.java	Tue Jul 03 16:18:42 2012 -0700
@@ -60,7 +60,7 @@
  * fillHeight property to determine whether to resize their heights to
  * fill its own height or keep their heights to their preferred (fillHeight defaults to true).
  * The alignment of the content is controlled by the alignment property,
- * which defaulst to Pos.TOP_LEFT.
+ * which defaults to Pos.TOP_LEFT.
  * <p>
  * If an hbox is resized larger than its preferred width, by default it will keep
  * children to their preferred widths, leaving the extra space unused.  If an
--- a/javafx-ui-common/src/javafx/scene/layout/TilePane.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/layout/TilePane.java	Tue Jul 03 16:18:42 2012 -0700
@@ -163,9 +163,10 @@
  * <pre><code>
  *     TilePane tilepane = new TilePane();
  *     for (int i = 0; i < 20; i++) {
- *        Label label = new Label(imageTitle[i]):
+ *        Label title = new Label(imageTitle[i]):
+ *        Imageview imageview = new ImageView(new Image(imageName[i])); 
  *        TilePane.setAlignment(label, Pos.BOTTOM_RIGHT);
- *        tilepane.getChildren().addAll(title, imageview[i]);
+ *        tilepane.getChildren().addAll(title, imageview);
  *     }
  * </code></pre>
  */
@@ -918,6 +919,10 @@
              new StyleableProperty<TilePane,Number>("-fx-pref-columns",
                  SizeConverter.getInstance(), 5.0) {
 
+            @Override public void set(TilePane node, Number value, Origin origin) {
+                super.set(node, value.intValue(), origin);
+            }
+            
             @Override
             public boolean isSettable(TilePane node) {
                 return node.prefColumns == null ||
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/StylesheetTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/StylesheetTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -28,6 +28,10 @@
 import java.net.URL;
 import java.util.Collections;
 import java.util.List;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
 import org.junit.*;
 import static org.junit.Assert.*;
 
@@ -192,4 +196,27 @@
         fail("The test case is a prototype.");
     }
      */
+    
+    @Test
+    public void testRT_23140() {
+
+        try {
+            Group root = new Group();
+            root.getChildren().add(new Rectangle(50,50));        
+            Scene scene = new Scene(root, 500, 500);
+            root.getStylesheets().add("bogus.css");
+            Stage stage = new Stage();
+            stage.setScene(scene);
+            stage.show();
+        } catch (NullPointerException e) {
+            // RT-23140 is supposed to fix the NPE. Did it?
+            fail("Test purpose failed: " + e.toString());
+        } catch (Exception e) {
+            // Something other than an NPE should still raise a red flag,
+            // but the exception is not what RT-23140 fixed.
+            fail("Exception not expected: " + e.toString());
+        }
+        
+    }
+    
 }
--- a/javafx-ui-common/test/unit/javafx/scene/layout/TilePaneTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-common/test/unit/javafx/scene/layout/TilePaneTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -950,4 +950,22 @@
             Assert.fail(e.toString());
         }
     }    
+    
+      
+    @Test public void testCSSsetPrefColumns_RT22929() {        
+        Scene scene = new Scene(tilepane);
+        Stage stage = new Stage();
+        stage.setScene(scene);                
+        stage.show();
+        
+        ParsedValue pv = CSSParser.getInstance().parseExpr("-fx-pref-columns","2");
+        Object val = pv.convert(null);        
+        StyleableProperty prop = StyleableProperty.getStyleableProperty(tilepane.prefColumnsProperty());
+        try {
+            prop.set(tilepane, val, null);
+            assertEquals(2, tilepane.getPrefColumns(), 0.00001);
+        } catch (Exception e) {
+            Assert.fail(e.toString());
+        }
+    }      
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java	Tue Jul 03 16:18:42 2012 -0700
@@ -144,8 +144,8 @@
         int index = tabPane.getTabs().indexOf(tab);
         if (tab.isSelected()) {
             if (index == 0) {
-                if (tabPane.getTabs().size() > 1) {
-                    tabPane.getSelectionModel().clearSelection();
+                if (tabPane.getTabs().size() > 0) {
+                    tabPane.getSelectionModel().selectFirst();
                 }
             } else {
                 tabPane.getSelectionModel().selectPrevious();
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeCellBehavior.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TreeCellBehavior.java	Tue Jul 03 16:18:42 2012 -0700
@@ -138,11 +138,14 @@
     @Override public void mouseDragged(MouseEvent event) {
         latePress = false;
         
+        TreeView treeView = getControl().getTreeView();
+        if (treeView == null || treeView.getSelectionModel() == null) return;
+        
         // the mouse has now been dragged on a touch device, we should
         // remove the selection if we just added it in the last mouse press
         // event
         if (isEmbedded && ! wasSelected && getControl().isSelected()) {
-            getControl().getTreeView().getSelectionModel().clearSelection(getControl().getIndex());
+            treeView.getSelectionModel().clearSelection(getControl().getIndex());
         }
     }
     
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Tue Jul 03 16:18:42 2012 -0700
@@ -408,7 +408,7 @@
         } else {
             // run item through StringConverter if it isn't null
             StringConverter c = comboBox.getConverter();
-            String s = item == null ? "" : (c == null ? item.toString() : c.toString(item));
+            String s = item == null ? comboBox.getPromptText() : (c == null ? item.toString() : c.toString(item));
             cell.setText(s);
             cell.setGraphic(null);
         }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/NestedTableColumnHeader.java	Tue Jul 03 16:18:42 2012 -0700
@@ -417,7 +417,7 @@
         for (TableColumnHeader n : getColumnHeaders()) {
             if (! n.isVisible()) continue;
             
-            double prefWidth = n.prefWidth(-1);
+            double prefWidth = snapSize(n.prefWidth(-1));
 //            double prefHeight = n.prefHeight(-1);
 
             // position the column header in the default location...
@@ -453,7 +453,7 @@
         if (getColumns() != null) {
             for (TableColumnHeader c : getColumnHeaders()) {
                 if (c.isVisible()) {
-                    width += c.computePrefWidth(height);
+                    width += snapSize(c.computePrefWidth(height));
                 }
             }
         }
--- a/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/ComboBox.java	Tue Jul 03 16:18:42 2012 -0700
@@ -384,11 +384,16 @@
     // When it changes, set the selectedItem in the value property.
     private ChangeListener<T> selectedItemListener = new ChangeListener<T>() {
         @Override public void changed(ObservableValue<? extends T> ov, T t, T t1) {
-            if (wasSetAllCalled) {
+            if (wasSetAllCalled && t1 == null) {
                 // no-op: fix for RT-22572 where the developer was completely
                 // replacing all items in the ComboBox, and expecting the 
                 // selection (and ComboBox.value) to remain set. If this isn't
                 // here, we would updateValue(null). 
+                // Additional fix for RT-22937: adding the '&& t1 == null'. 
+                // Without this, there would be circumstances where the user 
+                // selecting a new value from the ComboBox would end up in here,
+                // when we really should go into the updateValue(t1) call below.
+                // We should only ever go into this clause if t1 is null.
                 wasSetAllCalled = false;
             } else {
                 updateValue(t1);
--- a/javafx-ui-controls/src/javafx/scene/control/TabPane.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/TabPane.java	Tue Jul 03 16:18:42 2012 -0700
@@ -629,8 +629,8 @@
                     while (c.next()) {
                         for (Tab tab : c.getRemoved()) {
                             if (tab != null && !tabPane.getTabs().contains(tab)) {
-                                if (getSelectedIndex() == 0 && tabPane.getTabs().size() > 0) {
-                                    clearSelection();
+                                if (getSelectedIndex() == 0 && tabPane.getTabs().size() > 0) {                                    
+                                    clearAndSelect(0);
                                     tab.setSelected(false);
                                 }
                                 if (tab.isSelected()) {
@@ -653,7 +653,7 @@
                             }
                         }
                     }
-                    if (getSelectedIndex() == -1 && getSelectedItem() == null && tabPane.getTabs().size() > 0) {
+                    if (getSelectedIndex() == -1 && getSelectedItem() == null && tabPane.getTabs().size() > 0) {                        
                         selectFirst();
                     } else if (tabPane.getTabs().isEmpty()) {
                         clearSelection();
@@ -667,10 +667,11 @@
 
         // API Implementation
         @Override public void select(int index) {
-            if (index < 0 || (getItemCount() > 0 && index >= getItemCount()) || getSelectedIndex() == index) {
+            if (index < 0 || (getItemCount() > 0 && index >= getItemCount()) ||
+                (index == getSelectedIndex() && getModelItem(index).isSelected())) {
                 return;
             }
-
+            
             // Unselect the old tab
             if (getSelectedIndex() >= 0 && getSelectedIndex() < tabPane.getTabs().size()) {
                 tabPane.getTabs().get(getSelectedIndex()).setSelected(false);
--- a/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeCell.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/CheckBoxTreeCell.java	Tue Jul 03 16:18:42 2012 -0700
@@ -305,6 +305,8 @@
     
     private ObservableValue<Boolean> booleanProperty;
     
+    private BooleanProperty indeterminateProperty;
+    
     
     
     /***************************************************************************
@@ -506,9 +508,9 @@
             if (booleanProperty != null) {
                 checkBox.selectedProperty().unbindBidirectional((BooleanProperty)booleanProperty);
             }
-//            if (indeterminateProperty != null) {
-//                checkBox.indeterminateProperty().unbindBidirectional(indeterminateProperty);
-//            }
+            if (indeterminateProperty != null) {
+                checkBox.indeterminateProperty().unbindBidirectional(indeterminateProperty);
+            }
 
             // install new bindings.
             // We special case things when the TreeItem is a CheckBoxTreeItem
@@ -517,8 +519,8 @@
                 booleanProperty = cbti.selectedProperty();
                 checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty);
                 
-//                indeterminateProperty = cbti.indeterminateProperty();
-//                checkBox.indeterminateProperty().bindBidirectional(indeterminateProperty);
+                indeterminateProperty = cbti.indeterminateProperty();
+                checkBox.indeterminateProperty().bindBidirectional(indeterminateProperty);
             } else {
                 booleanProperty = callback.call(getTreeItem());
                 if (booleanProperty != null) {
--- a/javafx-ui-controls/src/javafx/scene/control/cell/package.html	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/src/javafx/scene/control/cell/package.html	Tue Jul 03 16:18:42 2012 -0700
@@ -12,10 +12,9 @@
     and {@link javafx.scene.control.TableCell TableCell}. At present this package
     is relatively bare, but it is where future cell-related classes will be located.</p>
     
-    <p>At present the only class available in this package is the 
-    {@link javafx.scene.control.cell.PropertyValueFactory PropertyValueFactory}, 
-    which helps to simplify the population of the TableCell
-    {@link javafx.scene.control.TableCell#itemProperty() item} property. Refer
-    to the class documentation for more information and examples of how to use it.
+    <p>It is important to note that whilst most cells in this package are editable,
+        for a cells editing functionality to be enabled it is required that all
+        related classes have editing enabled. For example, in a TableView, both
+        the TableView and the relevant TableColumn must have setEditing(true) called.
 </body>
 </html>
--- a/javafx-ui-controls/test/javafx/scene/control/TabPaneTest.java	Fri Jun 29 21:46:13 2012 -0700
+++ b/javafx-ui-controls/test/javafx/scene/control/TabPaneTest.java	Tue Jul 03 16:18:42 2012 -0700
@@ -15,6 +15,8 @@
 import javafx.beans.property.SimpleBooleanProperty;
 import javafx.beans.property.SimpleDoubleProperty;
 import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.geometry.Side;
@@ -742,4 +744,27 @@
         assertEquals(0, tabPane.getSelectionModel().getSelectedIndex());
         assertEquals(tab2, tabPane.getSelectionModel().getSelectedItem());        
     }
+    
+    @Test public void selectionModelShouldNotBeNullWhenClosingFirstTab_RT22925() {
+        tabPane.getTabs().add(tab1);
+        tabPane.getTabs().add(tab2);
+        tabPane.getTabs().add(tab3);        
+
+        tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
+            public void changed(ObservableValue<? extends Tab> ov, Tab t, Tab t1) {
+                assertEquals(t.getText(), "one");
+                assertEquals(t1.getText(), "two");
+            }            
+        });
+        
+        assertEquals("one", tabPane.getTabs().get(0).getText());
+        assertEquals("two", tabPane.getTabs().get(1).getText());
+        assertEquals("three", tabPane.getTabs().get(2).getText());
+        
+        tabPane.getTabs().remove(tab1);
+
+        assertEquals(2, tabPane.getTabs().size());
+        assertEquals(0, tabPane.getSelectionModel().getSelectedIndex());
+        assertEquals(tab2, tabPane.getSelectionModel().getSelectedItem());        
+    }    
 }