Class TableHelper.VariableTableHelper
- All Implemented Interfaces:
TableHelper
- Direct Known Subclasses:
PaginatedHelper.VariablePaginatedTableHelper
- Enclosing interface:
TableHelper
TableHelper.FixedTableHelper
made to work specifically
with ColumnsLayoutMode.VARIABLE
.
Many of the methods of the other mode can be reused for this, just a few need their behavior to be redefined.
As you can guess, this is not the most efficient. All columns are laid out in the viewport which directly translates to "there are more cells in the viewport". You can also consider this mode as "partially virtualized", rows will still be virtualized but since columns widths are variable we have no way to easily and consistently virtualize them too.
The advantage of this mode is of course having columns that can be resized programmatically or by a gesture at runtime.
-
Property Summary
Properties inherited from class io.github.palexdev.virtualizedfx.table.TableHelper.AbstractHelper
estimatedSize, layoutInitialized
-
Nested Class Summary
Nested classes/interfaces inherited from interface io.github.palexdev.virtualizedfx.table.TableHelper
TableHelper.AbstractHelper, TableHelper.FixedTableHelper, TableHelper.VariableTableHelper
-
Field Summary
Fields inherited from class io.github.palexdev.virtualizedfx.table.TableHelper.FixedTableHelper
positions
Fields inherited from class io.github.palexdev.virtualizedfx.table.TableHelper.AbstractHelper
estimatedSize, heightListener, layoutInitialized, manager, positionListener, table, widthListener, xPosBinding, yPosBinding
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
autosizeColumn
(TableColumn<?, ? extends TableCell<?>> column) Attempts at auto-sizing the given column to fit its content.void
CallsautosizeColumn(TableColumn)
on all the columns in the table.io.github.palexdev.mfxcore.base.beans.range.IntegerRange
computePositions
(TableState<?> state, boolean forceXComputation, boolean forceYComputation) Given a certain state, computes the positions of each column/row/cell as a map.int
int
void
layout()
Entirely responsible for laying out columns/rows/cells.int
void
scrollToColumn
(int index) Scrolls the viewport to the given column index.This binding holds the horizontal position of the viewport.Methods inherited from class io.github.palexdev.virtualizedfx.table.TableHelper.FixedTableHelper
computeEstimatedSize, dispose, firstRow, lastRow, maxHScroll, maxRows, maxVScroll, rowsRange, scrollBy, scrollTo, scrollToRow, yPosBinding
Methods inherited from class io.github.palexdev.virtualizedfx.table.TableHelper.AbstractHelper
estimatedSizeProperty, getViewportHeight, horizontalOffset, invalidatedPos, isLayoutInitialized, layoutInitializedProperty, onHeightChanged, onPositionChanged, onWidthChanged, verticalOffset
-
Constructor Details
-
VariableTableHelper
-
-
Method Details
-
firstColumn
public int firstColumn()- Specified by:
firstColumn
in interfaceTableHelper
- Overrides:
firstColumn
in classTableHelper.FixedTableHelper
- Returns:
- 0 or -1 if the columns list is empty
-
lastColumn
public int lastColumn()- Specified by:
lastColumn
in interfaceTableHelper
- Overrides:
lastColumn
in classTableHelper.FixedTableHelper
- Returns:
- the columns list size -1
-
maxColumns
public int maxColumns()- Specified by:
maxColumns
in interfaceTableHelper
- Overrides:
maxColumns
in classTableHelper.FixedTableHelper
- Returns:
- the size of the columns list
-
columnsRange
public io.github.palexdev.mfxcore.base.beans.range.IntegerRange columnsRange()Description copied from class:TableHelper.FixedTableHelper
Note that the result given by
Will return a range of (-1, -1) if the table has no columns.TableHelper.FixedTableHelper.maxColumns()
to compute the index of the first column, is clamped so that it will never be greater then the number of columns in the table.- Specified by:
columnsRange
in interfaceTableHelper
- Overrides:
columnsRange
in classTableHelper.FixedTableHelper
- Returns:
- an
IntegerRange
made from the values offirstColumn()
andlastColumn()
. Will return a range of (-1, -1) if the table has no columns
-
xPosBinding
This binding holds the horizontal position of the viewport. This is the direction along the estimated breath.This is not virtualized as columns have variable widths and the value is simply given by
-table.getHPos()
.- Specified by:
xPosBinding
in interfaceTableHelper
- Overrides:
xPosBinding
in classTableHelper.FixedTableHelper
-
scrollToColumn
public void scrollToColumn(int index) Scrolls the viewport to the given column index. This is actually more complicated for this layout mode as we can't always get the position at which a column will be in the viewport. In fact, if the table has not been laid out yet, meaning that its skin is null, or if the interested column has not been laid out yet there's no way to know where it is in the viewport.For this reason this distinguish between two cases:
1) Everything has been laid out at least once: the column position is given by
column.getRegion().getBoundsInParent().getMinX()
2) We cannot rely on the aforementioned method, we resort on the "super" method. Since
VirtualTable
specifies the minimum width every column must have at the initialization we can easily predict were it will be at the start.- Specified by:
scrollToColumn
in interfaceTableHelper
- Overrides:
scrollToColumn
in classTableHelper.FixedTableHelper
-
autosizeColumn
Attempts at auto-sizing the given column to fit its content. To accomplish this we need the current state of the table,VirtualTable.stateProperty()
, and the index of the given column,VirtualTable.getColumnIndex(TableColumn)
. (if the state is completely empty,TableState.isEmptyAll()
, exits immediately).We get the rows from the state and then use
The last column is handled differently though. First we compute the total width of all the columns before. If this is lesser than the table width than the column will be resized to make it occupy all the available space. If this is not the case, then we fall back to the normal handling.TableRow.getWidthOf(int)
to get the preferred width of the cell at index (same index of column). From these results we get the maximum value and this will be the new width of the column.- Specified by:
autosizeColumn
in interfaceTableHelper
- Overrides:
autosizeColumn
in classTableHelper.FixedTableHelper
-
autosizeColumns
public void autosizeColumns()CallsautosizeColumn(TableColumn)
on all the columns in the table.- Specified by:
autosizeColumns
in interfaceTableHelper
- Overrides:
autosizeColumns
in classTableHelper.FixedTableHelper
-
computePositions
public Map<Orientation,List<Double>> computePositions(TableState<?> state, boolean forceXComputation, boolean forceYComputation) Given a certain state, computes the positions of each column/row/cell as a map. The key is anOrientation
value to differentiate between the vertical and horizontal positions. Most of the time this computation is not needed and the old positions can be reused, but if for whatever reason the computation is believed to be necessary then it's possible to force it by setting the desired parameter flags as true. X Positions ComputationThe horizontal positions are computed by iterating over all the columns and getting their width as the maximum between its current width and the minimum width specified by
VirtualTable.columnSizeProperty()
. The positions are actually computed with a simple accumulator.Horizontal positions are not computed unless at least one of these conditions is true:
- forceXComputation flag is true
- the positions have not been computed before
Y Positions ComputationThe vertical positions are computed by using a
DoubleStream.iterate(double, DoubleUnaryOperator)
withrowsNum * cellHeight
as the seed andx -> x - cellHeight
as the operator. The stream is also limited,DoubleStream.limit(long)
, to the number of rows we need, the results are stored in a list and put in the positions map withOrientation.VERTICAL
as the key.Vertical positions are not computed unless at least one of these conditions is true:
- forceYComputation flag is true
- the positions have not been computed before
- the number of positions previously computed is not equal to the number of rows we need
- Specified by:
computePositions
in interfaceTableHelper
- Overrides:
computePositions
in classTableHelper.FixedTableHelper
- Parameters:
forceXComputation
- forces the computation of the HORIZONTAL positions even if not neededforceYComputation
- forces the computation of the VERTICAL positions even if not needed
-
layout
public void layout()Entirely responsible for laying out columns/rows/cells. The layout makes use of the current table' state,VirtualTable.stateProperty()
, and the positions computed bycomputePositions(TableState, boolean, boolean)
, this is invoked without forcing the re-computation.Exits immediately if the state is completely empty,
Before proceeding with layout retrieves the following parameters:TableState.isEmptyAll()
, ifTableHelper.AbstractHelper.invalidatedPos()
returns true, or ifVirtualTable.needsViewportLayoutProperty()
is false.- the columns height
- the columns range
- the X positions
- the cells height
- the Y positions
- the Y offset with
Columns are laid out from left to right, relocated at the extracted X position and at Y 0; and resized to the previously gathered height. The width is computed byTableHelper.AbstractHelper.verticalOffset()
LayoutUtils.boundWidth(Node)
to honor the min, pref, and max values. The last column is an exception because if not all the space of the table was occupied by laying out the previous columns than its width will be set to the entire remaining space. Rows are laid out from top to bottom, relocated at X 0 and at the extracted Y position (+ the Y offset); and resized with the previously gathered height. The width is given by the currentVirtualTable.estimatedSizeProperty()
so that rows always have the same width of the column's container. For each row in the loop it also lays out their cells. Each cell is relocated at the extracted X position and at Y 0; and resized to the previously gathered cell height. The width is the same of the corresponding column. Note that the rows layout process won't even start if the current state is half-empty,TableState.empty()
.- Specified by:
layout
in interfaceTableHelper
- Overrides:
layout
in classTableHelper.FixedTableHelper
-