SlideShare a Scribd company logo
Adapting to Tablets & Desktops - Part III
In this module we dig into the TabletUI class
public void start() {
if(current != null){
current.show();
return;
}
AppSettings app = AppStorage.getInstance().fetchAppSettings();
if(app.logo.get() == null) {
app.setLogo(theme.getImage("icon.png"));
app.setTitleBackground(theme.getImage("title-image.jpg"));
}
if(Display.getInstance().isTablet()) {
Toolbar.setPermanentSideMenu(true);
new TabletUI(app);
}
BaseNavigationForm.showDishForm(app);
Display.getInstance().callSerially(() -> {
Display.getInstance().registerPush(new Hashtable(), true);
});
}
RestaurantAppBuilder
The tablet UI is created by the main class of the application, we initialize it here so when base navigation form uses the generic code it would already be initialized. We
also initialize the permanent side menu which makes the side menu stay open all the time without the button. That’s a UI paradigm that makes sense on tablets and
desktops.
public class TabletUI extends Form {
private static TabletUI instance;
public TabletUI(AppSettings app) {
super(new BorderLayout());
instance = this;
Toolbar tb = getToolbar();
Style titleStyle = tb.getUnselectedStyle();
titleStyle.setBorder(Border.createEmpty());
titleStyle.setBgImage(app.getTitleBackground());
titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS);
titleStyle.setPadding(4, 4, 4, 4);
TextField title = new TextField(Restaurant.getInstance().name.get());
title.setUIID("NavigationTitle");
title.addActionListener(a -> {
Restaurant.getInstance().name.set(title.getText());
new Builder().updateRestaurantSettings(app);
});
TextField tagline = new TextField(Restaurant.getInstance().tagline.get());
tagline.setUIID("Tagline");
TabletUI
The tablet UI class is a form that encapsulates the full layout on a tablet

It’s a singleton because we have just one form in the application and one UI
public class TabletUI extends Form {
private static TabletUI instance;
public TabletUI(AppSettings app) {
super(new BorderLayout());
instance = this;
Toolbar tb = getToolbar();
Style titleStyle = tb.getUnselectedStyle();
titleStyle.setBorder(Border.createEmpty());
titleStyle.setBgImage(app.getTitleBackground());
titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS);
titleStyle.setPadding(4, 4, 4, 4);
TextField title = new TextField(Restaurant.getInstance().name.get());
title.setUIID("NavigationTitle");
title.addActionListener(a -> {
Restaurant.getInstance().name.set(title.getText());
new Builder().updateRestaurantSettings(app);
});
TextField tagline = new TextField(Restaurant.getInstance().tagline.get());
tagline.setUIID("Tagline");
TabletUI
We use a border layout and place the content of the UI in the center so we can replace it when navigating between UIAbstraction instances
public class TabletUI extends Form {
private static TabletUI instance;
public TabletUI(AppSettings app) {
super(new BorderLayout());
instance = this;
Toolbar tb = getToolbar();
Style titleStyle = tb.getUnselectedStyle();
titleStyle.setBorder(Border.createEmpty());
titleStyle.setBgImage(app.getTitleBackground());
titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS);
titleStyle.setPadding(4, 4, 4, 4);
TextField title = new TextField(Restaurant.getInstance().name.get());
title.setUIID("NavigationTitle");
title.addActionListener(a -> {
Restaurant.getInstance().name.set(title.getText());
new Builder().updateRestaurantSettings(app);
});
TextField tagline = new TextField(Restaurant.getInstance().tagline.get());
tagline.setUIID("Tagline");
TabletUI
The title and subtitle are editable here too, this is effectively a copy of the code from base navigation form adapted for the tablet form factor
tagline.addActionListener(a -> {
Restaurant.getInstance().tagline.set(tagline.getText());
new Builder().updateRestaurantSettings(app);
});
tb.setTitleComponent(BoxLayout.encloseY(title, tagline));
Button logoImage = new Button("", app.getRoundedScaledLogo(), "TabletLogoImage");
logoImage.addActionListener(e -> {
new ImagePickerForm(512, 512, "Icon", app.getLogo(),
newImage -> {
app.setLogo(newImage);
logoImage.setIcon(app.getRoundedScaledLogo());
}).show();
});
tb.addComponentToSideMenu(logoImage);
ButtonGroup bg = new ButtonGroup();
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Dish List",
FontImage.MATERIAL_RESTAURANT_MENU, true,
e -> BaseNavigationForm.showDishForm(app)));
TabletUI
This is also a copy from base navigation form, but thanks to the available space we don’t need to jump thru hoops to make this look good or fit. So the code here is
much simpler
tagline.addActionListener(a -> {
Restaurant.getInstance().tagline.set(tagline.getText());
new Builder().updateRestaurantSettings(app);
});
tb.setTitleComponent(BoxLayout.encloseY(title, tagline));
Button logoImage = new Button("", app.getRoundedScaledLogo(), "TabletLogoImage");
logoImage.addActionListener(e -> {
new ImagePickerForm(512, 512, "Icon", app.getLogo(),
newImage -> {
app.setLogo(newImage);
logoImage.setIcon(app.getRoundedScaledLogo());
}).show();
});
tb.addComponentToSideMenu(logoImage);
ButtonGroup bg = new ButtonGroup();
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Dish List",
FontImage.MATERIAL_RESTAURANT_MENU, true,
e -> BaseNavigationForm.showDishForm(app)));
TabletUI
The logo image is now just an icon on the side menu which makes it look far better overall
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Details",
FontImage.MATERIAL_DESCRIPTION,
e -> BaseNavigationForm.showDetailsForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Billing",
FontImage.MATERIAL_CREDIT_CARD,
e -> BaseNavigationForm.showBillingForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Build the App",
FontImage.MATERIAL_PHONE_IPHONE,
e -> BaseNavigationForm.showAppForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "About Us",
FontImage.MATERIAL_INFO,
e -> BaseNavigationForm.showAboutForm(app)));
tb.addCommandToRightBar("Edit Background", null, e -> {
new ImagePickerForm(750, 295, "Background Image", app.getTitleBackground(),
newImage -> {
app.setTitleBackground(newImage);
titleStyle.setBgImage(newImage);
}).show();
});
}
TabletUI
You’ll notice that all the side menu entries are marked here but I’ll only highlight one as they are all mostly the same. Since we don’t derive from the base navigation form
this code is a bit duplicate but it’s much simpler as we don’t need the whole hack with marking the selection.

