SlideShare a Scribd company logo
1 of 12
Download to read offline
Initial UI Mockup - Part III
We’ll continue with the code for the dish list
private static GridLayout createLayout() {
if(Display.getInstance().isTablet()) {
return new GridLayout(6, 6);
} else {
return new GridLayout(3, 2);
}
}
public DishListForm(AppSettings app) {
super(app, createLayout());
for(Dish d : Restaurant.getInstance().menu.get().dishes) {
addDish(d);
}
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);
fab.bindFabToContainer(getContentPane());
fab.addActionListener(e -> {
Dish d = new Dish().description.set("Description of the dish...").
name.set("Dish Name").
price.set(3.0);
d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg"));
Restaurant.getInstance().menu.get().dishes.add(d);
addDish(d);
revalidate();
new DishEditForm(d).show();
});
}
DishListForm
The dish list form is the form that contains the set of dishes we can select from
private static GridLayout createLayout() {
if(Display.getInstance().isTablet()) {
return new GridLayout(6, 6);
} else {
return new GridLayout(3, 2);
}
}
public DishListForm(AppSettings app) {
super(app, createLayout());
for(Dish d : Restaurant.getInstance().menu.get().dishes) {
addDish(d);
}
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);
fab.bindFabToContainer(getContentPane());
fab.addActionListener(e -> {
Dish d = new Dish().description.set("Description of the dish...").
name.set("Dish Name").
price.set(3.0);
d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg"));
Restaurant.getInstance().menu.get().dishes.add(d);
addDish(d);
revalidate();
new DishEditForm(d).show();
});
}
DishListForm
The elements within this form are stored in a grid layout. You will notice that the number of rows is hardcoded, that is because rows are added implicitly as we add more
elements but columns won’t change by default. This means that if we only have 1 or two elements the rest of the places will remain blank and the one element we have
won’t take up all the space.
private static GridLayout createLayout() {
if(Display.getInstance().isTablet()) {
return new GridLayout(6, 6);
} else {
return new GridLayout(3, 2);
}
}
public DishListForm(AppSettings app) {
super(app, createLayout());
for(Dish d : Restaurant.getInstance().menu.get().dishes) {
addDish(d);
}
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);
fab.bindFabToContainer(getContentPane());
fab.addActionListener(e -> {
Dish d = new Dish().description.set("Description of the dish...").
name.set("Dish Name").
price.set(3.0);
d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg"));
Restaurant.getInstance().menu.get().dishes.add(d);
addDish(d);
revalidate();
new DishEditForm(d).show();
});
}
DishListForm
The floating action button at the bottom allows us to add a new dish to the set of existing dishes. Notice that we instantly add a dish and show the edit UI forcing the
user to delete the dish if he wants to cancel this addition. That’s a common practice on mobile where dealing with the OK/Cancel process is sometimes harder than just
doing something like this.
final void addDish(Dish d) {
ScaleImageButton sb = new ScaleImageButton(d.getFullSize());
sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
Label title = new Label(d.name.get(), "DishName");
Label description = new Label(d.description.get(), "DishDescription");
Container titleAndDescription = BoxLayout.encloseY(title, description);
titleAndDescription.setUIID("BlackGradient");
Container cnt = LayeredLayout.encloseIn(sb,
BorderLayout.south(titleAndDescription));
add(cnt);
cnt.setLeadComponent(sb);
setLayout(createLayout());
sb.addActionListener(e -> new DishEditForm(d).show());
}
DishListForm
The add dish method adds a UI element to the list of dishes. That element includes a black gradient overlay which makes the white text on top readable even with a
white image below.
final void addDish(Dish d) {
ScaleImageButton sb = new ScaleImageButton(d.getFullSize());
sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
Label title = new Label(d.name.get(), "DishName");
Label description = new Label(d.description.get(), "DishDescription");
Container titleAndDescription = BoxLayout.encloseY(title, description);
titleAndDescription.setUIID("BlackGradient");
Container cnt = LayeredLayout.encloseIn(sb,
BorderLayout.south(titleAndDescription));
add(cnt);
cnt.setLeadComponent(sb);
setLayout(createLayout());
sb.addActionListener(e -> new DishEditForm(d).show());
}
DishListForm
The entire component is a lead component which means all events within the container are delegated to the scale image button. That means that the listener on the scale
image button in the last line will receive all of the events in the container hierachy
super(d.name.get(), new BorderLayout());
Toolbar tb = getToolbar();
Button back = new Button("", "Title");
Button ok = new Button("", "Title");
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5);
FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5);
TextField title = new TextField(d.name.get());
title.setUIID("Title");
tb.setTitleComponent(
BorderLayout.centerEastWest(
BoxLayout.encloseY(title),
FlowLayout.encloseRight(ok),
FlowLayout.encloseIn(back)));
tb.setUIID("BlueGradient");
ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) {
@Override
protected Dimension calcPreferredSize() {
Dimension d = super.calcPreferredSize();
d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38)));
return d;
}
};
DishEditForm
We show the dish edit form when editing a dish, since a dish is instantly created and edited there is no form for new dish and this form doesn’t have 2 modes like you
normally would for edit or create. In this app there is only one mode: edit.
super(d.name.get(), new BorderLayout());
Toolbar tb = getToolbar();
Button back = new Button("", "Title");
Button ok = new Button("", "Title");
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5);
FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5);
TextField title = new TextField(d.name.get());
title.setUIID("Title");
tb.setTitleComponent(
BorderLayout.centerEastWest(
BoxLayout.encloseY(title),
FlowLayout.encloseRight(ok),
FlowLayout.encloseIn(back)));
tb.setUIID("BlueGradient");
ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) {
@Override
protected Dimension calcPreferredSize() {
Dimension d = super.calcPreferredSize();
d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38)));
return d;
}
};
DishEditForm
The title area of the dish edit form is built of components because it is large and relatively custom I preferred to handle all of the commands and functionality in code. So
the title itself is a text field again just like in the main form as the dish title can be edited “in place”.

The back and ok buttons are just standard buttons with the right UIID and icon.
super(d.name.get(), new BorderLayout());
Toolbar tb = getToolbar();
Button back = new Button("", "Title");
Button ok = new Button("", "Title");
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5);
FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5);
TextField title = new TextField(d.name.get());
title.setUIID("Title");
tb.setTitleComponent(
BorderLayout.centerEastWest(
BoxLayout.encloseY(title),
FlowLayout.encloseRight(ok),
FlowLayout.encloseIn(back)));
tb.setUIID("BlueGradient");
ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) {
@Override
protected Dimension calcPreferredSize() {
Dimension d = super.calcPreferredSize();
d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38)));
return d;
}
};
DishEditForm
This is where it get’s interesting… The title component is now really tall because of the background image. So if I had used a standard add material command it would
have been placed somewhere along the middle of the layout instead of at the top. 

So to get around this I created a border layout which effectively occupies this area but again if I’d add the components directly they will be placed at the middle vertically
instead of at the top as I would like. So I wrapped the two commands with a flow layout to push them to the top… 

I wrapped the text field with a box layout though and the reason is a bit more complicated. Flow layout doesn’t deal well with resizable components like text field since it
tries to break a line when we run out of space. If the title is too long it will try to break a line instead of letting the text field overflow which is what I want. Box layout
doesn’t have that problem.
backgroundImage.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
add(BorderLayout.NORTH, backgroundImage);
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_COLLECTIONS);
Style fabStyle = fab.getAllStyles();
fab.bindFabToContainer(getContentPane(), RIGHT, TOP);
final Form previous = Display.getInstance().getCurrent();
Component.setSameHeight(tb, backgroundImage);
fabStyle.setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS,
Style.UNIT_TYPE_DIPS);
fabStyle.setMarginTop(tb.getPreferredH() - fab.getPreferredH() / 2);
Button delete = new Button("Delete Dish", "DeleteButton");
FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE);
delete.addActionListener(e -> previous.showBack());
ok.addActionListener(e -> previous.showBack());
back.addActionListener(e -> previous.showBack());
add(BorderLayout.SOUTH, delete);
TextField price = new TextField("" + d.price.get(), "Price", 5, TextField.DECIMAL);
TextField description = new TextField(d.description.get(), "Description", 5, TextField.ANY);
description.setSingleLineTextArea(false);
description.setRows(4);
add(BorderLayout.CENTER, BoxLayout.encloseY(
new Label("Price", "TextFieldLabel"),
price,
new Label("Description", "TextFieldLabel"),
description
));
DishEditForm
This code right here positions the floating action button on the border between the title area and the body. Notice that this component is positioned on top of both and
doesn’t require a special empty region like the icon in the previous form. We bind the floating action button directly to the layered layout on the top right which should
position it really high in the form but we then use this code to set the margin of the floating action button so it will match the toolbar height minus half the height of the
floating button. This positions it perfectly.
backgroundImage.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
add(BorderLayout.NORTH, backgroundImage);
FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_COLLECTIONS);
Style fabStyle = fab.getAllStyles();
fab.bindFabToContainer(getContentPane(), RIGHT, TOP);
final Form previous = Display.getInstance().getCurrent();
Component.setSameHeight(tb, backgroundImage);
fabStyle.setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS,
Style.UNIT_TYPE_DIPS);
fabStyle.setMarginTop(tb.getPreferredH() - fab.getPreferredH() / 2);
Button delete = new Button("Delete Dish", "DeleteButton");
FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE);
delete.addActionListener(e -> previous.showBack());
ok.addActionListener(e -> previous.showBack());
back.addActionListener(e -> previous.showBack());
add(BorderLayout.SOUTH, delete);
TextField price = new TextField("" + d.price.get(), "Price", 5, TextField.DECIMAL);
TextField description = new TextField(d.description.get(), "Description", 5, TextField.ANY);
description.setSingleLineTextArea(false);
description.setRows(4);
add(BorderLayout.CENTER, BoxLayout.encloseY(
new Label("Price", "TextFieldLabel"),
price,
new Label("Description", "TextFieldLabel"),
description
));
DishEditForm
Last but not least we can see the component representing the delete button at the bottom followed by stub action handling code for the various buttons.

