如何在表格的每一行添加买书按钮并在区域中打印书籍?

问题描述 投票:0回答:1

我下面的代码从我按下 buyButton 的行打印这本书。但我想改变这一点。每次我按下购买按钮时,我都需要这本书出现在“您的购物车:”区域中,但我却陷入了困境。我不知道如何为 Controller 类中的 buyButton 创建处理程序。 这是我的视图类:

public CustomerView(Stage primaryStage) {
        primaryStage.setTitle("Book Store");

        GridPane gridPane = new GridPane();
        initializeGridPane(gridPane);

        Scene scene = new Scene(gridPane, 720, 480);
        primaryStage.setScene(scene);

        initializeSceneTitle(gridPane);

        initializeTableView(gridPane);

        initializeFields(gridPane);

        primaryStage.show();
    }

    private void initializeGridPane(GridPane gridPane) {
        gridPane.setAlignment(Pos.CENTER);
        gridPane.setHgap(10);
        gridPane.setVgap(10);
        gridPane.setPadding(new Insets(40, 40, 40, 40));
    }

    private void initializeSceneTitle(GridPane gridPane) {
        Text sceneTitle = new Text("Our book colection");
        sceneTitle.setFont(Font.font("Tahome", FontWeight.NORMAL, 20));
        gridPane.add(sceneTitle, 0, 0, 1, 3);
    }

    private void initializeTableView(GridPane gridPane) {
        table = new TableView<>();

        idColumn = new TableColumn<>("ID");
        titleColumn = new TableColumn<>("Title");
        authorColumn = new TableColumn<>("Author");
        pubDateColumn = new TableColumn<>("Published Date");
        priceColumn = new TableColumn<>("Price");
        stockColumn = new TableColumn<>("Stock");
        buyColumn = new TableColumn<>("Buy");

        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
        authorColumn.setCellValueFactory(new PropertyValueFactory<>("author"));
        pubDateColumn.setCellValueFactory(new PropertyValueFactory<>("publishedDate"));
        priceColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
        stockColumn.setCellValueFactory(new PropertyValueFactory<>("stock"));

        //final Button buyButton = new Button("Buy");

        //bibliografie pentru codul de mai jos
        //https://stackoverflow.com/questions/29489366/how-to-add-button-in-javafx-table-view
        Callback<TableColumn<Book, Button>, TableCell<Book, Button>> cellFactory
                = //
                new Callback<TableColumn<Book, Button>, TableCell<Book, Button>>() {
                    @Override
                    public TableCell call(final TableColumn<Book, Button> param) {
                        final TableCell<Book, Button> cell = new TableCell<Book, Button>() {

                            final Button buyButton = new Button("Buy");

                            @Override
                            protected void updateItem(Button item, boolean empty) {
                                super.updateItem(item, empty);
                                if (empty) {
                                    setGraphic(null);
                                } else {
                                    buyButton.setOnAction(event -> {
                                        Book book = getTableView().getItems().get(getIndex());
                                        System.out.println(book.getAuthor()
                                                + "   " + book.getTitle());
                                        //buyBookHandler.handle(event);
                                    });
                                    setGraphic(buyButton);
                                }

                            }
                        };
                        return cell;
                    }
                };

        buyColumn.setCellFactory(cellFactory);

        table.getColumns().add(idColumn);
        table.getColumns().add(titleColumn);
        table.getColumns().add(authorColumn);
        table.getColumns().add(pubDateColumn);
        table.getColumns().add(priceColumn);
        table.getColumns().add(stockColumn);
        table.getColumns().add(buyColumn);
        gridPane.add(table,2, 4, 25,25);//1:0

        VBox tableViewBox = new VBox(10);
        tableViewBox.getChildren().add(table);

        showAllBooksButton = new Button("See out book colection");

        HBox viewAllBooksHBox = new HBox(10);
        viewAllBooksHBox.setAlignment(Pos.BOTTOM_LEFT);
        viewAllBooksHBox.getChildren().add(showAllBooksButton);
        gridPane.add(viewAllBooksHBox, 5, 1);

        //HBox buyButtonHBox = new HBox(10);
        //buyButtonHBox.setAlignment(Pos.BOTTOM_LEFT);

        //gridPane.add(buyButtonHBox, 0,20,2,1);
        gridPane.add(tableViewBox, 0, 5, 10, 20);

    }

    private void initializeFields(GridPane gridPane) {
        cartArea = new TextArea();
        cartArea.setEditable(false);
        cartArea.setText("Your cart: \n");

        HBox buttonsHBox = new HBox(5);
        buttonsHBox.setAlignment(Pos.BOTTOM_CENTER);
        buttonsHBox.getChildren().addAll(cartArea);
        gridPane.add(buttonsHBox, 0, 27, 2, 5);

        totalPriceLabel = new Label("Total price: ");
        gridPane.add(totalPriceLabel, 0, 32, 5, 1);
    }

    public void setBooksData(List<Book> books) {
        booksList = FXCollections.observableArrayList(books);
        table.setItems(booksList);
    }

    public void showAllBooks(EventHandler<ActionEvent> show){
        showAllBooksButton.setOnAction(show);
    }

    public void setCartArea(String msj){
        cartArea.appendText(msj);
    }

    public void setPriceTotal(int price){
        totalPriceLabel.setText(totalPriceLabel.getText() + price);
    }

