From 4a56d2a8867aec86e99c278d14516b7f765eef9c Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Wed, 2 Aug 2023 07:42:25 +0100 Subject: [PATCH] Support initial checked state - In MenuView initial check state can be set. - Relates #832 --- .../component/view/control/MenuView.java | 38 +++++++++++++++++- .../component/view/control/MenuViewTests.java | 40 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/MenuView.java b/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/MenuView.java index 0269efbf4..8cbb6426a 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/MenuView.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/MenuView.java @@ -94,6 +94,14 @@ public void setItems(@Nullable List items) { if (!items.isEmpty()) { activeItemIndex = 0; } + items.forEach(i -> { + if (i.initialCheckState && i.getCheckStyle() == MenuItemCheckStyle.CHECKED) { + checkedActive.add(i); + } + else if (i.initialCheckState && i.getCheckStyle() == MenuItemCheckStyle.RADIO) { + radioActive = i; + } + }); } } @@ -321,6 +329,7 @@ public static class MenuItem { private final MenuItemCheckStyle checkStyle; private final List items; private Runnable action; + private boolean initialCheckState = false; /** * Construct menu item with a title. @@ -342,19 +351,33 @@ public MenuItem(String title, MenuItemCheckStyle checkStyle) { } /** - * Construct menu item with a title and a check style. + * Construct menu item with a title, a check style and a runnable. * * @param title the title * @param checkStyle the check style * @param action the action to run when item is chosen */ public MenuItem(String title, MenuItemCheckStyle checkStyle, Runnable action) { + this(title, checkStyle, action, false); + } + + /** + * Construct menu item with a title, a check style, a runnable and initial + * checked state. + * + * @param title the title + * @param checkStyle the check style + * @param action the action to run when item is chosen + * @param initialCheckState initial checked state + */ + public MenuItem(String title, MenuItemCheckStyle checkStyle, Runnable action, boolean initialCheckState) { Assert.state(StringUtils.hasText(title), "title must have text"); Assert.notNull(checkStyle, "check style cannot be null"); this.title = title; this.checkStyle = checkStyle; this.action = action; this.items = null; + this.initialCheckState = initialCheckState; } protected MenuItem(String title, MenuItem[] items) { @@ -395,6 +418,10 @@ public static MenuItem of(String title, MenuItemCheckStyle checkStyle, Runnable return new MenuItem(title, checkStyle, action); } + public static MenuItem of(String title, MenuItemCheckStyle checkStyle, Runnable action, boolean initialCheckState) { + return new MenuItem(title, checkStyle, action, initialCheckState); + } + public Runnable getAction() { return action; } @@ -403,6 +430,15 @@ public void setAction(Runnable action) { this.action = action; } + /** + * Gets initial check state. + * + * @return initial check state + */ + public boolean isInitialCheckState() { + return initialCheckState; + } + /** * Get a {@code title}. Never null, empty or just having white spaces. * diff --git a/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/MenuViewTests.java b/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/MenuViewTests.java index 5a8988a79..5681b8eac 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/MenuViewTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/MenuViewTests.java @@ -17,6 +17,7 @@ import java.time.Duration; import java.util.Arrays; +import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -38,10 +39,13 @@ class MenuViewTests extends AbstractViewTests { private static final String SELECTED_FIELD = "activeItemIndex"; + private static final String RADIO_ACTIVE_FIELD = "radioActive"; + private static final String CHECKED_ACTIVE_FIELD = "checkedActive"; @Nested class Construction { + @SuppressWarnings("unchecked") @Test void constructView() { MenuView view; @@ -69,6 +73,42 @@ void constructView() { new MenuItem("sub2", MenuItemCheckStyle.RADIO) }); assertThat(view.getItems()).hasSize(2); + + view = new MenuView(new MenuItem[] { + new MenuItem("sub1", MenuItemCheckStyle.RADIO, null, true), + new MenuItem("sub2", MenuItemCheckStyle.RADIO, null, false) + }); + assertThat(view.getItems()).hasSize(2); + MenuItem radioActive = (MenuItem) ReflectionTestUtils.getField(view, RADIO_ACTIVE_FIELD); + assertThat(radioActive).isNotNull(); + assertThat(radioActive.getTitle()).isEqualTo("sub1"); + + view = new MenuView(new MenuItem[] { + new MenuItem("sub1", MenuItemCheckStyle.CHECKED, null, true), + new MenuItem("sub2", MenuItemCheckStyle.CHECKED, null, true) + }); + assertThat(view.getItems()).hasSize(2); + Set checkedActive = (Set) ReflectionTestUtils.getField(view, CHECKED_ACTIVE_FIELD); + assertThat(checkedActive).isNotNull(); + assertThat(checkedActive).hasSize(2); + } + + @Test + void constructItem() { + MenuItem item; + Runnable runnable = () -> {}; + + item = new MenuItem("title", MenuItemCheckStyle.RADIO, runnable, true); + assertThat(item.getTitle()).isEqualTo("title"); + assertThat(item.getCheckStyle()).isEqualTo(MenuItemCheckStyle.RADIO); + assertThat(item.getAction()).isSameAs(runnable); + assertThat(item.isInitialCheckState()).isTrue(); + + item = MenuItem.of("title", MenuItemCheckStyle.RADIO, runnable, true); + assertThat(item.getTitle()).isEqualTo("title"); + assertThat(item.getCheckStyle()).isEqualTo(MenuItemCheckStyle.RADIO); + assertThat(item.getAction()).isSameAs(runnable); + assertThat(item.isInitialCheckState()).isTrue(); } @Test