Skip to content

Commit a5d0ad5

Browse files
authored
Add first-class Sheet title component customization (#4709)
1 parent 820a51e commit a5d0ad5

5 files changed

Lines changed: 112 additions & 3 deletions

File tree

CodenameOne/src/com/codename1/ui/Sheet.java

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,14 @@ public class Sheet extends Container {
122122
private static final int DEFAULT_TRANSITION_DURATION = 300;
123123
private final Sheet parentSheet;
124124
private final Label title = new Label();
125+
private Component titleComponent = title;
125126
private final EventDispatcher closeListeners = new EventDispatcher();
126127
private final EventDispatcher backListeners = new EventDispatcher();
127128
private final Button backButton = new Button(FontImage.MATERIAL_CLOSE);
128129
private final Container commandsContainer = new Container(BoxLayout.x());
130+
private final Container titleComponentContainer = FlowLayout.encloseCenterMiddle(title);
129131
private final Container titleBar = BorderLayout.center(LayeredLayout.encloseIn(
130-
BorderLayout.center(FlowLayout.encloseCenterMiddle(title)),
132+
BorderLayout.center(titleComponentContainer),
131133
BorderLayout.centerEastWest(null, commandsContainer, backButton)
132134
));
133135
private final Container contentPane = new Container(BoxLayout.y());
@@ -399,6 +401,77 @@ public Container getCommandsContainer() {
399401
return commandsContainer;
400402
}
401403

404+
/// Gets the title text displayed in the default title label.
405+
///
406+
/// #### Returns
407+
///
408+
/// The sheet title text.
409+
///
410+
/// #### Since
411+
///
412+
/// 8.0
413+
public String getTitle() {
414+
return title.getText();
415+
}
416+
417+
/// Sets the title text displayed in the default title label.
418+
///
419+
/// If a custom title component is currently installed via {@link #setTitleComponent(Component)},
420+
/// this method still updates the default title label so that it will be shown if the title
421+
/// component is reset back to null.
422+
///
423+
/// #### Parameters
424+
///
425+
/// - `title`: The title text.
426+
///
427+
/// #### Since
428+
///
429+
/// 8.0
430+
public void setTitle(String title) {
431+
this.title.setText(title);
432+
}
433+
434+
/// Gets the component currently used in the center of the title bar.
435+
///
436+
/// #### Returns
437+
///
438+
/// The current title component.
439+
///
440+
/// #### Since
441+
///
442+
/// 8.0
443+
public Component getTitleComponent() {
444+
return titleComponent;
445+
}
446+
447+
/// Sets the title component rendered in the center of the title bar.
448+
///
449+
/// This allows for custom title layouts such as including an image above the title text.
450+
/// If `null` is passed, the default title label is restored.
451+
///
452+
/// #### Parameters
453+
///
454+
/// - `cmp`: The component to use for the title area, or `null` to restore the default title label.
455+
///
456+
/// #### Since
457+
///
458+
/// 8.0
459+
public void setTitleComponent(Component cmp) {
460+
if (cmp == null) {
461+
cmp = title;
462+
}
463+
if (cmp == titleComponent) { //NOPMD CompareObjectsWithEquals
464+
return;
465+
}
466+
if (cmp.getParent() != null) {
467+
cmp.remove();
468+
}
469+
titleComponentContainer.removeAll();
470+
titleComponentContainer.add(cmp);
471+
titleComponent = cmp;
472+
titleComponentContainer.revalidateLater();
473+
}
474+
402475
private void initUI() {
403476
setLayout(new BorderLayout());
404477
contentPane.setSafeArea(true);
@@ -449,7 +522,7 @@ public void show(final int duration) {
449522

450523
// Set the padding in the content pane to match the corner radius
451524
Style s = getStyle();
452-
Style titleParentStyle = title.getParent().getStyle();
525+
Style titleParentStyle = titleComponentContainer.getStyle();
453526
titleParentStyle.setMarginLeft(titleMargin);
454527
titleParentStyle.setMarginRight(titleMargin);
455528
Border border = s.getBorder();

maven/core-unittests/src/test/java/com/codename1/ui/SheetTest.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.codename1.junit.FormTest;
44
import com.codename1.junit.UITestBase;
5-
import com.codename1.ui.Label;
65
import com.codename1.ui.layouts.BorderLayout;
6+
import com.codename1.ui.layouts.BoxLayout;
77

88
import java.util.concurrent.CountDownLatch;
99
import java.util.concurrent.TimeUnit;
@@ -85,4 +85,33 @@ void allowCloseFlagCanBeToggled() {
8585
form.getAnimationManager().flush();
8686
assertNull(Sheet.getCurrentSheet(), "No sheet should remain after backing out");
8787
}
88+
89+
@FormTest
90+
void titleComponentCanBeCustomized() {
91+
implementation.setBuiltinSoundsEnabled(false);
92+
Form form = Display.getInstance().getCurrent();
93+
form.setLayout(new BorderLayout());
94+
95+
Sheet sheet = new Sheet(null, "Default Title");
96+
Container customTitle = BoxLayout.encloseY(
97+
new Label("Icon"),
98+
new Label("Custom Title")
99+
);
100+
sheet.setTitleComponent(customTitle);
101+
102+
assertSame(customTitle, sheet.getTitleComponent(), "Custom title component should be installed");
103+
assertEquals("Default Title", sheet.getTitle(), "getTitle() should still return default title label text");
104+
105+
sheet.show(0);
106+
form.getAnimationManager().flush();
107+
flushSerialCalls();
108+
109+
assertSame(sheet, Sheet.findContainingSheet(customTitle), "Custom title component should be in the sheet hierarchy");
110+
111+
sheet.setTitle("Updated");
112+
assertEquals("Updated", sheet.getTitle(), "setTitle() should update default title label text");
113+
114+
sheet.setTitleComponent(null);
115+
assertNotNull(sheet.getTitleComponent(), "Resetting title component should restore default title label");
116+
}
88117
}
230 Bytes
Loading

scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/SheetScreenshotTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.codename1.ui.Button;
44
import com.codename1.ui.Container;
55
import com.codename1.ui.Form;
6+
import com.codename1.ui.FontImage;
67
import com.codename1.ui.Label;
78
import com.codename1.ui.Sheet;
89
import com.codename1.ui.layouts.BorderLayout;
@@ -35,6 +36,12 @@ protected void registerReadyCallback(Form parent, Runnable run) {
3536

3637
private Sheet createSheet(Sheet parent, String title) {
3738
Sheet newSheet = new Sheet(parent, title);
39+
Label titleIcon = new Label();
40+
FontImage.setMaterialIcon(titleIcon, FontImage.MATERIAL_IMAGE, 3f);
41+
titleIcon.setUIID("SheetTitleIcon");
42+
Label titleLabel = new Label(title);
43+
titleLabel.setUIID("SheetTitleText");
44+
newSheet.setTitleComponent(BoxLayout.encloseYCenter(titleIcon, titleLabel));
3845
Container content = newSheet.getContentPane();
3946
content.setLayout(BoxLayout.y());
4047
content.add(new Label("Sheet content"));

scripts/ios/screenshots/Sheet.png

1.25 KB
Loading

0 commit comments

Comments
 (0)