这在我的控制器类中:

public class CustomerController {
    private final CustomerView customerView;
    private final BookService bookService;
    List<Book> booksInCart = new ArrayList<>();

    public CustomerController(CustomerView customerView, BookService bookService) {
        this.customerView = customerView;
        this.bookService = bookService;

        //this.customerView.setBuyButtonHandler(new BuyBook());
        this.customerView.showAllBooks(new ViewAllBooks());
    }

    private class ViewAllBooks implements EventHandler<ActionEvent> {
        private List<Book> books;
        @Override
        public void handle(ActionEvent event) {
            books = bookService.findAll();
            customerView.setBooksData(books);
        }
    }

    private class BuyBook implements EventHandler<ActionEvent> {
        private String title;
        private int stock;
        private Book selectedBook;
        private int price = 0;
        @Override
        public void handle(ActionEvent event) {
            selectedBook = customerView.getSelectedBook();
            //booksInCart.add(selectedBook);
            title = selectedBook.getTitle();
            stock = selectedBook.getStock();

            if(stock > 0){
                selectedBook.setStock(stock - 1);
                customerView.setCartArea(title);

                price += selectedBook.getPrice();
                customerView.setPriceTotal(price);
            }
            else {
                customerView.setCartArea("Sold out!");
            }
        }
    }

}

java button javafx
1个回答
0
投票

您应该对您的域(书店)进行建模,然后编写代码来使用建模的域。

你需要一些东西来代表一本书:

record Book(String title, String author) {}

还有代表购物车的东西:

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.Optional;

class Cart {
    private final ObservableList<CartItem> items = FXCollections.observableArrayList();

    public ObservableList<CartItem> getItems() {
        return items;
    }

    public void addBook(Book book) {
        Optional<CartItem> cartItem =
                items.stream()
                        .filter(item -> item.getBook().equals(book))
                        .findFirst();

        if (cartItem.isPresent()) {
            cartItem.get().setQuantity(
                    cartItem.get().getQuantity() + 1
            );
        } else {
            items.add(new CartItem(book, 1));
        }
    }

    public void clear() {
        items.clear();
    }
}

以及代表购物车中的订单项的东西:

import javafx.beans.property.SimpleIntegerProperty;

class CartItem {
    private final Book book;
    private final SimpleIntegerProperty quantity;

    public CartItem(Book book, int quantity) {
        this.book = book;
        this.quantity = new SimpleIntegerProperty(quantity);
    }

    public Book getBook() {
        return book;
    }

    public int getQuantity() {
        return quantity.get();
    }

    public SimpleIntegerProperty quantityProperty() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity.set(quantity);
    }
}

以及代表商店中所有可用书籍和当前购物车的东西。

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

class BookStoreModel {
    private final ObservableList<Book> books = FXCollections.observableArrayList();
    private final Cart cart = new Cart();

    public BookStoreModel() {
        books.addAll(
                new Book("The Seven Lamps of Architecture", "John Ruskin"),
                new Book("Collapse: How Societies Choose to Fail or Succeed", "Jared Diamond")
        );
    }

    public ObservableList<Book> getBooks() {
        return books;
    }

    public Cart getCart() {
        return cart;
    }
}

那么你需要一个 UI:

import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;

class BookStoreUI {
    public TableView<Book> createAvailableBooksView(
            ObservableList<Book> books, Cart cart
    ) {
        TableView<Book> availableBooks = new TableView<>(books);

        TableColumn<Book, String> titleColumn = new TableColumn<>("Title");
        titleColumn.setCellValueFactory(p ->
                new SimpleStringProperty(p.getValue().title())
        );
        titleColumn.setPrefWidth(250);

        TableColumn<Book, String> authorColumn = new TableColumn<>("Author");
        authorColumn.setCellValueFactory(p ->
                new SimpleStringProperty(p.getValue().author())
        );

        TableColumn<Book, Void> buyColumn = new TableColumn<>("Buy");
        buyColumn.setMaxWidth(70);
        buyColumn.setCellFactory(p ->
                new BuyCell(cart)
        );

        //noinspection unchecked
        availableBooks.getColumns().addAll(titleColumn, authorColumn, buyColumn);

        availableBooks.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_ALL_COLUMNS);

        return availableBooks;
    }

    public TableView<CartItem> createPurchasesView(Cart cart) {
        TableView<CartItem> purchases = new TableView<>(cart.getItems());
        TableColumn<CartItem, String> purchasedTitleColumn = new TableColumn<>("Title");
        purchasedTitleColumn.setCellValueFactory(p ->
                new SimpleStringProperty(p.getValue().getBook().title())
        );
        purchasedTitleColumn.setPrefWidth(250);

        TableColumn<CartItem, Integer> quantityColumn = new TableColumn<>("Quantity");
        quantityColumn.setMaxWidth(70);
        quantityColumn.setCellValueFactory(p ->
                p.getValue().quantityProperty().asObject()
        );

        //noinspection unchecked
        purchases.getColumns().addAll(purchasedTitleColumn, quantityColumn);

        purchases.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_ALL_COLUMNS);

        return purchases;
    }

    public Parent createCartControl(Cart cart) {
        Button clear = new Button("Clear");
        clear.setOnAction(e -> cart.clear());
        clear.disableProperty().bind(Bindings.isEmpty(cart.getItems()));

        return clear;
    }
}

还有“购买”按钮的小部件。

import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.layout.StackPane;

class BuyCell extends TableCell<Book, Void> {
    private final Button buy = new Button("Buy");
    private final StackPane container = new StackPane(buy);

    public BuyCell(Cart cart) {
        container.setPadding(new Insets(5));
        buy.setOnAction(e ->
                cart.addBook(getTableRow().getItem())
        );
    }

    @Override
    protected void updateItem(Void item, boolean empty) {
        super.updateItem(item, empty);

        setGraphic(empty ? null : container);
    }
}

还有一个将它们结合在一起的应用程序。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BookStoreApp extends Application {
    private final BookStoreModel model = new BookStoreModel();

    @Override
    public void start(Stage stage) {
        BookStoreUI ui = new BookStoreUI();

        VBox layout = new VBox(
                10,
                new Label("Available Books"),
                ui.createAvailableBooksView(model.getBooks(), model.getCart()),
                new Label("Shopping Cart"),
                ui.createPurchasesView(model.getCart()),
                ui.createCartControl(model.getCart())
        );
        layout.setPadding(new Insets(10));
        layout.setPrefSize(500, 400);

        stage.setScene(new Scene(layout));
        stage.show();
    }
}

然后你会得到这样的结果:

© www.soinside.com 2019 - 2024. All rights reserved.