FXMisc / Flowless

Efficient VirtualFlow for JavaFX
BSD 2-Clause "Simplified" License
185 stars 38 forks source link

Whether the creation of a grid layout similar to a GridView is supported #121

Closed ZTMIDGO closed 1 week ago

ZTMIDGO commented 1 week ago

VirtualFlow.createHorizontal and VirtualFlow.createVertical seem to only create effects similar to ListView

Jugen commented 1 week ago

Could you please give more detail. Like what were your expectations versus what you got ? That is what isn't it doing that you thought it would do ?

ZTMIDGO commented 1 week ago

Similar to controlsfx gridview, but there are some issues with the gridview, so I tried to implement the grid layout with Flowless

I hope Flowless will be able to achieve this effect

{96608177-3D70-4730-BA68-65BE01A0135F}

Here's the code for GridView


import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;
import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;
import org.controlsfx.control.cell.ColorGridCell;

import java.util.ArrayList;
import java.util.Random;

public class Test extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        var list = FXCollections.observableArrayList(new ArrayList<Color>());
        GridView<Color> myGrid = new GridView<>(list);
        myGrid.setHorizontalCellSpacing(5);

        myGrid.setCellFactory(new Callback<GridView<Color>, GridCell<Color>>() {
            public GridCell<Color> call(GridView<Color> gridView) {
                ColorGridCell cell = new ColorGridCell();
                return cell;
            }
        });

        Random r = new Random(System.currentTimeMillis());
        for(int i = 0; i < 10000; i++) {
            list.add(new Color(r.nextDouble(), r.nextDouble(), r.nextDouble(), 1.0));
        }

        myGrid.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observableValue, Number number, Number t1) {
                myGrid.setCellWidth((t1.doubleValue() - 10) / 5);
            }
        });

        Scene scene = new Scene(myGrid, 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }
}

Here's the code for Flowless


import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import org.fxmisc.flowless.Cell;
import org.fxmisc.flowless.VirtualFlow;

import java.util.function.Function;

public class FlowlessGridExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        ObservableList<Color> flowItems = getItems();
        VirtualFlow<Color, ?> flow = VirtualFlow.createVertical(flowItems, new Function<Color, Cell<Color, Pane>>() {
            @Override
            public Cell<Color, Pane> apply(Color color) {
                Rectangle rect = new Rectangle(50, 50, color);
                Pane pane = new Pane(rect);
                pane.setPadding(new Insets(5));
                return Cell.wrapNode(pane);
            }
        });

        Scene scene = new Scene(flow, 300, 300);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Flowless Grid Example");
        primaryStage.show();
    }

    private ObservableList<Color> getItems() {
        ObservableList<Color> items = FXCollections.observableArrayList();
        for(int i = 0; i < 20; ++i) {
            items.addAll(Color.GREEN, Color.RED, Color.PINK);
        }
        return items;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Jugen commented 1 week ago

So as you've discovered Flowless doesn't do a grid layout out of the box, but I think with some work you could maybe get it to do so (not sure!).

If you have a look at VirtualFlow's constructor you'll see that it has an OrientationHelper parameter for which there are currently the HorizontalHelper and VerticalHelper implementations. So if you implemented a GridHelper version and added a static createGrid method to VirtualFlow, then maybe it 'll work.

Note that currently the 2nd parameter of the relocate method in your GridHelper will be 0, so if the grid is always a square then just use the 3rd parameter for both x and y. If the grid layout is NOT always square you'll also have to change all the places in CellPositioner that call relocate (and this is where things may not work anymore!?).

If you manage to get this right please consider submitting a PR.

ZTMIDGO commented 1 week ago

Thanks, I'll try it and see if it works