实体属性更改后网格不更新
在我的项目中,我有“事件”和“用户”。用户报名参加活动。无论如何,事件实体有一个“参与者”属性,它是一个 int 值,表示事件的总容量,每次用户注册事件时都会递减。每个事件还有一个名为“注册者”的 ArrayList 属性,该属性应该包含已注册该事件的所有当前用户实体。
我的问题是,当用户注册活动时,这个容量属性“参与者”根本没有像预期的那样减少,我怀疑这意味着 ArrayList“注册者”也不会随着注册的用户而更新。在使用用户注册事件后,我重新检查 EventManagementView,以查看容量是否从其初始设置值下降,但它从来没有下降。以下是直接用于此问题的所有代码:
事件实体的 Events.java 类:
package ymca.tracker.application.data.entity;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import ymca.tracker.application.data.AbstractEntity;
@Embeddable
@Entity
public class Events extends AbstractEntity{
private String name;
private java.time.LocalDate startDate;
private java.time.LocalDate endDate;
private java.time.LocalTime startTime;
private java.time.LocalTime endTime;
private String recurring;
// The capacity attribute I was referring to above
public int participants;
private String nonMemberPrice;
private String memberPrice;
private String location;
private String description;
// Registrants ArrayList that is supposed to hold all the User entities that sign up for an event
@ElementCollection
@OneToMany(fetch = FetchType.EAGER)
public List<User> registrants = new ArrayList<User>();
public Events() {
}
public Events(String name, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime,
String recurring, int participants, String nonMemberPrice, String memberPrice, String location,
String description, ArrayList<User> registrants) {
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.startTime = startTime;
this.endTime = endTime;
this.recurring = recurring;
this.participants = participants;
this.nonMemberPrice = nonMemberPrice;
this.memberPrice = memberPrice;
this.location = location;
this.description = description;
this.registrants = registrants;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.time.LocalDate getStartDate() {
return startDate;
}
public void setStartDate(java.time.LocalDate startDate) {
this.startDate = startDate;
}
public java.time.LocalDate getEndDate() {
return endDate;
}
public void setEndDate(java.time.LocalDate endDate) {
this.endDate = endDate;
}
public java.time.LocalTime getStartTime() {
return startTime;
}
public void setStartTime(java.time.LocalTime startTime) {
this.startTime = startTime;
}
public java.time.LocalTime getEndTime() {
return endTime;
}
public void setEndTime(java.time.LocalTime endTime) {
this.endTime = endTime;
}
public String getRecurring() {
return recurring;
}
public void setRecurring(String recurring) {
this.recurring = recurring;
}
public int getParticipants() {
return participants;
}
public void setParticipants(int participants) {
this.participants = participants;
}
// This method is called (only with value 1 for now) to decrease participants count
public void decreaseCapacity(int numToDecreaseBy) {
this.participants = this.participants - numToDecreaseBy;
}
public String getMemberPrice() {
return memberPrice;
}
public void setMemberPrice(String memberPrice) {
this.memberPrice = memberPrice;
}
public String getNonMemberPrice() {
return nonMemberPrice;
}
public void setNonMemberPrice(String nonMemberPrice) {
this.nonMemberPrice = nonMemberPrice;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<User> getRegistrants() {
return registrants;
}
public void setGuests(ArrayList<User> registrants) {
this.registrants = registrants;
}
// This method is called to add a User to the registrants ArrayList
public void addRegistrant(User user) {
this.registrants.add(user);
}
public void removeRegistrant(User user) {
this.registrants.remove(user);
}
}
用户实体的 User.java 类:
package ymca.tracker.application.data.entity;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import ymca.tracker.application.data.AbstractEntity;
@Embeddable
@Entity
public class User extends AbstractEntity {
private boolean familyAccount;
private String firstName;
private String lastName;
private String username;
private String password;
private String passwordSalt;
private String passwordHash;
private ymca.tracker.application.data.entity.Role role;
public User() {
}
public User(boolean familyAccount, String firstName, String lastName,
String username, String password, ymca.tracker.application.data.entity.Role role) {
this.familyAccount = familyAccount;
this.firstName = firstName;
this.lastName = lastName;
this.username = username;
this.role = role;
this.password = password;
this.passwordSalt = RandomStringUtils.random(32);
this.passwordHash = DigestUtils.sha1Hex(password + passwordSalt);
}
public boolean checkPassword(String password) {
return DigestUtils.sha1Hex(password + passwordSalt).equals(passwordHash);
}
public boolean getFamilyAccount() {
return familyAccount;
}
public void setFamilyAccount(boolean familyAccount) {
this.familyAccount = familyAccount;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public ymca.tracker.application.data.entity.Role getRole() {
return role;
}
public void setRole(ymca.tracker.application.data.entity.Role role) {
this.role = role;
}
}
我的员工/管理员帐户使用下面的这个 EventManagementView 来初始创建事件:
package ymca.tracker.application.views.eventmanagement;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.splitlayout.SplitLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import ymca.tracker.application.data.entity.Events;
import ymca.tracker.application.data.entity.User;
import ymca.tracker.application.data.service.EventsService;
@PageTitle("Event Management")
@Route(value = "event-management")
@Uses(Icon.class)
public class EventManagementView extends Div implements BeforeEnterObserver {
private final String EVENTS_ID = "eventsID";
private final String EVENTS_EDIT_ROUTE_TEMPLATE = "event-management/%s/edit";
private Grid<Events> grid = new Grid<>(Events.class, false);
private TextField name;
private DatePicker startDate;
private DatePicker endDate;
private TimePicker startTime;
private TimePicker endTime;
private TextField recurring;
private IntegerField participants;
private TextField nonMemberPrice;
private TextField memberPrice;
private TextField location;
private TextField description;
private Button delete = new Button("Delete");
private Button cancel = new Button("Cancel");
private Button save = new Button("Save");
private BeanValidationBinder<Events> binder;
private Events events;
private EventsService eventsService;
public EventManagementView(@Autowired EventsService eventsService) {
this.eventsService = eventsService;
addClassNames("event-management-view", "flex", "flex-col", "h-full");
// Create UI
SplitLayout splitLayout = new SplitLayout();
splitLayout.setSizeFull();
createGridLayout(splitLayout);
createEditorLayout(splitLayout);
add(splitLayout);
// Configure Grid
grid.addColumn("name").setAutoWidth(true);
grid.addColumn("startDate").setAutoWidth(true);
grid.addColumn("endDate").setAutoWidth(true);
grid.addColumn("startTime").setAutoWidth(true);
grid.addColumn("endTime").setAutoWidth(true);
grid.addColumn("recurring").setAutoWidth(true);
grid.addColumn("participants").setAutoWidth(true);
grid.addColumn("nonMemberPrice").setAutoWidth(true);
grid.addColumn("memberPrice").setAutoWidth(true);
grid.addColumn("location").setAutoWidth(true);
grid.addColumn("description").setAutoWidth(true);
grid.setItems(query -> eventsService.list(
PageRequest.of(query.getPage(), query.getPageSize(), VaadinSpringDataHelpers.toSpringDataSort(query)))
.stream());
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
grid.setHeightFull();
// when a row is selected or deselected, populate form
grid.asSingleSelect().addValueChangeListener(event -> {
if (event.getValue() != null) {
UI.getCurrent().navigate(String.format(EVENTS_EDIT_ROUTE_TEMPLATE, event.getValue().getId()));
} else {
clearForm();
UI.getCurrent().navigate(EventManagementView.class);
}
});
// Configure Form
binder = new BeanValidationBinder<>(Events.class);
// Bind fields. This is where you'd define e.g. validation rules
binder.bindInstanceFields(this);
delete.addClickListener(e -> {
binder.removeBean();
eventsService.delete(this.events.getId());
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event deleted");
UI.getCurrent().navigate(EventManagementView.class);
});
cancel.addClickListener(e -> {
clearForm();
refreshGrid();
});
save.addClickListener(e -> {
try {
if (this.events == null) {
this.events = new Events();
}
/*
Since the ArrayList isn't set by the grid editor, I hardcoded an
empty ArrayList to go with the new Event here
*/
ArrayList<User> registrants = new ArrayList<User>();
this.events.setGuests(registrants);
binder.writeBean(this.events);
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event details saved.");
UI.getCurrent().navigate(EventManagementView.class);
} catch (ValidationException validationException) {
Notification.show("An exception happened while trying to save the event details.");
}
});
}
@Override
public void beforeEnter(BeforeEnterEvent event) {
Optional<UUID> eventsId = event.getRouteParameters().get(EVENTS_ID).map(UUID::fromString);
if (eventsId.isPresent()) {
Optional<Events> eventsFromBackend = eventsService.get(eventsId.get());
if (eventsFromBackend.isPresent()) {
populateForm(eventsFromBackend.get());
} else {
Notification.show(
String.format("The requested event was not found, ID = %s", eventsId.get()), 3000,
Notification.Position.BOTTOM_START);
// when a row is selected but the data is no longer available,
// refresh grid
refreshGrid();
event.forwardTo(EventManagementView.class);
}
}
}
private void createEditorLayout(SplitLayout splitLayout) {
Div editorLayoutDiv = new Div();
editorLayoutDiv.setClassName("flex flex-col");
editorLayoutDiv.setWidth("400px");
Div editorDiv = new Div();
editorDiv.setClassName("p-l flex-grow");
editorLayoutDiv.add(editorDiv);
FormLayout formLayout = new FormLayout();
name = new TextField("Event Name");
startDate = new DatePicker("Start Date");
endDate = new DatePicker("End Date");
startTime = new TimePicker("Start Time");
startTime.setStep(Duration.ofMinutes(10));
endTime = new TimePicker("End Time");
endTime.setStep(Duration.ofMinutes(10));
recurring = new TextField("Recurring Event?");
participants = new IntegerField("Number of Participants");
nonMemberPrice = new TextField("Non-Member Price");
memberPrice = new TextField("Member Price");
location = new TextField("Location");
description = new TextField("Description");
Component[] fields = new Component[]{name, startDate, endDate, startTime, endTime, recurring, participants, nonMemberPrice, memberPrice, location, description};
for (Component field : fields) {
((HasStyle) field).addClassName("full-width");
}
formLayout.add(fields);
editorDiv.add(formLayout);
createButtonLayout(editorLayoutDiv);
splitLayout.addToSecondary(editorLayoutDiv);
}
private void createButtonLayout(Div editorLayoutDiv) {
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setClassName("w-full flex-wrap bg-contrast-5 py-s px-l");
buttonLayout.setSpacing(true);
cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
buttonLayout.add(save, cancel, delete);
editorLayoutDiv.add(buttonLayout);
}
private void createGridLayout(SplitLayout splitLayout) {
Div wrapper = new Div();
wrapper.setId("grid-wrapper");
wrapper.setWidthFull();
splitLayout.addToPrimary(wrapper);
wrapper.add(grid);
}
private void refreshGrid() {
grid.select(null);
grid.getLazyDataView().refreshAll();
}
private void clearForm() {
populateForm(null);
}
private void populateForm(Events value) {
this.events = value;
binder.readBean(this.events);
}
}
处理事件的代码部分注册一个用户(如果您希望查看此视图的整个类而不仅仅是此方法,请告诉我):
private VerticalLayout createSignUpFormLayout(Dialog signUpForm) {
signUpForm.getElement().setAttribute("aria-label", "Registration Form");
TextField firstName = new TextField("First Name");
TextField lastName = new TextField("Last Name");
H2 headline = new H2("Registration Form");
headline.getStyle().set("margin-top", "0");
Button cancel = new Button("Cancel", e -> signUpForm.close());
Button submit = new Button("Submit", e -> {
if(fillChecker(firstName.getValue(), lastName.getValue()) == true) {
String fn = firstName.getValue();
String ln = lastName.getValue();
User guest = new User(false, fn, ln,
"null", "null", Role.GUEST);
Set<Events> selected = grid.getSelectedItems();
Events[] curEvent = selected.toArray(new Events[1]);
Events selectedEvent = curEvent[0];
if(selectedEvent == null) {
Notification.show("No Event Selected!", 5000, Position.TOP_CENTER);
} else {
userRepository.save(guest); // Saves guest sign-up info to user repository
selectedEvent.addRegistrant(guest);; // Adds guest sign-up info to events guest list
selectedEvent.decreaseCapacity(1); // Decrease events participants count by 1
signUpForm.close();
Notification.show("Registered 1 Guest", 5000, Position.TOP_CENTER);
}
} else {
Notification.show("Please complete the form to register", 5000, Position.TOP_CENTER);
}
});
In my project, I have "Events" and "Users". Users sign up for events. Anyways the Events entity has a "participants" attribute which is an int that is the total capacity of the event, that is supposed to decrement every time a User signs up for the Event. Each Event also has an ArrayList attribute called "registrants" that is supposed to contain all the current User entities that have signed up for the Event.
My issue is that when a User signs up for an Event, this capacity attribute "participants" does not decrease at all like it is supposed to, which I suspect means the ArrayList "registrants" is also not be updated with the User that signs up. I re-check the EventManagementView after using a User to sign up for an event to see if the capacity is ever dropped from its initial set value, but it never is. Here's all the code that is directly used with this issue:
Events.java class for Events entity:
package ymca.tracker.application.data.entity;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import ymca.tracker.application.data.AbstractEntity;
@Embeddable
@Entity
public class Events extends AbstractEntity{
private String name;
private java.time.LocalDate startDate;
private java.time.LocalDate endDate;
private java.time.LocalTime startTime;
private java.time.LocalTime endTime;
private String recurring;
// The capacity attribute I was referring to above
public int participants;
private String nonMemberPrice;
private String memberPrice;
private String location;
private String description;
// Registrants ArrayList that is supposed to hold all the User entities that sign up for an event
@ElementCollection
@OneToMany(fetch = FetchType.EAGER)
public List<User> registrants = new ArrayList<User>();
public Events() {
}
public Events(String name, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime,
String recurring, int participants, String nonMemberPrice, String memberPrice, String location,
String description, ArrayList<User> registrants) {
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.startTime = startTime;
this.endTime = endTime;
this.recurring = recurring;
this.participants = participants;
this.nonMemberPrice = nonMemberPrice;
this.memberPrice = memberPrice;
this.location = location;
this.description = description;
this.registrants = registrants;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.time.LocalDate getStartDate() {
return startDate;
}
public void setStartDate(java.time.LocalDate startDate) {
this.startDate = startDate;
}
public java.time.LocalDate getEndDate() {
return endDate;
}
public void setEndDate(java.time.LocalDate endDate) {
this.endDate = endDate;
}
public java.time.LocalTime getStartTime() {
return startTime;
}
public void setStartTime(java.time.LocalTime startTime) {
this.startTime = startTime;
}
public java.time.LocalTime getEndTime() {
return endTime;
}
public void setEndTime(java.time.LocalTime endTime) {
this.endTime = endTime;
}
public String getRecurring() {
return recurring;
}
public void setRecurring(String recurring) {
this.recurring = recurring;
}
public int getParticipants() {
return participants;
}
public void setParticipants(int participants) {
this.participants = participants;
}
// This method is called (only with value 1 for now) to decrease participants count
public void decreaseCapacity(int numToDecreaseBy) {
this.participants = this.participants - numToDecreaseBy;
}
public String getMemberPrice() {
return memberPrice;
}
public void setMemberPrice(String memberPrice) {
this.memberPrice = memberPrice;
}
public String getNonMemberPrice() {
return nonMemberPrice;
}
public void setNonMemberPrice(String nonMemberPrice) {
this.nonMemberPrice = nonMemberPrice;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<User> getRegistrants() {
return registrants;
}
public void setGuests(ArrayList<User> registrants) {
this.registrants = registrants;
}
// This method is called to add a User to the registrants ArrayList
public void addRegistrant(User user) {
this.registrants.add(user);
}
public void removeRegistrant(User user) {
this.registrants.remove(user);
}
}
User.java class for User entity:
package ymca.tracker.application.data.entity;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import ymca.tracker.application.data.AbstractEntity;
@Embeddable
@Entity
public class User extends AbstractEntity {
private boolean familyAccount;
private String firstName;
private String lastName;
private String username;
private String password;
private String passwordSalt;
private String passwordHash;
private ymca.tracker.application.data.entity.Role role;
public User() {
}
public User(boolean familyAccount, String firstName, String lastName,
String username, String password, ymca.tracker.application.data.entity.Role role) {
this.familyAccount = familyAccount;
this.firstName = firstName;
this.lastName = lastName;
this.username = username;
this.role = role;
this.password = password;
this.passwordSalt = RandomStringUtils.random(32);
this.passwordHash = DigestUtils.sha1Hex(password + passwordSalt);
}
public boolean checkPassword(String password) {
return DigestUtils.sha1Hex(password + passwordSalt).equals(passwordHash);
}
public boolean getFamilyAccount() {
return familyAccount;
}
public void setFamilyAccount(boolean familyAccount) {
this.familyAccount = familyAccount;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public ymca.tracker.application.data.entity.Role getRole() {
return role;
}
public void setRole(ymca.tracker.application.data.entity.Role role) {
this.role = role;
}
}
My Staff/Admin account uses this EventManagementView below to initially create the event:
package ymca.tracker.application.views.eventmanagement;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.splitlayout.SplitLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import ymca.tracker.application.data.entity.Events;
import ymca.tracker.application.data.entity.User;
import ymca.tracker.application.data.service.EventsService;
@PageTitle("Event Management")
@Route(value = "event-management")
@Uses(Icon.class)
public class EventManagementView extends Div implements BeforeEnterObserver {
private final String EVENTS_ID = "eventsID";
private final String EVENTS_EDIT_ROUTE_TEMPLATE = "event-management/%s/edit";
private Grid<Events> grid = new Grid<>(Events.class, false);
private TextField name;
private DatePicker startDate;
private DatePicker endDate;
private TimePicker startTime;
private TimePicker endTime;
private TextField recurring;
private IntegerField participants;
private TextField nonMemberPrice;
private TextField memberPrice;
private TextField location;
private TextField description;
private Button delete = new Button("Delete");
private Button cancel = new Button("Cancel");
private Button save = new Button("Save");
private BeanValidationBinder<Events> binder;
private Events events;
private EventsService eventsService;
public EventManagementView(@Autowired EventsService eventsService) {
this.eventsService = eventsService;
addClassNames("event-management-view", "flex", "flex-col", "h-full");
// Create UI
SplitLayout splitLayout = new SplitLayout();
splitLayout.setSizeFull();
createGridLayout(splitLayout);
createEditorLayout(splitLayout);
add(splitLayout);
// Configure Grid
grid.addColumn("name").setAutoWidth(true);
grid.addColumn("startDate").setAutoWidth(true);
grid.addColumn("endDate").setAutoWidth(true);
grid.addColumn("startTime").setAutoWidth(true);
grid.addColumn("endTime").setAutoWidth(true);
grid.addColumn("recurring").setAutoWidth(true);
grid.addColumn("participants").setAutoWidth(true);
grid.addColumn("nonMemberPrice").setAutoWidth(true);
grid.addColumn("memberPrice").setAutoWidth(true);
grid.addColumn("location").setAutoWidth(true);
grid.addColumn("description").setAutoWidth(true);
grid.setItems(query -> eventsService.list(
PageRequest.of(query.getPage(), query.getPageSize(), VaadinSpringDataHelpers.toSpringDataSort(query)))
.stream());
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
grid.setHeightFull();
// when a row is selected or deselected, populate form
grid.asSingleSelect().addValueChangeListener(event -> {
if (event.getValue() != null) {
UI.getCurrent().navigate(String.format(EVENTS_EDIT_ROUTE_TEMPLATE, event.getValue().getId()));
} else {
clearForm();
UI.getCurrent().navigate(EventManagementView.class);
}
});
// Configure Form
binder = new BeanValidationBinder<>(Events.class);
// Bind fields. This is where you'd define e.g. validation rules
binder.bindInstanceFields(this);
delete.addClickListener(e -> {
binder.removeBean();
eventsService.delete(this.events.getId());
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event deleted");
UI.getCurrent().navigate(EventManagementView.class);
});
cancel.addClickListener(e -> {
clearForm();
refreshGrid();
});
save.addClickListener(e -> {
try {
if (this.events == null) {
this.events = new Events();
}
/*
Since the ArrayList isn't set by the grid editor, I hardcoded an
empty ArrayList to go with the new Event here
*/
ArrayList<User> registrants = new ArrayList<User>();
this.events.setGuests(registrants);
binder.writeBean(this.events);
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event details saved.");
UI.getCurrent().navigate(EventManagementView.class);
} catch (ValidationException validationException) {
Notification.show("An exception happened while trying to save the event details.");
}
});
}
@Override
public void beforeEnter(BeforeEnterEvent event) {
Optional<UUID> eventsId = event.getRouteParameters().get(EVENTS_ID).map(UUID::fromString);
if (eventsId.isPresent()) {
Optional<Events> eventsFromBackend = eventsService.get(eventsId.get());
if (eventsFromBackend.isPresent()) {
populateForm(eventsFromBackend.get());
} else {
Notification.show(
String.format("The requested event was not found, ID = %s", eventsId.get()), 3000,
Notification.Position.BOTTOM_START);
// when a row is selected but the data is no longer available,
// refresh grid
refreshGrid();
event.forwardTo(EventManagementView.class);
}
}
}
private void createEditorLayout(SplitLayout splitLayout) {
Div editorLayoutDiv = new Div();
editorLayoutDiv.setClassName("flex flex-col");
editorLayoutDiv.setWidth("400px");
Div editorDiv = new Div();
editorDiv.setClassName("p-l flex-grow");
editorLayoutDiv.add(editorDiv);
FormLayout formLayout = new FormLayout();
name = new TextField("Event Name");
startDate = new DatePicker("Start Date");
endDate = new DatePicker("End Date");
startTime = new TimePicker("Start Time");
startTime.setStep(Duration.ofMinutes(10));
endTime = new TimePicker("End Time");
endTime.setStep(Duration.ofMinutes(10));
recurring = new TextField("Recurring Event?");
participants = new IntegerField("Number of Participants");
nonMemberPrice = new TextField("Non-Member Price");
memberPrice = new TextField("Member Price");
location = new TextField("Location");
description = new TextField("Description");
Component[] fields = new Component[]{name, startDate, endDate, startTime, endTime, recurring, participants, nonMemberPrice, memberPrice, location, description};
for (Component field : fields) {
((HasStyle) field).addClassName("full-width");
}
formLayout.add(fields);
editorDiv.add(formLayout);
createButtonLayout(editorLayoutDiv);
splitLayout.addToSecondary(editorLayoutDiv);
}
private void createButtonLayout(Div editorLayoutDiv) {
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setClassName("w-full flex-wrap bg-contrast-5 py-s px-l");
buttonLayout.setSpacing(true);
cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
buttonLayout.add(save, cancel, delete);
editorLayoutDiv.add(buttonLayout);
}
private void createGridLayout(SplitLayout splitLayout) {
Div wrapper = new Div();
wrapper.setId("grid-wrapper");
wrapper.setWidthFull();
splitLayout.addToPrimary(wrapper);
wrapper.add(grid);
}
private void refreshGrid() {
grid.select(null);
grid.getLazyDataView().refreshAll();
}
private void clearForm() {
populateForm(null);
}
private void populateForm(Events value) {
this.events = value;
binder.readBean(this.events);
}
}
The portion of code that handles event sign up for a User (If you'd prefer to see the whole class for this view instead of just this method please let me know):
private VerticalLayout createSignUpFormLayout(Dialog signUpForm) {
signUpForm.getElement().setAttribute("aria-label", "Registration Form");
TextField firstName = new TextField("First Name");
TextField lastName = new TextField("Last Name");
H2 headline = new H2("Registration Form");
headline.getStyle().set("margin-top", "0");
Button cancel = new Button("Cancel", e -> signUpForm.close());
Button submit = new Button("Submit", e -> {
if(fillChecker(firstName.getValue(), lastName.getValue()) == true) {
String fn = firstName.getValue();
String ln = lastName.getValue();
User guest = new User(false, fn, ln,
"null", "null", Role.GUEST);
Set<Events> selected = grid.getSelectedItems();
Events[] curEvent = selected.toArray(new Events[1]);
Events selectedEvent = curEvent[0];
if(selectedEvent == null) {
Notification.show("No Event Selected!", 5000, Position.TOP_CENTER);
} else {
userRepository.save(guest); // Saves guest sign-up info to user repository
selectedEvent.addRegistrant(guest);; // Adds guest sign-up info to events guest list
selectedEvent.decreaseCapacity(1); // Decrease events participants count by 1
signUpForm.close();
Notification.show("Registered 1 Guest", 5000, Position.TOP_CENTER);
}
} else {
Notification.show("Please complete the form to register", 5000, Position.TOP_CENTER);
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论