palexdev / MaterialFX

A library of material components for JavaFX
GNU Lesser General Public License v3.0
1.2k stars 122 forks source link

Virtualized Masonry Pane #203

Closed DaRealTurtyWurty closed 2 years ago

DaRealTurtyWurty commented 2 years ago

Is your feature request related to a problem? Please describe. So I'm trying to create a sort of gallery application where a bunch of images can be viewed. However, I have been unable to find any sort of JavaFX library that provides a Masonry Pane.

Describe the solution you'd like I would like to see a Masonry Pane. I also say "Virtualized" because, as I will explain later, the current alternative is not and therefore causes insane amounts of lag when rendering just a few images.

Describe alternatives you've considered The only other decent alternative I could find is the one from JFoenix. However that library appears to be unmaintained and and the issue with theirs is that it is not virtualized and so causes lots of issues when there are many items in the pane. Image of the JFoenix Masonry Pane is below: 687474703a2f2f6a666f656e69782e636f6d2f6769662f6d61736f6e72792e676966

Another alternative that I have looked at is TilesFX, however that is not really a masonry pane and I have found it quite hard to work with.

Additional context I think that something like this would be very helpful to many people since displaying images on masonry panes is very common, yet not currently possible without building a whole new node and set of tools to do it (which at least personally, I have no idea how to do). If this could be added that would be fantastic and I would much appreciate it!

M-K-Al commented 2 years ago

As of JavaFX 2.0, FlowPane does the mentioned functionality. However, the implementation does not provided any animation. Luckily, It has been found that this can be achieved easily. To animate the FlowPane, we will use LayoutAnimator, you may want to add the class to your project.

This's an example:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import org.jetbrains.annotations.NotNull;

public class TestFlowPane extends Application {

    @Override
    public void start(@NotNull final Stage stage) throws Exception {
        final FlowPane flowPane = new FlowPane();

        for (int i = 0; i < 100; i++) {
            final Button button = new Button("Hello, World%d!".formatted(i));
            button.setMinSize(100 + Math.random() * 200, 40);
            FlowPane.setMargin(button, new Insets(2));
            flowPane.getChildren().add(button);
        }

        new LayoutAnimator().observe(flowPane.getChildren());

        final Scene scene = new Scene(flowPane, 400, 400);
        scene.getStylesheets().add("stylesheet.css");
        stage.setScene(scene);
        stage.show();
    }

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

You may change the duration of the animation by changing LayoutAnimator.MoveTransition.MOVEMENT_ANIMATION_DURATION.

For the performance, you tell me ;). On my machine up to 3000 buttons still gives good performance, yet it depends on your objects. note that LayoutAnimator barely reduces the performance. I'm not really fully aware of the implementation of the FlowPane, but, surely, it could have been much more efficient dealing with large amount of items.

Hope this helps!

palexdev commented 2 years ago

@DaRealTurtyWurty I rarely see mansory layout these days

Even gallery apps nowadays tend to use grids So, no, I'm not interested in porting a mansory layout, also virtualizing it would be very hard But... I want to implement a virtualized grid some day as part of VirtualizedFX. I don't know when though, it will need a lot of time and work

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

Closed for inactivity.