{"id":13348901,"url":"https://github.com/fxmisc/Flowless","last_synced_at":"2025-03-12T08:31:36.781Z","repository":{"id":18339693,"uuid":"21519278","full_name":"FXMisc/Flowless","owner":"FXMisc","description":"Efficient VirtualFlow for JavaFX","archived":false,"fork":false,"pushed_at":"2024-05-14T14:13:33.000Z","size":334,"stargazers_count":181,"open_issues_count":14,"forks_count":38,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-06-15T04:41:14.081Z","etag":null,"topics":["javafx","viewport"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FXMisc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-07-05T12:10:28.000Z","updated_at":"2024-06-15T04:41:26.136Z","dependencies_parsed_at":"2024-01-13T07:25:49.299Z","dependency_job_id":"c2f3285c-5f98-4c14-a2df-6a8bce9593dc","html_url":"https://github.com/FXMisc/Flowless","commit_stats":null,"previous_names":["tomasmikula/flowless"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FXMisc%2FFlowless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FXMisc%2FFlowless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FXMisc%2FFlowless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FXMisc%2FFlowless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FXMisc","download_url":"https://codeload.github.com/FXMisc/Flowless/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221279991,"owners_count":16790563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javafx","viewport"],"created_at":"2024-07-29T20:02:03.223Z","updated_at":"2024-10-24T05:31:07.135Z","avatar_url":"https://github.com/FXMisc.png","language":"Java","funding_links":[],"categories":["Community"],"sub_categories":["Libraries"],"readme":"Flowless\n========\n\nPlease note that as from version **0.6.5** Flowless requires Java 9 or newer.\n\nEfficient VirtualFlow for JavaFX. VirtualFlow is a layout container that lays out _cells_ in a vertical or horizontal _flow_. The main feature of a _virtual_ flow is that only the currently visible cells are rendered in the scene. You may have a list of thousands of items, but only, say, 30 cells are rendered at any given time.\n\nJavaFX has its own VirtualFlow, which is not part of the public API, but is used, for example, in the implementation of [ListView](https://openjfx.io/javadoc/23/javafx.controls/javafx/scene/control/ListView.html). It is, however, [not very efficient](https://bugs.openjdk.java.net/browse/JDK-8091726) when updating the viewport on items changed or scroll.\n\nHere is a comparison of JavaFX's ListView vs. Flowless on a list of 80 items, 25 of which fit into the viewport.\n\n|                                              | Flowless (# of cell creations / # of cell layouts) | JDK 8u40 ListView (# of `updateItem` calls / # of cell layouts) | JDK 16 ListView with fixed cell size (# of `updateItem` calls / # of cell layouts) |\n|----------------------------------------------|:-----:|:-----:|:-----:|\n| update an item in the viewport               |   1/1 | 1/1   | 1/1   |\n| update an item outside the viewport          |   0/0 | 0/0   | 0/0   |\n| delete an item in the middle of the viewport |   1/1 | 38/25 | 13/13 |\n| add an item in the middle of the viewport    |   1/1 | 38/25 | 13/13 |\n| scroll 5 items down                          |   5/5 | 5/5   | 5/5   |\n| scroll 50 items down                         | 25/25 | 50/25 | 25/25 |\n\n\nHere is the [source code](https://gist.github.com/Jugen/2d392fd72ebec9db3c5d2aca1f8f5eb5) of this mini-benchmark.\n\nUse case for Flowless\n---------------------\n\nYou will benefit from Flowless (compared to ListView) the most if you have many add/delete items occuring in the viewport and an expensive [updateItem](https://openjfx.io/javadoc/23/javafx.controls/javafx/scene/control/Cell.html#updateItem(T,boolean)) method.\n\nNote, however, that Flowless is a low-level layout component and does not provide higher-level features like selection model or inline editing. One can, of course, implement those on top of Flowless.\n\nAdditional API\n--------------\n\nVirtualFlow in Flowless provides additional public API compared to ListView or VirtualFlow from JavaFX.\n\n**Direct cell access** with [getCell(itemIndex)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#getCell-int-) and [getCellIfVisible(itemIndex)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#getCellIfVisible-int-) methods. This is useful for measurement purposes.\n\n**List of currently visible cells** via [visibleCells()](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#visibleCells--).\n\n**Hit test** with the [hit(double x, double y)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#hit-double-double-) method that converts viewport coordinates into a cell index and coordinates relative to the cell, or indicates that the hit is before or beyond the cells.\n\n**Navigate to a subregion of a cell** using the [show(itemIndex, region)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#show-int-javafx.geometry.Bounds-) method. This is a finer grained navigation than just the [show(itemIndex)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#show-int-) method.\n\n**Scroll:** [scrollXBy(deltaX)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#scrollXBy-double-) and [scrollYBy(deltaY)](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/VirtualFlow.html#scrollYBy-double-) methods.\n\n**Gravity:** You can create VirtualFlow where cells stick to the bottom (vertical flow) or right (horizontal flow) when there are not enough items to fill the viewport.\n\nConceptual differences from ListView\n------------------------------------\n\n**Dumb cells.** This is the most important difference. For Flowless, cells are just [Node](https://openjfx.io/javadoc/23/javafx.graphics/javafx/scene/Node.html)s and don't encapsulate any logic regarding virtual flow. A cell does not even necessarily store the index of the item it is displaying. This allows VirtualFlow to have complete control over when the cells are created and/or updated.\n\n**Cell reuse is opt-in,** not forced. Cells are not reused by default. A new cell is created for each item. This simplifies cell implementation and does not impair performance if reusing a cell would be about as expensive as creating a new one (i.e. `updateItem` would be expensive).\n\n**No empty cells.** There are no _empty cells_ used to fill the viewport when there are too few items. A cell is either displaying an item, or is not displayed at all.\n\nAssumptions about cells\n-----------------------\n\nAs noted before, for the purposes of virtual flow in Flowless the cells are just `Node`s. You are not forced to inherit from `ListCell`. However, they are expected to behave according to the following rules:\n\n* Cells of a vertical virtual flow should properly implement methods\n  * `computeMinWidth(-1)`\n  * `computePrefWidth(-1)`\n  * `computePrefHeight(width)`\n* Cells of a horizontal virtual flow should properly implement methods\n  * `computeMinHeight(-1)`\n  * `computePrefHeight(-1)`\n  * `computePrefWidth(height)`\n\nInclude Flowless in your project\n--------------------------------\n\n#### Maven coordinates\n\n| Group ID            | Artifact ID | Version |\n| :---------:         | :---------: | :-----: |\n| org.fxmisc.flowless | flowless    | 0.7.3   |\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.fxmisc.flowless/flowless/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.fxmisc.flowless/flowless)\n\n#### Gradle example\n\n```groovy\ndependencies {\n    implementation group: 'org.fxmisc.flowless', name: 'flowless', version: '0.7.3'\n}\n```\n\n#### Sbt example\n\n```scala\nlibraryDependencies += \"org.fxmisc.flowless\" % \"flowless\" % \"0.7.3\"\n```\n\n#### Manual download\n\nDownload the [0.7.3 jar](https://github.com/FXMisc/Flowless/releases/tag/v0.7.3) and place it on your classpath.\n\nDocumentation\n-------------\n\n[Javadoc](https://fxmisc.github.io/flowless/javadoc/0.7.0/org/fxmisc/flowless/package-summary.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffxmisc%2FFlowless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffxmisc%2FFlowless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffxmisc%2FFlowless/lists"}