【问题标题】:Switch add-on with push, vaadin使用 push 切换插件,vaadin
【发布时间】:2017-06-04 21:13:02
【问题描述】:

我有一个带有vaadin的附加开关的简单示例,我想要的是即使我更新UI时也保持开关的状态,即我支持多个选项卡,但我做不到,这个推送示例与我想要做的事情非常相似,但使用 textField

https://github.com/vaadin-marcus/push-example/blob/master/src/main/java/com/vaadin/training/ScrumBoardLayout.java

https://github.com/rucko24/MVP/blob/testingSwitchPushTemu/src/main/java/com/Core/vaadin/pushServer/ejemploPushMarkus/ScrumBoard.java

在我的示例中,我添加了一个灯泡,以便当其他人访问应用程序时可以看到灯泡的当前状态。我在 github 中的示例是只有 3 个类

https://github.com/rucko24/MVP/tree/testingSwitchPushTemu/src/main/java/com/Core/vaadin/pushServer/ejemploPushMarkus

这是改变我灯泡的开关监听器,但是当我得到布尔值(真或假)时,我仍然不明白按下另一个开关的正确方法

switchTemu.addValueChangeListener(new Property.ValueChangeListener() {
        private static final long serialVersionUID = 1L;

@Override
public void valueChange(Property.ValueChangeEvent event) {
        boolean estado = (boolean) event.getProperty().getValue();
        ScrumBoard.addSwitch(estado);
        switchTemu.removeValueChangeListener(this);
        if(estado == Boolean.TRUE) {
                bombilla.setIcon(bombillaON);

        }else {
                bombilla.setIcon(bombillaOFF);

        }
        switchTemu.addValueChangeListener(this);

        }
});

更新

在我的示例github成就中,将所有开关的状态更改为所有UI,但我仍然不知道如何获取开关的状态

【问题讨论】:

  • 对我来说,在查看代码并阅读说明后,您有点不清楚您想要做什么:1) 在您的 UI 之间共享一个灯泡/开关状态,如果它是在 UI 中打开/关闭更新其余部分? 2) 每个 UI 都有一个灯泡/开关,并且...?我假设它是 1),因此您应该只有一个静态开关状态(不是列表)和一个侦听器列表。一旦状态发生变化,将新状态广播给所有监听器,以便它们对应的 UI 得到更新。
  • 您好@Morfic 非常感谢您的帮助,是 1),当我更改影响其他 UI 的开关时,实际上只做那部分,我的问题是开关的状态不是刷新浏览器时保留,我尝试了几件事但我感到困惑: Markus 的代码,我尝试将其用作我的开关的指南,并像在他们的示例中一样保留其状态,甚至刷新浏览器

标签: java vaadin


【解决方案1】:

我对您的来源进行了一些更改(仍然是基本的,但它可以帮助您入门):

  • 只有 1 个公共共享状态
  • switch value change listeners 现在只需触发 state changed event
  • state changed listeners 现在会在触发时更新 UI 元素
  • 注册后,state changed listeners 会被告知(触发)当前状态

主要思想是只有一个共享状态,任何更改都会传达给所有侦听器(包括更改起源的侦听器)。

您可以在下面找到代码:(P.S. 我没有重新编译我的小部件集,所以漂亮的开关图标会退回到默认复选框样式)

1) SwitchState - 表示所有应用实例之间共享的开关状态

public enum SwitchState {
    ON(true, new ThemeResource("img/on.png")), OFF(false, new ThemeResource("img/off.png"));

    private final boolean value;
    private final ThemeResource icon;

    SwitchState(boolean value, ThemeResource icon) {
        this.value = value;
        this.icon = icon;
    }

    public boolean getValue() {
        return value;
    }

    public ThemeResource getIcon() {
        return icon;
    }

    public static SwitchState from(boolean value) {
        return value ? ON : OFF;
    }
}

2) ScrumBoard 通用状态和监听器管理器

public class ScrumBoard {

    // list of listeners    
    private static List<SwitchChangeListener> LISTENERS = new ArrayList<>();
    // initial state
    private static SwitchState STATE = SwitchState.OFF;

    // state change listener contract
    public interface SwitchChangeListener {
        void handleStateChange(SwitchState state);
    }

