VaadinPlugin ClientSideEditorHints ru

Contents

Описание подсказок и доступных правок ассистента редактора, помогающих при разработке собственных компонент

Подсказки, описанные здесь являются лишь частью множества имплементированных правил, ограничений и конфигурационных требований фреймворка. Все эти правила конфигурируемы: можно отключить какие-то из них, изменить тип подсказки (ошибка, предупреждение,...), посмотреть описание каждого правила. Настройки конфигурации доступны через пункт меню Tools->Options, раздел Editor, вкладка Hints, узел Vaadin.

File:Vaadin-options-hints.png

Подсказки класса состояния

Класс состояния (подкласс SharedState) обычно создаётся с публично доступными полями:

          import com.vaadin.shared.ui.label.LabelState;

          public class LabelExState extends LabelState {
    
              public String tooltipShortText;
    
              public String tooltipFullText;
          }
Это нарушает принципы инкапсуляции, но в этом конкретном случае такой подход имеет смысл: класс служит только для переноса информации между сервером и клиентом. Он должен быть сериализуемым и следовать спецификации JavaBeans. Это требования фреймворка. И для этого есть реализованные правила в списке упомянутых.


Вместо использования публичных полей можно было бы сделать класс бином: изменить модификаторы с public на private и добавить методы доступа к полям getXXX/setXXX. Но это даст только большее количество строк кода и не защитит поля от модификации, потому что всё равно метод установки значения необходим. А вот про эти методы можно очень легко забыть: вместо них можно сделать конструктор, инициализирующий поля. Методы, возвращающие значение есть, а больше в коде ничего и не требуется.

Но на деле эти методы необходимы: данные пересылаются по сети, будучи сериализованы и класс воссоздаётся и десериализируется на другом конце. Для того чтобы его десериализировать необходимы методы, устанавливающие значения полей. Такая же ситуация с классами, являющимися типами параметров RPC методов. Вернёмся к ней ещё раз ниже. Для класса состояния будет показана подсказка если такая ситуация возникнет.

Подсказки для RPC методов

Для взаимодействия сервер->клиент необходим подинтерфейс ClientRpc, также как для взаимодействия клиент-> сервер необходим интерфейс, отнаследованный от ServerRpc. Его можно создать и зарегистрировать для использования ровно тем же образом как и подинтерейс ServerRpc, рассмотренный здесь. Соответствующие подсказки показывает как редактор для серверной компоненты так и для класса коннектора.

File:Vaadin-component-client-rpc-hint.png File:Vaadin-component-client-rpc-fix.png

Если начать с серверной компоненты и воспользоваться предложенной правкой, то ассистент создаст необходимый интерфейс и сгенерирует метод, возвращающий ссылку на его прокси. Эту ссылку можно использовать в логике серверной компоненты для вызова методов на клиентской стороне.

    private LabelExClientRpc getClientRpc() {
        return getRpcProxy(LabelExClientRpc.class);
    }

Теперь можно открыть файл коннектора в редакторе и воспользоваться подсказками для генерации кода реализации RPC интерфейса и его регистрации. Ассистент редактора найдёт сгенерированный ранее интерфейс и предложит его использовать в качестве одной из правок. Другая предлагаемая правка сгенерирует интерфейс с нуля и задействует его в коннекторе также как и предыдущая правка уже существующий интерфейс.

