我對源進行了一些更改(仍是基本的,但它可以讓你開始):
- 只有1個公共共享狀態
switch value change listeners
現在只是觸發state changed event
state changed listeners
現在更新UI元素觸發
- UPO時Ñ註冊,
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)結果
對我來說這是一個有點不清楚你想要做什麼seing代碼和閱讀後說明:** 1)**在UI中共享一個燈泡/開關狀態,並且在UI中打開/關閉更新剩餘的狀態? ** 2 **)每個用戶界面都有一個燈泡/開關...?我假設它是** 1)**,所以你應該只有一個靜態開關狀態(不是列表)和一個監聽器列表。一旦狀態改變,將新狀態廣播給所有的監聽者,這樣他們相應的UI就會被更新。 – Morfic
您好@Morfic非常感謝您的幫助,是1),當我更改影響其他用戶界面的開關,並且實際上只是在做這個部分時,我的問題是,當我刷新瀏覽器時,開關狀態不會保留,我已經嘗試了幾件事,但我感到困惑:s,也就是說,如果我的開關打開,我應該繼續刷新選項卡,我不想使用PreserveOnRefresh:s,作爲Markus的示例代碼,我嘗試使用它作爲我的交換機的指南,並保持其狀態,因爲他們在他們的例子中甚至刷新瀏覽器 –