Notice we aren’t adding commands but rather adding components using the generic createSideNavigationEntry method. We’ll discuss that method soon but notice the
bg argument we pass to each one of them. That’s a button group and these methods return a radio button this allows us to have the selection effect
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Details",
FontImage.MATERIAL_DESCRIPTION,
e -> BaseNavigationForm.showDetailsForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Billing",
FontImage.MATERIAL_CREDIT_CARD,
e -> BaseNavigationForm.showBillingForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Build the App",
FontImage.MATERIAL_PHONE_IPHONE,
e -> BaseNavigationForm.showAppForm(app)));
tb.addComponentToSideMenu(createSideNavigationEntry(bg, "About Us",
FontImage.MATERIAL_INFO,
e -> BaseNavigationForm.showAboutForm(app)));
tb.addCommandToRightBar("Edit Background", null, e -> {
new ImagePickerForm(750, 295, "Background Image", app.getTitleBackground(),
newImage -> {
app.setTitleBackground(newImage);
titleStyle.setBgImage(newImage);
}).show();
});
}
TabletUI
We also add the edit background image button to the side, it’s relatively trivial as there isn’t that much we need to do here.
private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon,
ActionListener<ActionEvent> ac) {
return createSideNavigationEntry(bg, title, icon, false, ac);
}
private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon,
boolean selected, ActionListener<ActionEvent> ac) {
RadioButton a = RadioButton.createToggle(title, bg);
a.setSelected(selected);
a.setUIID("SideCommand");
FontImage.setMaterialIcon(a, icon, 4);
a.addActionListener(ac);
return a;
}
void showContainer(Container cnt, boolean direction) {
if(getContentPane().getComponentCount() == 0) {
add(BorderLayout.CENTER, cnt);
show();
} else {
getContentPane().replace(getContentPane().getComponentAt(0), cnt,
CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL,
direction, 150));
}
}
TabletUI
createSideNavigationEntry just generalizes the code that creates a radio button toggle button. It mostly saves some boilerplate and doesn’t feature much logic
private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon,
ActionListener<ActionEvent> ac) {
return createSideNavigationEntry(bg, title, icon, false, ac);
}
private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon,
boolean selected, ActionListener<ActionEvent> ac) {
RadioButton a = RadioButton.createToggle(title, bg);
a.setSelected(selected);
a.setUIID("SideCommand");
FontImage.setMaterialIcon(a, icon, 4);
a.addActionListener(ac);
return a;
}
void showContainer(Container cnt, boolean direction) {
if(getContentPane().getComponentCount() == 0) {
add(BorderLayout.CENTER, cnt);
show();
} else {
getContentPane().replace(getContentPane().getComponentAt(0), cnt,
CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL,
direction, 150));
}
}
TabletUI
However, showContainer is pretty interesting. It’s the method that’s effectively invoked when show() or showBack() are invoked.

