Skip to content

Commit

Permalink
Errai (content complete)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbogoevici authored and pmuir committed May 28, 2012
1 parent e1cec4d commit 908ad4a
Showing 1 changed file with 154 additions and 38 deletions.
192 changes: 154 additions & 38 deletions tutorial/DashboardGWT.asciidoc
Expand Up @@ -243,43 +243,11 @@ public class BookingMonitor {

As soon as Errai has completed its initialization process, the `createAndShowUI` method is invoked (`@AfterInitialization` takes care of that). In this case the method will fetch initial data from the server using Errai RPC and construct the user interface. To carry out the remote procedure call, we use an injected `Caller` for the remote interface `BookingMonitorService` which is part of the `org.jboss.jdf.example.ticketmonster.monitor.client.shared` package and whose implementation `BookingMonitorServiceImpl` has been explained in the previous chapter.

In order for the booking status to be updated in real-time, the class must be notified when a change has occured. If you have built the service layer already, you may remember that the JAX-RS `BookingService` class will fire CDI events whenver a booking has been created or cancelled. Now we need to listen to those events.
In order for the booking status to be updated in real-time, the class must be notified when a change has occured. If you have built the service layer already, you may remember that the JAX-RS `BookingService` class will fire CDI events whenever a booking has been created or cancelled. Now we need to listen to those events.

.src/main/java/org/jboss/jdf/example/ticketmonster/monitor/client/local/BookingMonitor.java
[source, java]
---------------------------------------------------------------------------------------------------------
package org.jboss.jdf.example.ticketmonster.monitor.client.local;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.jboss.errai.bus.client.api.RemoteCallback;
import org.jboss.errai.ioc.client.api.AfterInitialization;
import org.jboss.errai.ioc.client.api.Caller;
import org.jboss.errai.ioc.client.api.EntryPoint;
import org.jboss.jdf.example.ticketmonster.monitor.client.shared.BookingMonitorService;
import org.jboss.jdf.example.ticketmonster.monitor.client.shared.qualifier.Cancelled;
import org.jboss.jdf.example.ticketmonster.monitor.client.shared.qualifier.Created;
import org.jboss.jdf.example.ticketmonster.model.Booking;
import org.jboss.jdf.example.ticketmonster.model.Performance;
import org.jboss.jdf.example.ticketmonster.model.Show;
import com.google.gwt.user.client.ui.RootPanel;
/**
* The entry point into the TicketMonster booking monitor.
*
* The {@code @EntryPoint} annotation indicates to the Errai framework that
* this class should be instantiated inside the web browser when the web page
* is first loaded.
*
* @author Christian Sadilek <csadilek@redhat.com>
*/
@EntryPoint
public class BookingMonitor {
/**
Expand Down Expand Up @@ -329,10 +297,158 @@ public class BookingMonitor {
The newly created methods `onNewBooking` and `onCancelledBooking`are _event listeners_. They are identified as such by the `@Observes` annotation applied to their parameters. By using the `@Created` and `@Cancelled` qualifiers that we have defined in our application, we narrow down the range of events that they listen.



The widgets
~~~~~~~~~~~

The last step involves
Next, we will define the widget classes that are responsible for rendering the user interface. First, we will create the widget class for an individual performance.

.src/main/java/org/jboss/jdf/example/ticketmonster/monitor/client/local/PerformanceStatusWidget.java
[source,java]
---------------------------------------------------------------------------------------------------------
package org.jboss.jdf.example.ticketmonster.monitor.client.local;
import org.jboss.jdf.example.ticketmonster.model.Performance;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
/**
* A UI component to display the status of a {@link Performance}.
*
* @author Christian Sadilek <csadilek@redhat.com>
*/
public class PerformanceStatusWidget extends Composite {
private Label bookingStatusLabel = new Label();
private HorizontalPanel progressBar = new HorizontalPanel();
private Label soldPercentLabel;
private Label availablePercentLabel;
private Performance performance;
private long soldTickets;
private int capacity;
public PerformanceStatusWidget(Performance performance) {
this.performance = performance;
soldTickets = BookingMonitor.getOccupiedCountForPerformance(performance);
capacity = performance.getShow().getVenue().getCapacity();
setBookingStatus();
setProgress();
HorizontalPanel performancePanel = new HorizontalPanel();
String date = DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_SHORT).format(performance.getDate());
performancePanel.add(new Label(date));
performancePanel.add(progressBar);
performancePanel.add(bookingStatusLabel);
performancePanel.setStyleName("performance-status");
initWidget(performancePanel);
}
/**
* Updates the booking status (progress bar and corresponding text) of the {@link Performance}
* associated with this widget based on the number of sold tickets cached in {@link BookingMonitor}.
*/
public void updateBookingStatus() {
this.soldTickets = BookingMonitor.getOccupiedCountForPerformance(performance);
setBookingStatus();
setProgress();
}
private void setBookingStatus() {
bookingStatusLabel.setText(soldTickets + " of " + capacity + " tickets booked");
}
private void setProgress() {
int soldPercent = Math.round((soldTickets / (float) capacity) * 100);
if (soldPercentLabel != null) {
progressBar.remove(soldPercentLabel);
}
if (availablePercentLabel != null) {
progressBar.remove(availablePercentLabel);
}
soldPercentLabel = new Label();
soldPercentLabel.setStyleName("performance-status-progress-sold");
soldPercentLabel.setWidth(soldPercent + "px");
availablePercentLabel = new Label();
availablePercentLabel.setStyleName("performance-status-progress-available");
availablePercentLabel.setWidth((100 - soldPercent) + "px");
progressBar.add(soldPercentLabel);
progressBar.add(availablePercentLabel);
}
}
---------------------------------------------------------------------------------------------------------

A show has multiple performances, so we will create a `ShowStatusWidget` to contains a `PerformanceStatusWidget` for each performance.

.src/main/java/org/jboss/jdf/example/ticketmonster/monitor/client/local/ShowStatusWidget.java
[source,java]
---------------------------------------------------------------------------------------------------------
package org.jboss.jdf.example.ticketmonster.monitor.client.local;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.jboss.jdf.example.ticketmonster.model.Performance;
import org.jboss.jdf.example.ticketmonster.model.Show;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* A UI component to display the status of a {@link Show}.
*
* @author Christian Sadilek <csadilek@redhat.com>
*/
public class ShowStatusWidget extends Composite {
private Map<Long, PerformanceStatusWidget> performances = new HashMap<Long, PerformanceStatusWidget>();
public ShowStatusWidget(Show show) {
VerticalPanel widgetPanel = new VerticalPanel();
widgetPanel.setStyleName("show-status");
Label showStatusHeader = new Label(show.getEvent().getName() + " @ " + show.getVenue());
showStatusHeader.setStyleName("show-status-header");
widgetPanel.add(showStatusHeader);
// Add a performance status widget for each performance of the show
for (Performance performance : show.getPerformances()) {
if (performance.getDate().getTime() > new Date().getTime()) {
PerformanceStatusWidget psw = new PerformanceStatusWidget(performance);
performances.put(performance.getId(), psw);
widgetPanel.add(psw);
}
}
initWidget(widgetPanel);
}
/**
* Triggers an update of the {@link PerformanceStatusWidget} associated with
* the provided {@link Performance}.
*
* @param performance
*/
public void updatePerformance(Performance performance) {
PerformanceStatusWidget pw = performances.get(performance.getId());
if (pw != null) {
pw.updateBookingStatus();
}
}
}
---------------------------------------------------------------------------------------------------------

The user interface is constructed using two classes: `ShowStatusWidget` and `PerformanceStatusWidget`. A show has multiple performances, so an instance of `ShowStatusWidget` contains a `PerformanceStatusWidget` for each performance. The `PerformanceStatusWidget` will be updated every time a booking event is received on the client.
This class is has two responsibilities. First, it will to display together all the performances that belong to a given show. Also, it will update its `PerformanceStatusWidget` children whenever a booking event is received on the client (through the observer method defined above).

0 comments on commit 908ad4a

Please sign in to comment.