modules/controls/src/main/java/javafx/scene/control/skin/VirtualContainerBase.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
   1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.scene.control.skin;
  27 



  28 import javafx.scene.control.Control;
  29 import javafx.scene.control.IndexedCell;
  30 import javafx.scene.control.ScrollToEvent;
  31 
  32 import com.sun.javafx.scene.control.behavior.BehaviorBase;
  33 
  34 /**
  35  * Parent class to control skins whose contents are virtualized and scrollable.
  36  * This class handles the interaction with the VirtualFlow class, which is the
  37  * main class handling the virtualization of the contents of this container.
  38  *
  39  * @profile common
  40  */
  41 public abstract class VirtualContainerBase<C extends Control, B extends BehaviorBase<C>, I extends IndexedCell> extends BehaviorSkinBase<C, B> {
















  42     
  43     protected boolean rowCountDirty;




  44 
  45     public VirtualContainerBase(final C control, B behavior) {
  46         super(control, behavior);




  47         flow = createVirtualFlow();
  48         
  49         control.addEventHandler(ScrollToEvent.scrollToTopIndex(), event -> {
  50             // Fix for RT-24630: The row count in VirtualFlow was incorrect
  51             // (normally zero), so the scrollTo call was misbehaving.
  52             if (rowCountDirty) {
  53                 // update row count before we do a scroll
  54                 updateRowCount();
  55                 rowCountDirty = false;
  56             }
  57             flow.scrollTo(event.getScrollTarget());
  58         });
  59     }
  60 
  61     /**
  62      * The virtualized container which handles the layout and scrolling of
  63      * all the cells.
  64      */
  65     protected final VirtualFlow<I> flow;


  66 
  67     /**
  68      * Returns a Cell available to be used in the virtual flow. This means you
  69      * may return either a previously used, but now unrequired cell, or alternatively
  70      * create a new Cell instance.
  71      *
  72      * Preference is obviously given to reusing cells whenever possible, to keep
  73      * performance costs down.
  74      */
  75     public abstract I createCell();























  76 
  77     /**
  78      * This enables skin subclasses to provide a custom VirtualFlow implementation,
  79      * rather than have VirtualContainerBase instantiate the default instance.
  80      */
  81     protected VirtualFlow<I> createVirtualFlow() {
  82         return new VirtualFlow<I>();
  83     }
  84 
  85     /**
  86      * Returns the total number of items in this container, including those
  87      * that are currently hidden because they are out of view.
  88      */
  89     public abstract int getItemCount();
  90     
  91     protected abstract void updateRowCount();
  92 
  93     double getMaxCellWidth(int rowsToCount) {
  94         return snappedLeftInset() + flow.getMaxCellWidth(rowsToCount) + snappedRightInset();
  95     }
  96     
  97     double getVirtualFlowPreferredHeight(int rows) {
  98         double height = 1.0;
  99         
 100         for (int i = 0; i < rows && i < getItemCount(); i++) {
 101             height += flow.getCellLength(i);
 102         }
 103 
 104         return height + snappedTopInset() + snappedBottomInset();
 105     }
 106 
 107     @Override protected void layoutChildren(double x, double y, double w, double h) {
 108         checkState();
 109     }
 110 
 111     protected void checkState() {
 112         if (rowCountDirty) {
 113             updateRowCount();
 114             rowCountDirty = false;
 115         }
 116     }
 117 }
   1 /*
   2  * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.control.skin;
  27 
  28 import javafx.beans.property.ObjectProperty;
  29 import javafx.beans.property.SimpleObjectProperty;
  30 import javafx.scene.control.Cell;
  31 import javafx.scene.control.Control;
  32 import javafx.scene.control.IndexedCell;
  33 import javafx.scene.control.ScrollToEvent;
  34 import javafx.scene.control.SkinBase;
  35 import javafx.util.Callback;
  36 
  37 /**
  38  * Parent class to control skins whose contents are virtualized and scrollable.
  39  * This class handles the interaction with the VirtualFlow class, which is the
  40  * main class handling the virtualization of the contents of this container.


  41  */
  42 public abstract class VirtualContainerBase<C extends Control, I extends IndexedCell> extends SkinBase<C> {
  43 
  44     /***************************************************************************
  45      *                                                                         *
  46      * Private fields                                                          *
  47      *                                                                         *
  48      **************************************************************************/
  49     
  50     boolean rowCountDirty;
  51 
  52     /**
  53      * The virtualized container which handles the layout and scrolling of
  54      * all the cells.
  55      */
  56     private final VirtualFlow<I> flow;
  57 
  58 
  59 
  60     /***************************************************************************
  61      *                                                                         *
  62      * Constructors                                                            *
  63      *                                                                         *
  64      **************************************************************************/
  65 
  66     /**
  67      *
  68      * @param control
  69      */
  70     public VirtualContainerBase(final C control) {
  71         super(control);
  72         flow = createVirtualFlow();
  73         
  74         control.addEventHandler(ScrollToEvent.scrollToTopIndex(), event -> {
  75             // Fix for RT-24630: The row count in VirtualFlow was incorrect
  76             // (normally zero), so the scrollTo call was misbehaving.
  77             if (rowCountDirty) {
  78                 // update row count before we do a scroll
  79                 updateRowCount();
  80                 rowCountDirty = false;
  81             }
  82             flow.scrollToTop(event.getScrollTarget());
  83         });
  84     }
  85 
  86 
  87 
  88     /***************************************************************************
  89      *                                                                         *
  90      * Abstract API                                                            *
  91      *                                                                         *
  92      **************************************************************************/
  93 
  94     /**
  95      * Returns the total number of items in this container, including those
  96      * that are currently hidden because they are out of view.




  97      */
  98     abstract int getItemCount();
  99     
 100     abstract void updateRowCount();
 101 
 102 
 103 
 104     /***************************************************************************
 105      *                                                                         *
 106      * Public API                                                              *
 107      *                                                                         *
 108      **************************************************************************/
 109 
 110     /** {@inheritDoc} */
 111     @Override protected void layoutChildren(double x, double y, double w, double h) {
 112         checkState();
 113     }
 114 
 115 
 116 
 117     /***************************************************************************
 118      *                                                                         *
 119      * Private methods                                                         *
 120      *                                                                         *
 121      **************************************************************************/
 122 
 123     /**
 124      * This enables skin subclasses to provide a custom VirtualFlow implementation,
 125      * rather than have VirtualContainerBase instantiate the default instance.
 126      */
 127     VirtualFlow<I> createVirtualFlow() {
 128         return new VirtualFlow<>();
 129     }
 130 
 131     final VirtualFlow<I> getVirtualFlow() {
 132         return flow;
 133     }




 134 
 135     double getMaxCellWidth(int rowsToCount) {
 136         return snappedLeftInset() + flow.getMaxCellWidth(rowsToCount) + snappedRightInset();
 137     }
 138 
 139     double getVirtualFlowPreferredHeight(int rows) {
 140         double height = 1.0;
 141 
 142         for (int i = 0; i < rows && i < getItemCount(); i++) {
 143             height += flow.getCellLength(i);
 144         }
 145 
 146         return height + snappedTopInset() + snappedBottomInset();
 147     }
 148 
 149     void checkState() {




 150         if (rowCountDirty) {
 151             updateRowCount();
 152             rowCountDirty = false;
 153         }
 154     }
 155 }