Class VFXTableHelper.FixedTableHelper<T>
- All Implemented Interfaces:
VFXTableHelper<T>
- Enclosing interface:
VFXTableHelper<T>
VFXTableHelper.AbstractHelper
for ColumnsLayoutMode.FIXED
.
Here the range of rows and columns to display, as well as the viewport position,
the virtual max x and y properties are defined as follows:
- the columns range is given by the firstColumn()
element minus the buffer size VFXTable.columnsBufferSizeProperty()
,
(cannot be negative) and the sum between this start index and the total number of needed columns given by totalColumns()
.
It may happen that the number of indexes given by the range end - start + 1
is
lesser than the total number of columns we need. In such cases, the range start is corrected to be
end - needed + 1
. A typical situation for this is when the table's horizontal position reaches the max scroll.
If the table's width is 0 or the number of needed columns is 0, then the range will be Utils.INVALID_RANGE
.
The computation has the following dependencies: the columns' list, the table width, the horizontal position,
the columns buffer size and the columns' size.
- the rows range is given by the VFXTableHelper.AbstractHelper.firstRow()
element minus the buffer size VFXTable.rowsBufferSizeProperty()
,
(cannot be negative) and the sum between this start index and the total number of needed rows given by VFXTableHelper.AbstractHelper.totalRows()
.
It may happen that the number of indexes given by the range end - start + 1
is
lesser than the number of rows we need. In such cases, the range start is corrected to be
end - needed + 1
. A typical situation for this is when the table's vertical position reaches the max scroll.
If the viewport's height is 0 or the number of needed rows is 0, then the range will be Utils.INVALID_RANGE
.
The computation has the following dependencies: the table's height, the column's size (because it also specifies the
header height, which influences the viewport's height), the vertical position, the rows buffer size, the rows' height
and the items' list size.
- the viewport's position, a computation that is at the core of virtual scrolling. The viewport, which contains
the columns and the cells (even though the table's viewport is a bit more complex), is not supposed to scroll by insane
numbers of pixels both for performance reasons and because it is not necessary.
For both the horizontal and vertical positions, we use the same technique, just using the appropriate values according
to the axis we are working on.
First we get the range of rows/columns to display, then their respective sizes (rows' height, columns' width).
We compute the ranges to the first visible row/column, which are given by IntegerRange.of(range.getMin(), first())
,
in other words we limit the 'complete' ranges to the start buffer including the first row/column after the buffer.
The number of indexes in the newfound ranges (given by IntegerRange.diff()
) is multiplied by the respective
sizes, this way we are finding the number of pixels to the first visible row/column, pixelsToFirst
.
At this point, we are missing only one last piece of information: how much of the first row/column do we actually see?
We call this amount visibleAmountFirst
and it's given by pos % size
.
Finally, the viewport's position is given by this formula -(pixelsToFirst + visibleAmountFirst)
(for both hPos and vPos of course).
If a range is equal to Utils.INVALID_RANGE
, the respective position will be 0!
While it's true that the calculations are more complex and 'needy', it's important to note that this approach
allows avoiding 'hacks' to correctly lay out the cells in the viewport. No need for special offsets at the top
or bottom anymore.
The viewport's position computation has the following dependencies: the vertical and horizontal positions,
the rows' height and the columns' size.
- the virtual max x and y properties, which give the total number of pixels on the x-axis and y-axis. Virtual means that it's not the actual size of the container, rather the size it would have if it was not virtualized. The two values are given by the number of rows/columns multiplied by the respective size (rows' height, columns' width). Notes: 1) the virtualMaxX is the maximum between the aforementioned computation and the table's width (because the last column must always take all the available space). 2) the virtualMaxY is going to be 0 if there are no columns in the table. The computations have the following dependencies: the table's width, the number of columns and items, the columns' size, the rows' height.
-
Property Summary
Properties inherited from class io.github.palexdev.virtualizedfx.table.VFXTableHelper.AbstractHelper
columnsRange, maxHScroll, maxVScroll, rowsRange, viewportPosition, virtualMaxX, virtualMaxY
-
Nested Class Summary
Nested classes/interfaces inherited from interface io.github.palexdev.virtualizedfx.table.VFXTableHelper
VFXTableHelper.AbstractHelper<T>, VFXTableHelper.FixedTableHelper<T>, VFXTableHelper.VariableTableHelper<T>
-
Field Summary
Fields inherited from class io.github.palexdev.virtualizedfx.table.VFXTableHelper.AbstractHelper
columnsRange, maxHScroll, maxVScroll, rowsRange, table, viewportPosition, virtualMaxX, virtualMaxY
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
autosizeColumn
(VFXTableColumn<T, ?> column) This method is a no-op as the operation is not possible inColumnsLayoutMode.FIXED
.void
InColumnsLayoutMode.FIXED
this can be still used by setting theVFXTable.columnsSizeProperty()
rather than the width of each column.int
double
getColumnPos
(int layoutIdx, VFXTableColumn<T, ?> column) double
getColumnWidth
(VFXTableColumn<T, ?> column) protected void
Bindings and listeners should be initialized here, automatically called after the table instance is set.boolean
isInViewport
(VFXTableColumn<T, ?> column) boolean
layoutCell
(int layoutIdx, VFXTableCell<T> cell) Lays out the given cell.boolean
layoutColumn
(int layoutIdx, VFXTableColumn<T, ?> column) Lays out the given column.void
scrollToIndex
(javafx.geometry.Orientation orientation, int index) Scrolls in the viewport, depending on the given direction (orientation) to:int
int
Depends on the implementation!int
Methods inherited from class io.github.palexdev.virtualizedfx.table.VFXTableHelper.AbstractHelper
columnsRangeProperty, dispose, firstRow, getTable, lastColumn, lastRow, maxHScrollProperty, maxVScrollProperty, rowsRangeProperty, totalRows, viewportPositionProperty, virtualMaxXProperty, virtualMaxYProperty, visibleRows
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface io.github.palexdev.virtualizedfx.table.VFXTableHelper
columnsRange, getMaxHScroll, getMaxVScroll, getViewportHeight, getViewportPosition, getVirtualMaxX, getVirtualMaxY, indexToItem, indexToRow, invalidatePos, isLastColumn, itemToRow, layoutRow, rowsRange, scrollBy, scrollToPixel, totalCells
-
Constructor Details
-
FixedTableHelper
-
-
Method Details
-
initBindings
protected void initBindings()Description copied from class:VFXTableHelper.AbstractHelper
Bindings and listeners should be initialized here, automatically called after the table instance is set.- Overrides:
initBindings
in classVFXTableHelper.AbstractHelper<T>
-
firstColumn
public int firstColumn()Given byMath.floor(hPos / columnsWidth)
, clamped between 0 and the number of columns - 1.- Returns:
- the index of the first visible column
-
visibleColumns
public int visibleColumns()Given byMath.ceil(tableWidth / columnsWidth)
. 0 if the columns' width is also 0.- Returns:
- the number of columns visible in the viewport. Not necessarily the same as
VFXTableHelper.totalColumns()
-
totalColumns
public int totalColumns()Given byvisibleColumns()
plus double the value ofVFXTable.columnsBufferSizeProperty()
, cannot exceed the number of columns in the table.- Returns:
- the total number of columns in the viewport which doesn't include only the number of visible columns but also the number of buffer columns
- See Also:
-
getColumnWidth
For theColumnsLayoutMode.FIXED
mode, all columns will have the same width specified byVFXTable.columnsSizeProperty()
, except for the last one that needs to take all the available space (if any left). The last column's width is given byMath.max(fixedWidth, tableWidth - ((nColumns - 1) * fixedWidth))
.- Returns:
- the width for the given column
-
getColumnPos
Given bycolumnsWidth * layoutIndex
.- Returns:
- the x position for the given column and its layout index in the viewport
-
layoutColumn
Lays out the given column. The layout index is necessary to identify the position of a column among the others (comes before/after). Positions the column atX: getColumnPos(index, column)
andY: 0
.Sizes the column to
W: getColumnWidth(column)
andH: columnsHeight
- Returns:
- always true
- See Also:
-
layoutCell
Lays out the given cell. The layout index is necessary to identify the position of a cell among the others (comes before/after). The width and x position values are the exact same used by theVFXTableHelper.AbstractHelper.lastColumn()
method. So bothgetColumnPos(int, VFXTableColumn)
andgetColumnWidth(VFXTableColumn)
are used to find the cell's x and w respectively. However, before doing so, we must convert the given layout index to the respective column index and then extract the column (since the aforementioned methods need the column as a parameter). The conversion is done by this simple formula:columnsRange.getMin() + layoutIdx
.The y position will be 0 and the height will be
rowsHeight
.- Returns:
- always true
- See Also:
-
autosizeColumn
This method is a no-op as the operation is not possible inColumnsLayoutMode.FIXED
. -
autosizeColumns
public void autosizeColumns()InColumnsLayoutMode.FIXED
this can be still used by setting theVFXTable.columnsSizeProperty()
rather than the width of each column.If the current state is
VFXTableState.INVALID
then exits immediately.If the last column in range (
VFXTableHelper.columnsRange()
), has its skin stillnull
, then we assume that every other column is in the same situation. In such case, we need to 'delay' the operation and wait for the skin to be created, so that we can compute the columns' width.The first pass is to get the widest column by iterating over them, computing the width with
VFXTableColumn.computePrefWidth(double)
and keeping the maximum value found.If the state is empty (no rows), the computation ends and the
VFXTable.columnsSizeProperty()
is set to:Math.max(fixedW, foundMax + extra)
, where 'fixedW' is the current width specified by the property itself.The second pass is to get the widest cell among the ones in the viewport by using
VFXTableRow.getWidthOf(VFXTableColumn, boolean)
. TheforceLayout
flag istrue
if this operation was 'delayed' before for the aforementioned reasons.Finally, the
VFXTable.columnsSizeProperty()
is set to:Math.max(Math.max(fixedW, maxColumnsW + extra), maxCellsW + extra)
, where 'fixedW' is the current width specified by the property itself.- See Also:
-
visibleCells
public int visibleCells()Description copied from interface:VFXTableHelper
Depends on the implementation!- Returns:
- the theoretical number of cells present in the viewport. It's given by
visibleRows * visibleColumns
, which means that it does not take into accountnull
cells or anything else
-
isInViewport
To check whether the given column is visible this uses its index and the current state's columns range to callIntegerRange.inRangeOf(int, IntegerRange)
.The index is retrieved with
VFXTable.indexOf(VFXTableColumn)
.- Returns:
- whether the given column is currently visible in the viewport
-
scrollToIndex
public void scrollToIndex(javafx.geometry.Orientation orientation, int index) Description copied from interface:VFXTableHelper
Scrolls in the viewport, depending on the given direction (orientation) to:- the item at the given index if it's
Orientation.VERTICAL
- the column at the given index if it's
Orientation.HORIZONTAL
-