There are two modes here. For the very first screen we need to use add. From that point on we’ll always use replace to show the next UIAbstraction instance.

More Related Content

PDF
Adapting to Tablets and Desktops - Part 3.pdf
PDF
Initial UI Mockup - Part 2 - Transcript.pdf
PDF
Initial UI Mockup - Part 2.pdf
PDF
Initial UI Mockup - Part 3 - Transcript.pdf
PDF
Initial UI Mockup - Part 3.pdf
PDF
Creating a Facebook Clone - Part VI - Transcript.pdf
PDF
Miscellaneous Features - Part 1.pdf
PDF
Miscellaneous Features - Part 1 - Transcript.pdf
Adapting to Tablets and Desktops - Part 3.pdf
Initial UI Mockup - Part 2 - Transcript.pdf
Initial UI Mockup - Part 2.pdf
Initial UI Mockup - Part 3 - Transcript.pdf
Initial UI Mockup - Part 3.pdf
Creating a Facebook Clone - Part VI - Transcript.pdf
Miscellaneous Features - Part 1.pdf
Miscellaneous Features - Part 1 - Transcript.pdf

Similar to Adapting to Tablets and Desktops - Part 3 - Transcript.pdf (20)

PDF
Adapting to Tablets and Desktops - Part 1 - Transcript.pdf
PDF
Adapting to Tablets and Desktops - Part 1.pdf
PPTX
Academy PRO: React native - building first scenes
PDF
Extracting ui Design - part 5 - transcript.pdf
PDF
SQLite and ORM Binding - Part 2 - Transcript.pdf
PDF
Creating an Uber Clone - Part XXXIX.pdf
PDF
Miscellaneous Features - Part 3 - Transcript.pdf
PDF
Creating a Facebook Clone - Part XXIX - Transcript.pdf
PDF
Creating an Uber Clone - Part XXXIV - Transcript.pdf
PDF
Extracting ui Design - part 6 - transcript.pdf
PDF
JSLab. Алексей Волков. "React на практике"
PDF
Creating a Facebook Clone - Part VII.pdf
PDF
Creating a Facebook Clone - Part XXVIII.pdf
PDF
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
PDF
Team pdf ionic
PPTX
Advancing the UI — Part 1: Look, Motion, and Gestures
PDF
Creating an Uber Clone - Part XXXX - Transcript.pdf
PDF
mobl: Een DSL voor mobiele applicatieontwikkeling
PDF
Extracting ui Design - part 4 - transcript.pdf
PDF
Different types of sticker apps
Adapting to Tablets and Desktops - Part 1 - Transcript.pdf
Adapting to Tablets and Desktops - Part 1.pdf
Academy PRO: React native - building first scenes
Extracting ui Design - part 5 - transcript.pdf
SQLite and ORM Binding - Part 2 - Transcript.pdf
Creating an Uber Clone - Part XXXIX.pdf
Miscellaneous Features - Part 3 - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating an Uber Clone - Part XXXIV - Transcript.pdf
Extracting ui Design - part 6 - transcript.pdf
JSLab. Алексей Волков. "React на практике"
Creating a Facebook Clone - Part VII.pdf
Creating a Facebook Clone - Part XXVIII.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Team pdf ionic
Advancing the UI — Part 1: Look, Motion, and Gestures
Creating an Uber Clone - Part XXXX - Transcript.pdf
mobl: Een DSL voor mobiele applicatieontwikkeling
Extracting ui Design - part 4 - transcript.pdf
Different types of sticker apps
Ad

More from ShaiAlmog1 (20)

PDF
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
PDF
create-netflix-clone-06-client-ui.pdf
PDF
create-netflix-clone-01-introduction_transcript.pdf
PDF
create-netflix-clone-02-server_transcript.pdf
PDF
create-netflix-clone-04-server-continued_transcript.pdf
PDF
create-netflix-clone-01-introduction.pdf
PDF
create-netflix-clone-06-client-ui_transcript.pdf
PDF
create-netflix-clone-03-server.pdf
PDF
create-netflix-clone-04-server-continued.pdf
PDF
create-netflix-clone-05-client-model_transcript.pdf
PDF
create-netflix-clone-03-server_transcript.pdf
PDF
create-netflix-clone-02-server.pdf
PDF
create-netflix-clone-05-client-model.pdf
PDF
Creating a Whatsapp Clone - Part II.pdf
PDF
Creating a Whatsapp Clone - Part IX - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part II - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part V - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part IV - Transcript.pdf
PDF
Creating a Whatsapp Clone - Part IV.pdf
PDF
Creating a Whatsapp Clone - Part I - Transcript.pdf
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-01-introduction.pdf
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-03-server.pdf
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-02-server.pdf
create-netflix-clone-05-client-model.pdf
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
Ad

Recently uploaded (20)

PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
OMC Textile Division Presentation 2021.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Getting Started with Data Integration: FME Form 101
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Mushroom cultivation and it's methods.pdf
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Mobile App Security Testing_ A Comprehensive Guide.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
cloud_computing_Infrastucture_as_cloud_p
Reach Out and Touch Someone: Haptics and Empathic Computing
OMC Textile Division Presentation 2021.pptx
Unlocking AI with Model Context Protocol (MCP)
A comparative analysis of optical character recognition models for extracting...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Getting Started with Data Integration: FME Form 101
Assigned Numbers - 2025 - Bluetooth® Document
Group 1 Presentation -Planning and Decision Making .pptx
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Programs and apps: productivity, graphics, security and other tools
Heart disease approach using modified random forest and particle swarm optimi...
Mushroom cultivation and it's methods.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...