Delete is placed in the south so it will always appear at the very bottom of the form regardless of scrolling
Thank You
Thanks for watching. I hope you found this informative

More Related Content

Similar to Initial UI Mockup - Part 3 - Transcript.pdf

I am looking for some assistance with SQLite database. I have tried se.pdf
I am looking for some assistance with SQLite database. I have tried se.pdfI am looking for some assistance with SQLite database. I have tried se.pdf
I am looking for some assistance with SQLite database. I have tried se.pdf
Conint29
 
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
allwayscollection
 
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdfSet up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
xlynettalampleyxc
 

Similar to Initial UI Mockup - Part 3 - Transcript.pdf (20)

Initial UI Mockup - Part 2.pdf
Initial UI Mockup - Part 2.pdfInitial UI Mockup - Part 2.pdf
Initial UI Mockup - Part 2.pdf
 
Extracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdfExtracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdf
 
Adapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdfAdapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdf
 
Creating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfCreating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdf
 
Creating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdfCreating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdf
 
Creating a Facebook Clone - Part XVI - Transcript.pdf
Creating a Facebook Clone - Part XVI - Transcript.pdfCreating a Facebook Clone - Part XVI - Transcript.pdf
Creating a Facebook Clone - Part XVI - Transcript.pdf
 
Architecture - Part 2 - Transcript.pdf
Architecture - Part 2 - Transcript.pdfArchitecture - Part 2 - Transcript.pdf
Architecture - Part 2 - Transcript.pdf
 
I am looking for some assistance with SQLite database. I have tried se.pdf
I am looking for some assistance with SQLite database. I have tried se.pdfI am looking for some assistance with SQLite database. I have tried se.pdf
I am looking for some assistance with SQLite database. I have tried se.pdf
 
SQLite and ORM Binding - Part 2 - Transcript.pdf
SQLite and ORM Binding - Part 2 - Transcript.pdfSQLite and ORM Binding - Part 2 - Transcript.pdf
SQLite and ORM Binding - Part 2 - Transcript.pdf
 
Initial UI Mockup - Part 2 - Transcript.pdf
Initial UI Mockup - Part 2 - Transcript.pdfInitial UI Mockup - Part 2 - Transcript.pdf
Initial UI Mockup - Part 2 - Transcript.pdf
 
Creating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdfCreating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdf
 
Finishing the App - Part 1 - Transcript.pdf
Finishing the App - Part 1 - Transcript.pdfFinishing the App - Part 1 - Transcript.pdf
Finishing the App - Part 1 - Transcript.pdf
 
Creating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdfCreating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdf
 
Creating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdfCreating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdf
 
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
 
Creating a Facebook Clone - Part XLII.pdf
Creating a Facebook Clone - Part XLII.pdfCreating a Facebook Clone - Part XLII.pdf
Creating a Facebook Clone - Part XLII.pdf
 
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdfSet up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
Set up a JavaFX GUI-based program that shows a 10 times 10 grid of la.pdf
 
Creating an Uber Clone - Part IX.pdf
Creating an Uber Clone - Part IX.pdfCreating an Uber Clone - Part IX.pdf
Creating an Uber Clone - Part IX.pdf
 
Chap1 1 4
Chap1 1 4Chap1 1 4
Chap1 1 4
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
 

More from ShaiAlmog1

More from ShaiAlmog1 (20)

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

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Recently uploaded (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 

Initial UI Mockup - Part 3 - Transcript.pdf

  • 1. Initial UI Mockup - Part III We’ll continue with the code for the dish list
  • 2. private static GridLayout createLayout() { if(Display.getInstance().isTablet()) { return new GridLayout(6, 6); } else { return new GridLayout(3, 2); } } public DishListForm(AppSettings app) { super(app, createLayout()); for(Dish d : Restaurant.getInstance().menu.get().dishes) { addDish(d); } FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.bindFabToContainer(getContentPane()); fab.addActionListener(e -> { Dish d = new Dish().description.set("Description of the dish..."). name.set("Dish Name"). price.set(3.0); d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg")); Restaurant.getInstance().menu.get().dishes.add(d); addDish(d); revalidate(); new DishEditForm(d).show(); }); } DishListForm The dish list form is the form that contains the set of dishes we can select from
  • 3. private static GridLayout createLayout() { if(Display.getInstance().isTablet()) { return new GridLayout(6, 6); } else { return new GridLayout(3, 2); } } public DishListForm(AppSettings app) { super(app, createLayout()); for(Dish d : Restaurant.getInstance().menu.get().dishes) { addDish(d); } FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.bindFabToContainer(getContentPane()); fab.addActionListener(e -> { Dish d = new Dish().description.set("Description of the dish..."). name.set("Dish Name"). price.set(3.0); d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg")); Restaurant.getInstance().menu.get().dishes.add(d); addDish(d); revalidate(); new DishEditForm(d).show(); }); } DishListForm The elements within this form are stored in a grid layout. You will notice that the number of rows is hardcoded, that is because rows are added implicitly as we add more elements but columns won’t change by default. This means that if we only have 1 or two elements the rest of the places will remain blank and the one element we have won’t take up all the space.
  • 4. private static GridLayout createLayout() { if(Display.getInstance().isTablet()) { return new GridLayout(6, 6); } else { return new GridLayout(3, 2); } } public DishListForm(AppSettings app) { super(app, createLayout()); for(Dish d : Restaurant.getInstance().menu.get().dishes) { addDish(d); } FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.bindFabToContainer(getContentPane()); fab.addActionListener(e -> { Dish d = new Dish().description.set("Description of the dish..."). name.set("Dish Name"). price.set(3.0); d.setFullSize(Resources.getGlobalResources().getImage("food1.jpg")); Restaurant.getInstance().menu.get().dishes.add(d); addDish(d); revalidate(); new DishEditForm(d).show(); }); } DishListForm The floating action button at the bottom allows us to add a new dish to the set of existing dishes. Notice that we instantly add a dish and show the edit UI forcing the user to delete the dish if he wants to cancel this addition. That’s a common practice on mobile where dealing with the OK/Cancel process is sometimes harder than just doing something like this.
  • 5. final void addDish(Dish d) { ScaleImageButton sb = new ScaleImageButton(d.getFullSize()); sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Label title = new Label(d.name.get(), "DishName"); Label description = new Label(d.description.get(), "DishDescription"); Container titleAndDescription = BoxLayout.encloseY(title, description); titleAndDescription.setUIID("BlackGradient"); Container cnt = LayeredLayout.encloseIn(sb, BorderLayout.south(titleAndDescription)); add(cnt); cnt.setLeadComponent(sb); setLayout(createLayout()); sb.addActionListener(e -> new DishEditForm(d).show()); } DishListForm The add dish method adds a UI element to the list of dishes. That element includes a black gradient overlay which makes the white text on top readable even with a white image below.
  • 6. final void addDish(Dish d) { ScaleImageButton sb = new ScaleImageButton(d.getFullSize()); sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Label title = new Label(d.name.get(), "DishName"); Label description = new Label(d.description.get(), "DishDescription"); Container titleAndDescription = BoxLayout.encloseY(title, description); titleAndDescription.setUIID("BlackGradient"); Container cnt = LayeredLayout.encloseIn(sb, BorderLayout.south(titleAndDescription)); add(cnt); cnt.setLeadComponent(sb); setLayout(createLayout()); sb.addActionListener(e -> new DishEditForm(d).show()); } DishListForm The entire component is a lead component which means all events within the container are delegated to the scale image button. That means that the listener on the scale image button in the last line will receive all of the events in the container hierachy
  • 7. super(d.name.get(), new BorderLayout()); Toolbar tb = getToolbar(); Button back = new Button("", "Title"); Button ok = new Button("", "Title"); FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5); FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5); TextField title = new TextField(d.name.get()); title.setUIID("Title"); tb.setTitleComponent( BorderLayout.centerEastWest( BoxLayout.encloseY(title), FlowLayout.encloseRight(ok), FlowLayout.encloseIn(back))); tb.setUIID("BlueGradient"); ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) { @Override protected Dimension calcPreferredSize() { Dimension d = super.calcPreferredSize(); d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38))); return d; } }; DishEditForm We show the dish edit form when editing a dish, since a dish is instantly created and edited there is no form for new dish and this form doesn’t have 2 modes like you normally would for edit or create. In this app there is only one mode: edit.
  • 8. super(d.name.get(), new BorderLayout()); Toolbar tb = getToolbar(); Button back = new Button("", "Title"); Button ok = new Button("", "Title"); FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5); FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5); TextField title = new TextField(d.name.get()); title.setUIID("Title"); tb.setTitleComponent( BorderLayout.centerEastWest( BoxLayout.encloseY(title), FlowLayout.encloseRight(ok), FlowLayout.encloseIn(back))); tb.setUIID("BlueGradient"); ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) { @Override protected Dimension calcPreferredSize() { Dimension d = super.calcPreferredSize(); d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38))); return d; } }; DishEditForm The title area of the dish edit form is built of components because it is large and relatively custom I preferred to handle all of the commands and functionality in code. So the title itself is a text field again just like in the main form as the dish title can be edited “in place”. The back and ok buttons are just standard buttons with the right UIID and icon.
  • 9. super(d.name.get(), new BorderLayout()); Toolbar tb = getToolbar(); Button back = new Button("", "Title"); Button ok = new Button("", "Title"); FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK, 5); FontImage.setMaterialIcon(ok, FontImage.MATERIAL_CHECK, 5); TextField title = new TextField(d.name.get()); title.setUIID("Title"); tb.setTitleComponent( BorderLayout.centerEastWest( BoxLayout.encloseY(title), FlowLayout.encloseRight(ok), FlowLayout.encloseIn(back))); tb.setUIID("BlueGradient"); ScaleImageLabel backgroundImage = new ScaleImageLabel(d.getFullSize()) { @Override protected Dimension calcPreferredSize() { Dimension d = super.calcPreferredSize(); d.setHeight(Math.min(d.getHeight(), Display.getInstance().convertToPixels(38))); return d; } }; DishEditForm This is where it get’s interesting… The title component is now really tall because of the background image. So if I had used a standard add material command it would have been placed somewhere along the middle of the layout instead of at the top. So to get around this I created a border layout which effectively occupies this area but again if I’d add the components directly they will be placed at the middle vertically instead of at the top as I would like. So I wrapped the two commands with a flow layout to push them to the top… I wrapped the text field with a box layout though and the reason is a bit more complicated. Flow layout doesn’t deal well with resizable components like text field since it tries to break a line when we run out of space. If the title is too long it will try to break a line instead of letting the text field overflow which is what I want. Box layout doesn’t have that problem.
  • 10. backgroundImage.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); add(BorderLayout.NORTH, backgroundImage); FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_COLLECTIONS); Style fabStyle = fab.getAllStyles(); fab.bindFabToContainer(getContentPane(), RIGHT, TOP); final Form previous = Display.getInstance().getCurrent(); Component.setSameHeight(tb, backgroundImage); fabStyle.setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS); fabStyle.setMarginTop(tb.getPreferredH() - fab.getPreferredH() / 2); Button delete = new Button("Delete Dish", "DeleteButton"); FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE); delete.addActionListener(e -> previous.showBack()); ok.addActionListener(e -> previous.showBack()); back.addActionListener(e -> previous.showBack()); add(BorderLayout.SOUTH, delete); TextField price = new TextField("" + d.price.get(), "Price", 5, TextField.DECIMAL); TextField description = new TextField(d.description.get(), "Description", 5, TextField.ANY); description.setSingleLineTextArea(false); description.setRows(4); add(BorderLayout.CENTER, BoxLayout.encloseY( new Label("Price", "TextFieldLabel"), price, new Label("Description", "TextFieldLabel"), description )); DishEditForm This code right here positions the floating action button on the border between the title area and the body. Notice that this component is positioned on top of both and doesn’t require a special empty region like the icon in the previous form. We bind the floating action button directly to the layered layout on the top right which should position it really high in the form but we then use this code to set the margin of the floating action button so it will match the toolbar height minus half the height of the floating button. This positions it perfectly.
  • 11. backgroundImage.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); add(BorderLayout.NORTH, backgroundImage); FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_COLLECTIONS); Style fabStyle = fab.getAllStyles(); fab.bindFabToContainer(getContentPane(), RIGHT, TOP); final Form previous = Display.getInstance().getCurrent(); Component.setSameHeight(tb, backgroundImage); fabStyle.setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS); fabStyle.setMarginTop(tb.getPreferredH() - fab.getPreferredH() / 2); Button delete = new Button("Delete Dish", "DeleteButton"); FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE); delete.addActionListener(e -> previous.showBack()); ok.addActionListener(e -> previous.showBack()); back.addActionListener(e -> previous.showBack()); add(BorderLayout.SOUTH, delete); TextField price = new TextField("" + d.price.get(), "Price", 5, TextField.DECIMAL); TextField description = new TextField(d.description.get(), "Description", 5, TextField.ANY); description.setSingleLineTextArea(false); description.setRows(4); add(BorderLayout.CENTER, BoxLayout.encloseY( new Label("Price", "TextFieldLabel"), price, new Label("Description", "TextFieldLabel"), description )); DishEditForm Last but not least we can see the component representing the delete button at the bottom followed by stub action handling code for the various buttons. Delete is placed in the south so it will always appear at the very bottom of the form regardless of scrolling
  • 12. Thank You Thanks for watching. I hope you found this informative