Работа с формами во Free RAD

Форма описывается в XML/JSON. Первоначально это описание может делаться вручную, затем, по мере развития платформы, с помощью специально написанной программы-конфигуратора.

Декларативное описание формы

В описании формы указываются составляющие ее элементы.

Пример описания:

Group
  Name: DateAndNumber
  Frame: False
  Grouping: Horizontal
Field: Date
  Owner: DateAndNumber
  Caption: Дата
Field: Number
  Owner: DateAndNumber
  ButtonSelector: True
  Caption: №
  Width: 8 CH
Table: Products
Field: Product
  Owner: Table
  Caption: №
Field: Product
  Owner: Table
  Caption: Товар
Field: Count
  Owner: Table
  Caption: Кол-во
  Footer: true
Field: Rate
  Owner: Table
  Caption: Цена
Field: Summ
  Owner: Table
  Caption: Сумма
  Footer: true
Field: Comment
  Caption: Комментарий
  Multiline: True

Это описание описывает форму документа, содержащего дату, номер, таблицу товаров и многострочный комментарий.

Добавим еще кнопки в главную командную панель формы:

Button: Post
  Owner: MainCommandPanel
  Action: SystemFormPost
Button: Close
  Owner: MainCommandPanel
  Action: SystemFormClose
Button: Print
  Owner: MainCommandPanel 

Аналогично добавим кнопки в командную панель таблицы:

Button: ProductNewLine
  Owner: TableProduct
  Action: SystemTableAddNewLine
  Picture: SystemPictureAddNewLine //Картинка из системной библиотеки
  Display: Picture //Отображение в виде картинки, а не картинки с текстом или текста
Button: ProductDeleteLine
  Owner: TableProduct
  Action: SystemTableDeleteLine
  Picture: SystemPictureDeleteLine
  Display: Picture
Button: ProductMoveUp
  Owner: TableProduct
  Action: SystemTableMoveUp
  Picture: SystemPictureMoveUp
  Display: Picture
Button: ProductMoveDown
  Owner: TableProduct
  Action: SystemTableMoveDown
  Picture: SystemPictureMoveDown
  Display: Picture

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

Итак в этом разделе описаны элементы формы:

  1. Group — группа элементов
  2. Table — таблица
  3. Field — поле ввода
  4. Button — кнопка

Создание формы и ее события

В форму при открытии можно передать параметры Parameters. Также доступен родитель формы Parent.

Перед созданием формы вызывается событие FormInit, где можно отменить создание формы, проанализировав параметры или родительскую форму, например.

При открытии формы создаются последовательно ее элементы, происходит их выравнивание и размещение относительно друг друга.

Все элементы формы помещаются в коллекцию Controls.

После создания элементов вызывается FormReady. При необходимости можно добавить динамически свои элементы в коллекцию Controls и они будут отображены и размещены на форме.

Пример кода, который добавляет кнопку Calculate в главную командную панель:

FormReady {
  //Button - тип, Calculate - идентификатор
  Control = Controls.Add("Button", "Calculate");
  Control.Caption = "Расчитать";
  Control.Action = "OnCalculateAction";
  Control.Owner = MainCommandPanel;
}

Обработка событий элементов формы описывается в поле Action элемента.

События могут быть системными, тогда они начинаются с System.

Можно объявлять и свои обработчики событий. Тогда их нужно описывать в модуле формы. Например, если мы разместили кнопку с именем Calculate, которая выполняет некоторый расчет, и не указали название процедуры-обработчика в Action, то в модуле форме должна быть размещена процедура OnCalculateAction.

Если для элемента не назначен обработчик, событие можно обработать в процедуре OnOtherAction (для тех событий, для которых не назначены обработчики) или OnAllActions (вызывается для всех событий, перед вызовом описанного обработчика, можно отменить обработку) модуля формы, если эти обработчики описать в модуле формы.

Пример реализации процедуры нажатия на кнопку:

OnCalculateAction(Button) {
  MsgBox "Расчет ещё не реализован!";
}

Почему не ООП?

Почему в FreeRAD не используется ООП для описания форм?

Потому что это более сложный вариант описания форм.

Кроме того, возникает вопрос, как динамически добавлять нужные элементы?

Как-то раз я пробовал написать обычную форму для игры крестики-нолики на JAVA размером 15-15:

Код по созданию элементов формы загроможден и ужасен, вот только маленький его фрагмент:

javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
                .addContainerGap())
        );


        menuBar.setName("menuBar"); // NOI18N


        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N


        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(ru.com.fixin.crosszero.CrossZeroApp.class).getContext().getActionMap(CrossZeroView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);


        menuBar.add(fileMenu);


        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N


        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);


        menuBar.add(helpMenu);


        jMenu1.setText(resourceMap.getString("jMenu1.text")); // NOI18N
        jMenu1.setName("jMenu1"); // NOI18N
        jMenu1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenu1ActionPerformed(evt);
            }
        });
        menuBar.add(jMenu1);

Понятно, почему так происходит. Описание формы осуществляется непосредственно на языке, поэтому требуется соблюсти синтаксис и логику языка. В итоге — много мусора и перенасыщенность информации. Описание в формате XML/JSON намного компактнее и логичнее, понятно даже для визуального разбора.

комментариев 5

  1. royosi3498:

    Это курам на смех 🙂

    Во-первых, не раскрыто много критических вопросов, например: как будет происходить переиспользование кода (как сделать новый компонент и использовать его в своих формах, как создать новую форму на основе существующей), как управлять выводом элементов на форме (layout), как стилизовать существующие элементы (вот у тебя есть кнопка, которая в ста местах используется, не будешь же ты во всем ста местах ей прописывать проперти/флажки), как будет происходить биндинг данных с формой.

    Во-вторых, все это уже давно придумано, решено и успешно используется. Если бы ты не 20 лет сидел в своем болоте 1С, то знал бы это. Вот тебе краткий экскурс в историю: сначала (в конце 90-х, начале 2000-х) пытались решить эту проблему визуальными билдерами (Delphi, MSVC и т.д.), но это оказалось не удобно (тяжело вводить новые компоненты, тяжело рефакторить). Потом пытались использовать связку UI разметки + визуальные билдеры (ты сейчас находишься здесь 🙂 ), но осталась проблема связанности форм и кода. Наконец, пришли к DSL, специальным языкам, которые объединяют код и разметку (JavaFX/TornadoFX/QML, React/Vue/Flutter).

    А мораль сей басни такова, что прежде, чем изобретать велосипед, надо погуглить, может его изобрели уже до тебя 🙂

    • Спасибо за информацию, я обязательно учту ее при анализе программных инструментов для разработки Free RAD.
      Возможно, все и есть сейчас, но об этом мало известно.
      Иначе бы мы уже слышали о разработках в одно программистское лицо приложений с БД.
      Пока что я слышал о таких разработках только в 1С.
      Но я изучу ваши сведения, возможно в индустрии IT уже накопилось достаточно инструментов, чтобы собрать Free RAD, хорошо.
      Следите за темой и делитесь опытом.

      • naf2000:

        Может потому что ты ничем в разработке не интересуешься кроме 1с? Кстати я не знаю серьезных проектов в 1с написанных в одно рыло

  2. сергей:

    Посмотри что такое MS Access, и не изобретай ты велосипеда.

    • У меня есть практический опыт разработки в Access, это древний, морально устаревший инструмент. Типа Navision.

Добавить комментарий

Ваш адрес email не будет опубликован.