    // handle a a state change request
    public static synchronized void updateState(boolean value) {
        STATE = SwitchState.from(value);
        fireChangeEvent(STATE);
    }

    // register a new state listener
    public static synchronized void addSwitchChangeListener(SwitchChangeListener listener) {
        System.out.println("Added listener for " + listener);
        LISTENERS.add(listener);
        // when a new listener is registered, also inform it of the current state
        listener.handleStateChange(STATE);
    }

    // remove a state listener
    public static synchronized void removeSwitchListener(SwitchChangeListener listener) {
        LISTENERS.remove(listener);
    }

    // fire a change event to all registered listeners
    private static void fireChangeEvent(SwitchState state) {
        for (SwitchChangeListener listener : LISTENERS) {
            listener.handleStateChange(state);
        }
    }
}

3) ScrumBoardLayout - UI 布局和组件

public class ScrumBoardLayout extends VerticalLayout implements ScrumBoard.SwitchChangeListener {

    private Label icon = new Label();
    private Switch mySwitch = new Switch();

    public ScrumBoardLayout() {
        setMargin(true);
        setSpacing(true);
        addHeader();

        // listen for state changes
        ScrumBoard.addSwitchChangeListener(this);
    }

    private void addHeader() {
        mySwitch.setImmediate(true);
        icon.setSizeUndefined();

        // notify of state change
        mySwitch.addValueChangeListener((Property.ValueChangeListener) event -> ScrumBoard.updateState((Boolean) event.getProperty().getValue()));

        VerticalLayout layout = new VerticalLayout();
        layout.setHeight("78%");
        layout.addComponents(icon, mySwitch);

        layout.setComponentAlignment(icon, Alignment.BOTTOM_CENTER);
        layout.setComponentAlignment(mySwitch, Alignment.BOTTOM_CENTER);
        layout.setExpandRatio(mySwitch, 1);
        addComponents(layout);
    }

    @Override
    public void handleStateChange(SwitchState state) {
        // update UI on state change
        UI.getCurrent().access(() -> {
            mySwitch.setValue(state.getValue());
            icon.setIcon(state.getIcon());
            Notification.show(state.name(), Type.ASSISTIVE_NOTIFICATION);
        });
    }

    @Override
    public void detach() {
        super.detach();
        ScrumBoard.removeSwitchListener(this);
    }
}

4) 结果

【讨论】:

    【解决方案2】:

    我可以看到,使用 ThemeResource() 类,将灯泡更改为 ON/OFF 效果很奇怪,但我解决如下

    .bombillo-on {
        @include valo-animate-in-fade($duration: 1s);
        width: 181px;
        height: 216px;
        background: url(img/on.png) no-repeat;
    }
    .bombillo-off {
        @include valo-animate-in-fade($duration: 1s);
        width: 181px;
     height: 216px;
        background: url(img/off.png) no-repeat;
    }
    
    public enum Sstate {
    
    ON(true,"bombillo-on"),
    OFF(false,"bombillo-off");
    
    private boolean value;
    private String style;
    
    Sstate(boolean value, String style) {
        this.value = value;
        this.style = style;
    }
    
    public boolean getValue() { return value;}
    public String getStyle() { return style;}
    public static Sstate from(boolean value) { return value ? ON:OFF;}
    }
    

    而handleChangeEvent就一直这样

     @Override
     public void handleChangeEvent(Sstate state) {
        ui.access(() -> {
            bombilla.setStyleName(state.getStyle());
            s.setValue(state.getValue());
            System.out.println(state+" values "+s);
        });
     }
    

    更新:

    我注意到一个问题,当我添加新视图或使用 buttonMenuToggle 进行更改时,它会失去同步,并且更新灯泡很奇怪,用 themeResource 清除不会发生这种情况。

    解决方案:

    为了避免使用 Navigator 时出现 UiDetachedException,试试这个,效果很好

    @Override
     public void handleChangeEvent(Sstate state) {
        if(!ui.isAttached()) {
           BroadcastesSwitch.removeListener(this);
           return;
        }
        ui.access(() -> {
            bombilla.setStyleName(state.getStyle());
            s.setValue(state.getValue());
            System.out.println(state+" values "+s);
        });
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-03
      • 2021-04-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多