File:Vaadin-connector-client-rpc-hint.png File:Vaadin-connector-client-rpc-fix.png

         @Connect(LabelEx.class)
         public class LabelExConnector extends LabelConnector { 
    
             public LabelExConnector() {
                 registerRpc(LabelExClientRpc.class, new LabelExClientRpc() {
                 });
             }

Анонимный класс, реализующий интерфейс здесь пустой, потому что сгенерированный на предыдущем шаге интерфейс был пустой. Если бы он содержал методы, то были бы сгенерированы методы-заглушки. Таким образом, вся рутинная работа по созданию и регистрации интерфейса взаимодействия сервер->клиент может быть выполнена ассистентом редактора.

Методы RPC интерфейсов имеют некоторые ограничения. Первое такое ограничение: они не должны возвращать никаких значений, то есть их "return type" должен быть void. Это связано с тем, что все вызовы асинхронны, а асинхронный вызов не может возвращать значений. Для этого есть соответствующая подсказка с правкой.

File:Vaadin-rpc-return-type.png File:Vaadin-rpc-return-type-fix.png

Следующее ограничение связано с тем, что методы компилируются в соответствующие методы языка JavaScript, где имя метода является его идентификатором, в отличие от языка Java, где метод определяется его сигнатурой, то есть можно иметь несколько методов с одним и тем же именем, но разными параметрами. Это не является ошибкой и не будет выявлено на стадии компиляции, но может привести к очень странным эфектам в развёрнутом приложении во время его исполнения. Эта ситуация также отслеживается ассистентом редактора.

File:Vaadin-rpc-method-names.png

Последнее ограничение связано с уже упомянутым в применении к классу состояния требованием соответствия типов параметров спецификации JavaBeans. Типы параметров должны быть сериализуемы, иметь конструктор без аргументов и иметь методы getXXX/setXXX для приватных полей. В данном случае про последнее требование легко забыть ввиду того, что, в отличие от класса состояния, где наличие конструктора без аргументов форсируется сгенерированными методами, возвращаюшими объект класса в серверной компоненте и коннекторе, здесь велико искушение при написании кода создать конструктор с параметрами, инициализирующий поля их значениями и методы чтения этих полей (getXXX), а методы, устанавливающие значения (setXXX) в коде не нужны. Однако, подобный подход приведёт к тому, что все поля параметров в имплементирующем методе будут нулевыми. Дело в том, что при передаче по сети сериализованного объекта он должен быть воссоздан с нуля. Для этого и необходим конструктор без аргументов (чего для обычной Java сериализации, кстати, не требуется) и методы setXXX. Обычно, при написании классов для параметров методов, необходимость конструктора без параметров выявляется при выполнении приложения: оно выбросит Exception при попытке создать объект на другой стороне. Исправляется это быстрым способом создания необходимого конструктора, а про методы setXXX никто не вспоминает. В итоге объект не будет содержать переданных данных и это трудно диагностируется. Все эти скрытые оговорки при использовании параметров в методах RPC интерфейсов (и чуть больше) выявляются ассистентом.

File:Vaadin-rpc-method-params.png

          public class CustomBean implements  Serializable{
              CustomBean( int id){   
              }
    
              public Object name;
    
              private int id;
    
              public int getId(){
                  return id;
              }
          }

Создание коннектора через ассистент редактора

В основном тексте коннектор и сама компонента создавались через визард в несколько приёмов (вызов визарда, задание имени класса, выбор суперкласса). Можно избежать использования визарда и создания классов вручную, придерживаясь стиля итеративной разработки. Обычно начинается всё с того, что нужно расширить функциональность существующей компоненты. Создаётся подкласс, пишется какой-то код в нём, потом возникает необходимость расширить и клиентскую часть кода. Вместо того чтобы вызывать визард и копировать в сгенерированные классы написанный уже код или создавать коннектор с нуля, рискуя где то что-то недописать, можно воспользоваться ассистентом редактора на компоненте в качестве контекста, который выявит отсутствие связанного с компонентой коннектора и предложит его создать. Останется только дать имя коннектору, а всю остальную рутинную работу возьмёт на себя ассистент.

File:Vaadin-no-connector-hint.png File:Vaadin-no-connector-fixes.png

File:Vaadin-connector-dialog-fix.png File:Vaadin-connector-dialog-widget-fix.png

@Connect(LabelEx.class)
public class LabelExConnector extends LabelConnector {
    
    public LabelExConnector() {
    }
    
    @Override
    public LabelExWidget getWidget() {
        return (LabelExWidget) super.getWidget();
    }
}

public class LabelExWidget extends VLabel {
    
    public static final String CLASSNAME = "labelex";
    
    public LabelExWidget(){
        setStyleName(CLASSNAME);
    }
    
}

Подсказки для класса, имплементирующего AcceptCriterion

При использовании возможностей DnD, предоставляемых Vaadin фреймворком может понадобится реализовать свой класс имплементирующий AcceptCriterion. При этом легко забыть о том, что серверная имплементация требует парного клиентского класса. Для подобной ситуации ассистент редактора показывает подсказку и правку, которой можно воспользоваться чтобы сгенерировать клиентский класс с нужным кодом.

File:Accept-criterion.png File:Accept-criterion-fix.png

Создание и использование темы

Vaadin приложение использует ресурсные файлы, расположенные внутри web каталога приложения для задания стилей. Совокупность таких файлов в определённом каталоге называется темой и может быть задана для приложения с помощью аннотации @Theme. Если эта аннотация отсутствует у вашего UI класса, то редактор покажет подсказку, предлагающую использовать тему: добавить аннотацию @Theme к классу и сгенерировать каталог темы со всеми необходимыми файлами.

File:Theme-fix.png

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo