Artificial intelligence in the post-deep learning era
Creating an Uber Clone - Part XX - Transcript.pdf
1. Creating an Uber Clone - Part XX
We’ll continue the search UI implementation as we step into the CompletionContainer class
2. public class CompletionContainer {
private Container result;
private boolean completionUsed;
private final EventDispatcher dispatcher = new EventDispatcher();
void updateCompletion(String text, AutoCompleteAddressInput dest) {
SearchService.suggestLocations(text,
LocationService.getCurrentLocation(), resultList -> {
if(resultList != null && resultList.size() > 0) {
result.removeAll();
completionUsed = true;
for(SearchService.SuggestionResult r : resultList) {
MultiButton mb = createEntry(FontImage.MATERIAL_PLACE,
r.getMainText(), r.getSecondaryText());
result.add(mb);
mb.addActionListener(e -> {
dest.setTextNoEvent(r.getFullText());
r.getLocation(l -> {
dest.setCurrentLocation(l);
dispatcher.fireActionEvent(e);
});
});
}
CompletionContainer
The CompletionContainer tries to coordinate the two instances of the AutoCompleteAddressInput class by providing a single class that handles the completion UI. Most
of the code in this class should be very familiar as some of it is refactored code from the MapForm while other code relates to the suggestLocations API we implemented
earlier...
The name of the class is misleading. CompletionContainer is not a Container. Here instead of deriving I encapsulated the UI logic and tried to expose only the business
logic
3. public class CompletionContainer {
private Container result;
private boolean completionUsed;
private final EventDispatcher dispatcher = new EventDispatcher();
void updateCompletion(String text, AutoCompleteAddressInput dest) {
SearchService.suggestLocations(text,
LocationService.getCurrentLocation(), resultList -> {
if(resultList != null && resultList.size() > 0) {
result.removeAll();
completionUsed = true;
for(SearchService.SuggestionResult r : resultList) {
MultiButton mb = createEntry(FontImage.MATERIAL_PLACE,
r.getMainText(), r.getSecondaryText());
result.add(mb);
mb.addActionListener(e -> {
dest.setTextNoEvent(r.getFullText());
r.getLocation(l -> {
dest.setCurrentLocation(l);
dispatcher.fireActionEvent(e);
});
});
}
CompletionContainer
Event dispatchers allow us to broadcast events using the add/removeListener observer style API. We use this dispatcher to broadcast an event when a user presses a
completion button
4. public class CompletionContainer {
private Container result;
private boolean completionUsed;
private final EventDispatcher dispatcher = new EventDispatcher();
void updateCompletion(String text, AutoCompleteAddressInput dest) {
SearchService.suggestLocations(text,
LocationService.getCurrentLocation(), resultList -> {
if(resultList != null && resultList.size() > 0) {
result.removeAll();
completionUsed = true;
for(SearchService.SuggestionResult r : resultList) {
MultiButton mb = createEntry(FontImage.MATERIAL_PLACE,
r.getMainText(), r.getSecondaryText());
result.add(mb);
mb.addActionListener(e -> {
dest.setTextNoEvent(r.getFullText());
r.getLocation(l -> {
dest.setCurrentLocation(l);
dispatcher.fireActionEvent(e);
});
});
}
CompletionContainer
This method is invoked when completion is in progress it invokes the WebService call to request completion suggestions for the given string
5. public class CompletionContainer {
private Container result;
private boolean completionUsed;
private final EventDispatcher dispatcher = new EventDispatcher();
void updateCompletion(String text, AutoCompleteAddressInput dest) {
SearchService.suggestLocations(text,
LocationService.getCurrentLocation(), resultList -> {
if(resultList != null && resultList.size() > 0) {
result.removeAll();
completionUsed = true;
for(SearchService.SuggestionResult r : resultList) {
MultiButton mb = createEntry(FontImage.MATERIAL_PLACE,
r.getMainText(), r.getSecondaryText());
result.add(mb);
mb.addActionListener(e -> {
dest.setTextNoEvent(r.getFullText());
r.getLocation(l -> {
dest.setCurrentLocation(l);
dispatcher.fireActionEvent(e);
});
});
}
CompletionContainer
We fill up the container with buttons if one of the buttons is pressed we fetch the location from the webservice and fill it into the AutoCompleteAddressInput. We then fire
the event dispatcher to process the actual selection in the UI
6. result.animateLayout(150);
}
});
}
private MultiButton createEntry(char icon, String title) {
MultiButton b = new MultiButton(title);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLine1");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
private MultiButton createEntry(char icon, String title, String subtitle) {
MultiButton b = new MultiButton(title);
b.setTextLine2(subtitle);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLineNoBorder");
b.setUIIDLine2("WhereToButtonLine2");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
CompletionContainer
We have two types of entries here, one with only one line of text and one with two lines of text. This is mostly in place to fit the UIID's correctly with the right underline
behavior
7. b.setUIIDLine2("WhereToButtonLine2");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
public void initCompletionBar() {
if(!completionUsed) {
return;
}
completionUsed = false;
result.removeAll();
initCompletionBarImpl();
}
private void initCompletionBarImpl() {
MultiButton addHome = createEntry(FontImage.MATERIAL_HOME,
"Add Home");
MultiButton addWork = createEntry(FontImage.MATERIAL_WORK,
"Add Work");
MultiButton savedPlaces = createEntry(
FontImage.MATERIAL_NAVIGATE_NEXT, "Saved Places");
savedPlaces.setUIIDLine1("WhereToButtonLineNoBorder");
savedPlaces.setEmblemUIID("WhereToButtonLineNoBorder");
savedPlaces.setEmblem(FontImage.createMaterial(
CompletionContainer
This method is invoked externally to clear up the content of the completion UI and show the "clean" set of initial options
9. private void addHistoryToCompletionBar() {
MultiButton history1 = createEntry(FontImage.MATERIAL_HISTORY,
"Mikve Yisrael Str...");
result.add(history1);
}
public void showCompletionBar(Container parentLayer) {
result = new Container(BoxLayout.y());
initCompletionBarImpl();
result.setUIID("Form");
result.setScrollableY(true);
result.setScrollVisible(false);
Container enclose = BorderLayout.center(result);
enclose.setY(getDisplayHeight());
enclose.setWidth(getDisplayWidth());
enclose.setHeight(result.getPreferredH());
parentLayer.add(CENTER, enclose);
parentLayer.animateLayout(200);
}
public void addCompletionListener(ActionListener<ActionEvent> a) {
dispatcher.addListener(a);
CompletionContainer
This method constructs and animates the completion UI into place. Notice that we place the content in a Container which we wrap up in a BorderLayout this allows us to
manipulate the preferred size without breaking the scrolling behavior of the child Container