SlideShare a Scribd company logo
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

Initial UI Mockup - Part 2.pdf
Initial UI Mockup - Part 2.pdfInitial UI Mockup - Part 2.pdf
Initial UI Mockup - Part 2.pdf
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
Architecture - Part 2 - Transcript.pdf
Architecture - Part 2 - Transcript.pdfArchitecture - Part 2 - Transcript.pdf
Architecture - Part 2 - Transcript.pdf
ShaiAlmog1
 
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
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
 
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
ShaiAlmog1
 
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
 
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
ShaiAlmog1
 
Chap1 1 4
Chap1 1 4Chap1 1 4
Chap1 1 4
Hemo Chella
 
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
ShaiAlmog1
 

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

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 ...
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
ShaiAlmog1
 
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
ShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
ShaiAlmog1
 
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
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

Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
Zilliz
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 

Recently uploaded (20)

Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 

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