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 }
|