Rahul.B
Rahul.B

Reputation: 374

Using controlsfx GridView containing list of GridPane

I am learning JavaFx and building a sample app that would display a list of restaurant menu items in a scroll-able way. I figured out the best way to do this is using GridView control from controlsfx because even with the large set of menu items the scroll would work fast. Here is a sample code that I am trying to make it work:

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            VBox root = new VBox();
            Scene scene = new Scene(root,400,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);

            ObservableList<GridPane> list = FXCollections.<GridPane>observableArrayList();
            GridView<GridPane> gridView = new GridView<>(list);

            gridView.setCellFactory(new Callback<GridView<GridPane>, GridCell<GridPane>>() {
                 public GridCell<GridPane> call(GridView<GridPane> gridView) {
                     return new GridCell<GridPane>();
                 }
             });

            Label lblName1 = new Label("Name");
            GridPane grid = new GridPane();
            grid.addRow(0, lblName1);

            Label lblName2 = new Label("Price");
            grid.addRow(1, lblName2);

            list.add(grid);

            root.getChildren().add(gridView);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

When I run the code above it only shows the VBox with no item. I have tried to replicate the sample code given on controlsfx website on using GridView (http://controlsfx.bitbucket.org/org/controlsfx/control/GridView.html).

Any help/tip would be much appreciated. Thanks.

Upvotes: 4

Views: 4460

Answers (1)

Rahul.B
Rahul.B

Reputation: 374

Figured out the problem and here is the correct code. I needed to write the custom GridPane (for dsplaying menu items) and the cell factory for generating the custom object.

//Main Class
package application;

import java.util.Random;

import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;
import org.controlsfx.control.cell.ColorGridCell;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.util.Callback;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            VBox root = new VBox();
            Scene scene = new Scene(root,400,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);

            GridView<MenuItem> menuItems = new GridView<>();

            for(int i = 0; i < 10000; i++) {
                menuItems.getItems().addAll(new MenuItem(i));
            }

            menuItems.setCellFactory(new MenuItemCellFactory());

            root.getChildren().add(menuItems);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

/**
 * Custom Menu Item
 */
package application;

import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;

/**
 * @author Rahul
 *
 */
public class MenuItem extends GridPane {
    private Integer name = null;

    public MenuItem(int i) {
        // TODO Auto-generated constructor stub
        this.name = i;
    }

    public Integer getName() {
        return name;
    }

    public void setName(Integer name) {
        this.name = name;
    }
}


//Menu Item Cell Factory
package application;

import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;

import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.util.Callback;

public class MenuItemCellFactory implements Callback<GridView<MenuItem>, GridCell<MenuItem>> {

    @Override
    public GridCell<MenuItem> call(GridView<MenuItem> listview) {
        return new MenuItemCell();
    }
}


//Menu Item Cell
package application;

import org.controlsfx.control.GridCell;

import javafx.scene.control.ListCell;
import javafx.scene.layout.GridPane;

public class MenuItemCell extends GridCell<MenuItem> {

    @Override
    protected void updateItem(MenuItem item, boolean empty) {
        // TODO Auto-generated method stub
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            setText(item.getName().toString());
            setStyle("-fx-background-color: #ffffff; -fx-background-radius: 15; -fx-border-radius: 15; -fx-border-width: 0; -fx-padding: 10; -fx-pref-width: 145; -fx-max-width: 145; -fx-max-width: 145; -fx-pref-height: 130; -fx-max-height: 130; -fx-effect: dropshadow(three-pass-box, #93948d, 10, 0, 0, 0);");
        }
    }
}

This is a sample code to use GridView containing list of GridPane using cellfactory. Please modify it as per your requirement. The basic would remain the same.

Suggestions and feedback are most welcome. Thanks.

Upvotes: 7

Related Questions