Adapting to Tablets and Desktops - Part 3 - Transcript.pdf

  • 1. Adapting to Tablets & Desktops - Part III In this module we dig into the TabletUI class
  • 2. public void start() { if(current != null){ current.show(); return; } AppSettings app = AppStorage.getInstance().fetchAppSettings(); if(app.logo.get() == null) { app.setLogo(theme.getImage("icon.png")); app.setTitleBackground(theme.getImage("title-image.jpg")); } if(Display.getInstance().isTablet()) { Toolbar.setPermanentSideMenu(true); new TabletUI(app); } BaseNavigationForm.showDishForm(app); Display.getInstance().callSerially(() -> { Display.getInstance().registerPush(new Hashtable(), true); }); } RestaurantAppBuilder The tablet UI is created by the main class of the application, we initialize it here so when base navigation form uses the generic code it would already be initialized. We also initialize the permanent side menu which makes the side menu stay open all the time without the button. That’s a UI paradigm that makes sense on tablets and desktops.
  • 3. public class TabletUI extends Form { private static TabletUI instance; public TabletUI(AppSettings app) { super(new BorderLayout()); instance = this; Toolbar tb = getToolbar(); Style titleStyle = tb.getUnselectedStyle(); titleStyle.setBorder(Border.createEmpty()); titleStyle.setBgImage(app.getTitleBackground()); titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); titleStyle.setPadding(4, 4, 4, 4); TextField title = new TextField(Restaurant.getInstance().name.get()); title.setUIID("NavigationTitle"); title.addActionListener(a -> { Restaurant.getInstance().name.set(title.getText()); new Builder().updateRestaurantSettings(app); }); TextField tagline = new TextField(Restaurant.getInstance().tagline.get()); tagline.setUIID("Tagline"); TabletUI The tablet UI class is a form that encapsulates the full layout on a tablet It’s a singleton because we have just one form in the application and one UI
  • 4. public class TabletUI extends Form { private static TabletUI instance; public TabletUI(AppSettings app) { super(new BorderLayout()); instance = this; Toolbar tb = getToolbar(); Style titleStyle = tb.getUnselectedStyle(); titleStyle.setBorder(Border.createEmpty()); titleStyle.setBgImage(app.getTitleBackground()); titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); titleStyle.setPadding(4, 4, 4, 4); TextField title = new TextField(Restaurant.getInstance().name.get()); title.setUIID("NavigationTitle"); title.addActionListener(a -> { Restaurant.getInstance().name.set(title.getText()); new Builder().updateRestaurantSettings(app); }); TextField tagline = new TextField(Restaurant.getInstance().tagline.get()); tagline.setUIID("Tagline"); TabletUI We use a border layout and place the content of the UI in the center so we can replace it when navigating between UIAbstraction instances
  • 5. public class TabletUI extends Form { private static TabletUI instance; public TabletUI(AppSettings app) { super(new BorderLayout()); instance = this; Toolbar tb = getToolbar(); Style titleStyle = tb.getUnselectedStyle(); titleStyle.setBorder(Border.createEmpty()); titleStyle.setBgImage(app.getTitleBackground()); titleStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); titleStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); titleStyle.setPadding(4, 4, 4, 4); TextField title = new TextField(Restaurant.getInstance().name.get()); title.setUIID("NavigationTitle"); title.addActionListener(a -> { Restaurant.getInstance().name.set(title.getText()); new Builder().updateRestaurantSettings(app); }); TextField tagline = new TextField(Restaurant.getInstance().tagline.get()); tagline.setUIID("Tagline"); TabletUI The title and subtitle are editable here too, this is effectively a copy of the code from base navigation form adapted for the tablet form factor
  • 6. tagline.addActionListener(a -> { Restaurant.getInstance().tagline.set(tagline.getText()); new Builder().updateRestaurantSettings(app); }); tb.setTitleComponent(BoxLayout.encloseY(title, tagline)); Button logoImage = new Button("", app.getRoundedScaledLogo(), "TabletLogoImage"); logoImage.addActionListener(e -> { new ImagePickerForm(512, 512, "Icon", app.getLogo(), newImage -> { app.setLogo(newImage); logoImage.setIcon(app.getRoundedScaledLogo()); }).show(); }); tb.addComponentToSideMenu(logoImage); ButtonGroup bg = new ButtonGroup(); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Dish List", FontImage.MATERIAL_RESTAURANT_MENU, true, e -> BaseNavigationForm.showDishForm(app))); TabletUI This is also a copy from base navigation form, but thanks to the available space we don’t need to jump thru hoops to make this look good or fit. So the code here is much simpler
  • 7. tagline.addActionListener(a -> { Restaurant.getInstance().tagline.set(tagline.getText()); new Builder().updateRestaurantSettings(app); }); tb.setTitleComponent(BoxLayout.encloseY(title, tagline)); Button logoImage = new Button("", app.getRoundedScaledLogo(), "TabletLogoImage"); logoImage.addActionListener(e -> { new ImagePickerForm(512, 512, "Icon", app.getLogo(), newImage -> { app.setLogo(newImage); logoImage.setIcon(app.getRoundedScaledLogo()); }).show(); }); tb.addComponentToSideMenu(logoImage); ButtonGroup bg = new ButtonGroup(); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Dish List", FontImage.MATERIAL_RESTAURANT_MENU, true, e -> BaseNavigationForm.showDishForm(app))); TabletUI The logo image is now just an icon on the side menu which makes it look far better overall
  • 8. tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Details", FontImage.MATERIAL_DESCRIPTION, e -> BaseNavigationForm.showDetailsForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Billing", FontImage.MATERIAL_CREDIT_CARD, e -> BaseNavigationForm.showBillingForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Build the App", FontImage.MATERIAL_PHONE_IPHONE, e -> BaseNavigationForm.showAppForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "About Us", FontImage.MATERIAL_INFO, e -> BaseNavigationForm.showAboutForm(app))); tb.addCommandToRightBar("Edit Background", null, e -> { new ImagePickerForm(750, 295, "Background Image", app.getTitleBackground(), newImage -> { app.setTitleBackground(newImage); titleStyle.setBgImage(newImage); }).show(); }); } TabletUI You’ll notice that all the side menu entries are marked here but I’ll only highlight one as they are all mostly the same. Since we don’t derive from the base navigation form this code is a bit duplicate but it’s much simpler as we don’t need the whole hack with marking the selection. Notice we aren’t adding commands but rather adding components using the generic createSideNavigationEntry method. We’ll discuss that method soon but notice the bg argument we pass to each one of them. That’s a button group and these methods return a radio button this allows us to have the selection effect
  • 9. tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Details", FontImage.MATERIAL_DESCRIPTION, e -> BaseNavigationForm.showDetailsForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Billing", FontImage.MATERIAL_CREDIT_CARD, e -> BaseNavigationForm.showBillingForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "Build the App", FontImage.MATERIAL_PHONE_IPHONE, e -> BaseNavigationForm.showAppForm(app))); tb.addComponentToSideMenu(createSideNavigationEntry(bg, "About Us", FontImage.MATERIAL_INFO, e -> BaseNavigationForm.showAboutForm(app))); tb.addCommandToRightBar("Edit Background", null, e -> { new ImagePickerForm(750, 295, "Background Image", app.getTitleBackground(), newImage -> { app.setTitleBackground(newImage); titleStyle.setBgImage(newImage); }).show(); }); } TabletUI We also add the edit background image button to the side, it’s relatively trivial as there isn’t that much we need to do here.
  • 10. private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon, ActionListener<ActionEvent> ac) { return createSideNavigationEntry(bg, title, icon, false, ac); } private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon, boolean selected, ActionListener<ActionEvent> ac) { RadioButton a = RadioButton.createToggle(title, bg); a.setSelected(selected); a.setUIID("SideCommand"); FontImage.setMaterialIcon(a, icon, 4); a.addActionListener(ac); return a; } void showContainer(Container cnt, boolean direction) { if(getContentPane().getComponentCount() == 0) { add(BorderLayout.CENTER, cnt); show(); } else { getContentPane().replace(getContentPane().getComponentAt(0), cnt, CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, direction, 150)); } } TabletUI createSideNavigationEntry just generalizes the code that creates a radio button toggle button. It mostly saves some boilerplate and doesn’t feature much logic
  • 11. private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon, ActionListener<ActionEvent> ac) { return createSideNavigationEntry(bg, title, icon, false, ac); } private RadioButton createSideNavigationEntry(ButtonGroup bg, String title, char icon, boolean selected, ActionListener<ActionEvent> ac) { RadioButton a = RadioButton.createToggle(title, bg); a.setSelected(selected); a.setUIID("SideCommand"); FontImage.setMaterialIcon(a, icon, 4); a.addActionListener(ac); return a; } void showContainer(Container cnt, boolean direction) { if(getContentPane().getComponentCount() == 0) { add(BorderLayout.CENTER, cnt); show(); } else { getContentPane().replace(getContentPane().getComponentAt(0), cnt, CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, direction, 150)); } } TabletUI However, showContainer is pretty interesting. It’s the method that’s effectively invoked when show() or showBack() are invoked. There are two modes here. For the very first screen we need to use add. From that point on we’ll always use replace to show the next UIAbstraction instance.