Почему я не могу изменить состояние компонентов vaadin после создания пользовательского интерфейса? - PullRequest
0 голосов
/ 02 июля 2019

У меня есть пользовательский интерфейс vaadin, который должен быть динамическим (видимость полей должна меняться в зависимости от выбора пользователя). Я пробовал разные способы изменения состояния компонентов, такие как setEnabled (), setLabel (), ...

У меня есть ComboBox, в котором пользователь выбирает значения из en Enum. Я добавил ValueChangeListener в ComboBox, в котором я пытаюсь изменить Labels и другие свойства некоторых TextFields (setLabel (), setEnabled (), ...).

Мой ComboBox имеет ValueChangeListener как это:

myComboBox.addValueChangeListener(event -> refreshLabels(event.getValue()));

Сначала я написал такой метод:

private void refreshLabels(MyEnum e){
   switch(e){
   case OPTION1: textField1.setLabel("some Text");
                 textField2.setLabel("some Text");
   case OPTION2: textField1.setLabel("some other Text");
                 textField2.setLabel("some other Text");
   }
}

Но при этом методе ярлыки не будут обновляться.

Затем я написал еще одну процедуру обновления Ярлыков:

private String getNewLabel(MyEnum e){
   switch(e){
   case OPTION1: return "some Text";
   case OPTION2: return "some other Text";
   default: return "";
   }
}

Я также изменил ValueChangeListener моего ComboBox:

myComboBox.addValueChangeListener(event -> textField1.setLabel(getNewLabel(event.getValue())));

С этим кодом мои ярлыки обновляются.

Как видите, у меня есть обходной путь, но с этим обходным путем я должен написать метод getNeLabel для каждого поля, потому что все поля будут нуждаться в разных метках при обновлении ComboBox. Я не понимаю, почему мой первый подход не работает, а второй работает. В обоих случаях компоненты уже добавляются в макет и отображаются в пользовательском интерфейсе при изменении метки. Может кто-нибудь объяснить мне это?

1 Ответ

3 голосов
/ 03 июля 2019

На самом деле, нет ничего плохого в вашем первом подходе, и поле со списком должно и корректно обновляет значения меток текстовых полей. Проблема в вашем фрагменте кода в блоке switch. Вы забыли добавить break; туда. Таким образом, значения всегда устанавливаются на второй (последний) параметр, если есть любое совпадение. (Во втором случае вы прекращаете выполнение switch, возвращаясь из метода, поэтому он работает там)

Из Учебное пособие по оракулу :

Каждый оператор break завершает вмещающий оператор switch. Поток управления продолжается с первого оператора, следующего за блоком переключателей. Операторы break необходимы, потому что без них операторы в блоках переключателей не работают: все операторы после совпадающей метки регистра выполняются последовательно, независимо от выражения последующих меток регистра, до тех пор, пока не встретится оператор break.

Это работает для меня правильно:

 TextField textField1 = new TextField("first");
 TextField textField2 = new TextField("second");
//Some method here
 ComboBox<MyEnum> cb=new ComboBox<>();
 cb.setItems(MyEnum.values());
 cb.addValueChangeListener(event->{
        refreshLabels(event.getValue());
 });
 add(cb);
 add(textField1);
 add(textField2);
//End of a method here
 private void refreshLabels(MyEnum e){
             switch(e){
             case FIRST: textField1.setLabel("some Text");
                     textField2.setLabel("some Text");
                     break;
             case SECOND: textField1.setLabel("some other Text");
                     textField2.setLabel("some other Text");
                     break;
             }
     }
...