我下面的代码从我按下 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!");
}
}
}
}
您应该对您的域(书店)进行建模,然后编写代码来使用建模的域。
你需要一些东西来代表一本书:
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();
}
}
然后你会得到这样的结果: