【问题标题】:Horizontal button bar with slider in VaadinVaadin 中带滑块的水平按钮栏
【发布时间】:2019-10-17 05:06:41
【问题描述】:

我的目标是创建一个水平按钮栏,其中包含可变数量的按钮。每次单击按钮都应打开某个新的 gui,该 gui 嵌入到现有的 gui 中,位于 Horizo​​ntalLayout 上方。

第一个按钮应该始终存在。这是到目前为止的代码:

public class MainLayout extends VerticalLayout implements PageConfigurator
{
    int number = 10;

/**
 *
 */
public MainLayout()
{
    super();
    this.initUI();
    this.createButtons();
}

private void createButtons()
{
    for(int i = 1; i <= this.number; i++)
    {
        final Button button = new Button();
        button.setText("Button" + i);
        button.setHeight("120px");
        button.setWidth("120px");

        this.horizontalLayout.addComponentAtIndex(i, button);
    }
}

@Override
public void configurePage(final InitialPageSettings settings)
{
    settings.addLink("shortcut icon", "frontend/images/favicon.ico");
    settings.addFavIcon("icon", "frontend/images/favicon256.png", "256x256");
}

/* WARNING: Do NOT edit!<br>The content of this method is always regenerated by the UI designer. */
// <generated-code name="initUI">
private void initUI()
{
    this.div              = new Div();
    this.horizontalLayout = new HorizontalLayout();
    this.button           = new Button();

    this.button.setText("Button");

    this.button.setWidth("120px");
    this.button.setHeight("120px");
    this.horizontalLayout.add(this.button);
    this.div.setWidth("100px");
    this.div.setHeight("100px");
    this.horizontalLayout.setWidthFull();
    this.horizontalLayout.setHeight("100px");
    this.add(this.div, this.horizontalLayout);
    this.setSizeFull();
} // </generated-code>

// <generated-code name="variables">
private Button           button;
private HorizontalLayout horizontalLayout;
private Div              div;
// </generated-code>

}

我的问题:

  • 如何在按钮的水平布局中获得滑块?这样,当按钮太多时,我可以切换视图。

  • 稍后我想更新按钮栏,所以“数字”会在运行时改变。按钮栏应识别此更改并创建给定数量的按钮。如何实施更新?

【问题讨论】:

  • 听起来您应该使用 Vaadin 附带的 Tabs 小部件来在视图之间切换。除了切换内容之外,您的按钮栏还有更多内容吗?支持动态添加/删除选项卡,当您的选项卡超出屏幕大小时,滚动条也支持。
  • 我正在使用 Vaadin Flow

标签: java user-interface slider vaadin vaadin-flow


【解决方案1】:

如何在按钮的水平布局中获得滑块?

为此,我建议使用插件ScrollLayout,它提供VerticalScrollLayoutHorizontalScrollLayout 两个类。在这种情况下,您将使用水平的。像使用任何其他 Horizo​​ntalLayout 一样使用它,但是如果没有足够的空间来显示所有内容,它将水平扩展并添加一个水平滚动条。我自己制作了这个插件,所以如果有任何问题,请不要犹豫。 (此插件没有 V14 版本,但您可以在 V14 项目中使用 V13 版本,它是兼容的)

稍后我想更新按钮栏,所以“数字”会在运行时改变。按钮栏应能识别此更改并创建给定数量的按钮。如何实现更新?

1) 删除所有现有按钮
2) 再次添加适量的按钮

private void updateButtons(){
    this.horizontalLayout.removeAll();
    createButtons();
}

编辑:这是一种简单的方法,删除所有按钮,然后重新添加正确的数量。如果你想更花哨一点,你可以尝试保留一些按钮,如果它们无论如何都会被读取。示例:假设您最初有 4 个按钮。当您将number 更改为 3 时,您只需删除最后一个按钮,而不是删除 4 然后添加 3。这样做的好处是,您可能在相应显示的按钮布局中所做的任何更改都不会被丢弃。如果您在显示/隐藏布局中使用Binder,这将是一个重要的区别。


作为旁注,您基本上是在此处使用按钮实现Tabs 的功能。虽然这当然是可能的,但我建议您尝试使用 Tabs。我知道你昨天试过了,但我认为你放弃得太早了。我意识到选项卡有些复杂,但是您必须使用此按钮解决方案创建类似的复杂性(您的当前实现尚未完成 - 您仍然必须创建一个显示每个按钮的布局,并添加一个单击侦听器将触发此可见性更改)

【讨论】:

  • 我改成按钮的另一个原因是有更多的可能性来设置它们的样式。还是我错了?
  • 它肯定会有不同的外观/造型可能性。从技术上讲,您可以在每个选项卡中添加一个按钮。不知道那看起来有多棒。我并不是要强迫您使用 Tabs,只是要知道使用 Buttons 并没有变得更容易。
  • 只要没有死胡同就可以了。
【解决方案2】:

标签

您正在复制已内置到 Vaadin TabsTab 小部件中的功能。无需在这里重新发明轮子。此外,如果按钮的作用类似于选项卡,只会在窗口内的内容面板之间切换,您会迷惑用户。

标签具有您要求的功能:

  • 在窗口内切换内容面板
  • 如果太多而无法在屏幕上显示,则滚动
  • 可以通过 Vaadin themes (Lumo & Material) 和 CSS 自定义外观。
    (请参阅 this page 底部的示例。)
  • 可以添加和删除选项卡。您还可以禁用选项卡,使其在不活动时褪色但仍然可读。

要切换内容,只需调用setVisible 隐藏或显示即可。通过 CSS 隐藏非常快。并且setVisible 为 false 还会关闭从 Vaadin 服务器对 Vaadin 组件的更新,因此您可以更新隐藏的内容(如果需要),而无需不必要地更新浏览器。

examples page带有页面的标签 部分为您提供了一个很好的代码示例来管理内容切换。 Map 跟踪每个选项卡与其内容的关系。底部的监听器方法通过隐藏和显示来切换内容。复制到这里:

Tab tab1 = new Tab("Tab one");
Div page1 = new Div();
page1.setText("Page#1");

Tab tab2 = new Tab("Tab two");
Div page2 = new Div();
page2.setText("Page#2");
page2.setVisible(false);

Tab tab3 = new Tab("Tab three");
Div page3 = new Div();
page3.setText("Page#3");
page3.setVisible(false);

Map<Tab, Component> tabsToPages = new HashMap<>();
tabsToPages.put(tab1, page1);
tabsToPages.put(tab2, page2);
tabsToPages.put(tab3, page3);
Tabs tabs = new Tabs(tab1, tab2, tab3);
Div pages = new Div(page1, page2, page3);
Set<Component> pagesShown = Stream.of(page1)
        .collect(Collectors.toSet());

tabs.addSelectedChangeListener(event -> {
    pagesShown.forEach(page -> page.setVisible(false));
    pagesShown.clear();
    Component selectedPage = tabsToPages.get(tabs.getSelectedTab());
    selectedPage.setVisible(true);
    pagesShown.add(selectedPage);
});

PagedTabs 小部件

从上面的代码 sn-p 中可以看出,与 Vaadin 捆绑的 TabsTab 小部件实际上不会切换内容。这些小部件只是(a)以符合主题的方式在屏幕上显示自己,以及(b)知道它们何时被点击的最低要求。

幸运的是,Alejandro Duarte 编写了一个包装 TabsTab 的小部件。 paged-tabsVaadin Directory 上进行了描述。您可以通过 Maven 下载或安装。该产品是免费和开源的(Apache 许可证 2)。

使用PagedTabs,您可以在添加每个选项卡时传递内容。在选项卡之间单击时,该内容会自动交换。您无需跟踪哪些内容属于哪个选项卡。并且无需您显示/隐藏内容。该小部件包括用于添加或删除选项卡以及删除匹配内容的方法。实际上,这个小部件支持使用“关闭”控件来删除选项卡。

不幸的是,我无法让这个PagedTabs 小部件将自身限制在浏览器窗口的宽度上。滚动控件永远不会出现在选项卡栏中。相反,用户必须向右滚动整个网页才能访问额外的选项卡。我提交了Issue # 11

这个PagedTabs 项目当然是个好主意,而且看起来很有前途。检查一下,也许该问题将得到解决,或者您可以找到解决方法。

【讨论】:

    猜你喜欢
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 2015-06-30
    相关资源
    最近更新 更多