Kumar Gaurav
Kumar Gaurav

Reputation: 1317

How to save entire object for a checkbox in javafx

I have number of objects. Let's say i have 10 Books object and i want user to select any number of the book. When user press the submit button i want to retrieve all the books "object" that user selected.

As of now, while showing screen to user i use

CheckBox cb= new CheckBox(book.getName());

this shows bookname to user and user selects the book. But on runtime i will be needing bookid and other properties of book object as well.

Is there anyway through which i can save the book object in the checkbox?

Upvotes: 0

Views: 1308

Answers (3)

Gaurang
Gaurang

Reputation: 87

This is just a simplified version of the accepted answer. We can use setUserData(Object) to set data and getUserData() to retrieve the previously set data of any JavaFX node (including CheckBox). Reference: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#setUserData-java.lang.Object-

Upvotes: 0

James_D
James_D

Reputation: 209418

Consider using a control with built-in selection functionality, such as a ListView. Then you can just check the selection model.

import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class BookSelection extends Application {

    @Override
    public void start(Stage primaryStage) {

        ListView<Book> bookList = new ListView<>();
        bookList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        bookList.setCellFactory(lv -> new ListCell<Book>() {
            @Override
            public void updateItem(Book book, boolean empty) {
                super.updateItem(book, empty);
                if (empty) {
                    setText(null);
                } else {
                    setText(book.getTitle());
                }
            }
        });

        IntStream.rangeClosed(1, 10).mapToObj(i -> new Book("Book "+i)).forEach(bookList.getItems()::add);

        Button submit = new Button("Submit selection");
        submit.setOnAction(e -> 
                bookList.getSelectionModel().getSelectedItems().forEach(book -> System.out.println(book.getTitle())));

        BorderPane root = new BorderPane(bookList, null, null, submit, null);
        BorderPane.setAlignment(submit, Pos.CENTER);
        BorderPane.setMargin(submit, new Insets(10));

        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Book {
        private final StringProperty title = new SimpleStringProperty() ;
        public Book(String title) {
            setTitle(title);
        }
        public final StringProperty titleProperty() {
            return this.title;
        }
        public final java.lang.String getTitle() {
            return this.titleProperty().get();
        }
        public final void setTitle(final java.lang.String title) {
            this.titleProperty().set(title);
        }


    }

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

If for some reason you really want to implement this with check boxes, you can keep a Set<Book> representing the selected books, and update it when each check box is selected/unselected. Note this is similar to @user99370's answer, but is more robust as it avoids downcasting the (essentially unknown-type) userData to your data type.

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class BookSelection extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane grid = new GridPane();
        grid.setHgap(5);
        grid.setVgap(5);
        grid.setPadding(new Insets(10 ));
        List<Book> books = IntStream.rangeClosed(1, 10).mapToObj(i -> new Book("Book "+i)).collect(Collectors.toList());

        Set<Book> selectedBooks = new HashSet<>();

        int row = 0 ;
        for (Book book : books) {
            CheckBox checkBox = new CheckBox();
            checkBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
                if (isNowSelected) {
                    selectedBooks.add(book);
                } else {
                    selectedBooks.remove(book);
                }
            });
            grid.addRow(row, checkBox, new Label(book.getTitle()));
            row++ ;
        }

        Button submit = new Button("Submit selection");
        submit.setOnAction(e -> 
                selectedBooks.forEach(book -> System.out.println(book.getTitle())));

        GridPane.setHalignment(submit, HPos.CENTER);
        grid.add(submit, 0, row, 2, 1);

        Scene scene = new Scene(grid, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Book {
        private final StringProperty title = new SimpleStringProperty() ;
        public Book(String title) {
            setTitle(title);
        }
        public final StringProperty titleProperty() {
            return this.title;
        }
        public final java.lang.String getTitle() {
            return this.titleProperty().get();
        }
        public final void setTitle(final java.lang.String title) {
            this.titleProperty().set(title);
        }


    }

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

Upvotes: 0

Gaali Prabhakar
Gaali Prabhakar

Reputation: 583

Basic Examle. if you want more sepecifc you need to post your code, we can set object to node using setUserDate, then we can use that object when we need. here i am using object id for example, in yor case save that object i hope this will solve your problem ,?s post a comment

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class UserData extends Application {

public void start(Stage primaryStage) {
    VBox root = new VBox();
    Book book = new Book(22, "firstBok");
    Book book1 = new Book(2, "secondBok");
    CheckBox checkB = new CheckBox(book.getName());
    checkB.setUserData(book);
    CheckBox checkB1 = new CheckBox(book1.getName());
    checkB1.setUserData(book1);
    Button btn = new Button("Submit");
    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            if (checkB.isSelected()) {
                int firstCheckBxId = ((Book) checkB.getUserData()).getId();
                System.out.println("id:" + firstCheckBxId);
            }
            if (checkB1.isSelected()) {
                int secondCheckBxId = ((Book) checkB1.getUserData()).getId();
                System.out.println("id:" + secondCheckBxId);
            }

        }
    });
    root.getChildren().addAll(checkB, checkB1, btn);
    primaryStage.setScene(new Scene(root));
    primaryStage.show();
}

class Book {
    int id;
    private String name;

    Book(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return this.id;
    }

    public String getName() {
        return name;
    }

}

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

}

Upvotes: 3

Related Questions