Афоризм
А в письмах Вы казались мне стройнее.
Наталья Резник
Последние статьи

 • платформа JaBricks
Платформа OSGi-приложения JaBricks
 • уроки JaBricks
Учебные примеры изучения платформы Jabricks
 • бандл 'О программе'
Модуль представления инфо о программе
 • бандл form-locale
Модуль определения языка локализации приложения
 • бандл util-db
Модуль взаимодействия с СУБД
 • бандл db-connection
Модуль подключения к серверу БД
 • бандлы JaBricks
Бандлы приложения JaBricks

Урок 13. Интерфейсная панель JPanel

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

В данном уроке будем заниматься разработкой интерфейсной панели приложения на платформе JaBricks. Как и в уроках 11 и 12 создавать интерфейсный бандл будем не на «пустом» месте. Используем в качестве шаблона проект templ-jpanel, который наследует свойства базового модуля base-jpanel. Преимущества использования базового модуля для создания интерфейсного бандла представлены на странице его описания. Здесь мы должны увидеть, насколько это соответствует действительности.

Структура проекта

Скачаем архив проекта templ-jpanel и «развернем» его. Проект создан в среде разработки IDE Eclipse. Мудрить не будем, назовем проект/бандл «templ-jpanela», т.е. добавим один символ в наименование. В первую очередь переименуем директорию. После этого внесем изменения в наименование проекта (<name>) в файле «templ-jpanela/.project». Далее переименуем artifactId проекта в «templ-jpanela/pom.xml». На этом все приготовления проекта к использованию заканчиваются. Импортируем проект в IDE. На скриншоте слева представлен проект в IDE Eclipse.

Структура проекта включает проектный файл pom.xml, набор свойств в директории (resources/properties) и два класса : JPanelActivator и JPanelForm. JPanelActivator играет роль активатора бандла. JPanelForm формирует интерфейс панели. Проектный файл pom.xml включает все зависимости модуля, параметры GAV и определяет порядок сборки бандла. Листинги исходных кодов представлены на странице описания бандла templ-jpanel.

Таким образом, чтобы ориентироваться в структуре проекта создания бандла, Вам необходимо иметь представление о Maven и OSGi.

Как и в уроке 12, добавим в интерфейс окна нашего бандла таблицу. Таблица также будет иметь локализованные заголовки колонок. Небольшие изменения, которые необходимо внести в проект, касаются только JPanelForm и ресурсов. Что ждать от данного модуля? После старта модуля все его регулируемые настройки (размеры колонок таблицы, положение сплитера) должны соответствовать «последнему состоянию». Кроме этого интерфейс модуля меняет свои локализованные надписи (наименования колонок) в режиме run-time, т.е. без перезагрузки бандла.

Описание

Активатор JPanelActivator оставим без изменений. Также, практически без изменений останется проектный файл pom.xml, если не считать изменения в наименовании артифакта (artifactId), выполненное ранее. Как было отмечено выше, в интерфейс JPanelForm внесем изменения, связанные с размещением в панели таблицы.

Класс JPanelForm

Поскольку неудобно за каждым «чихом» отправлять Вас на страницу модуля templ-jpanel, то здесь придется отдельные моменты описания класса JPanelForm повторить. Проект с исходными кодами Вы можете скачать в конце страницы.

Описание полей

К описанию полей, связанных со сплитерами, добавлены описания параметров таблицы. Строковые константы SPLITPANE_H, SPLITPANE_V и GRIDNAME используются при восстановлении регулируемых настроек интерфейса, описанных в уроке 6.

Листинг
private  JSplitPane     split_h;
private  JSplitPane     split_v;

private  final  int     DIVIDER_H   = 450;
private  final  int     DIVIDER_V   = 200;

private  final  String  SPLITPANE_H = "SPLITPANE_H";
private  final  String  SPLITPANE_V = "SPLITPANE_V";

private  IGrid          grid        = null;
private  final  String  GRIDNAME    = "Grid";
// типы значений в колонках таблицы
private Class<?>[] column_classes = {
                        String.class, Integer.class,
                        Double.class, Double.class};
// наименование колонок таблицы
private String [] column_names = {"name", "quantity",
                                  "price", "cost"};
private int[]     column_width = {220, 80, 90, 90};
// выравнивание значений в ячейках таблицы
private Integer[] column_align = {
                        JLabel.LEFT, JLabel.RIGHT,
                        JLabel.RIGHT,JLabel.RIGHT};

private String RSC = "properties/properties";

Конструктор класса

Конструктор класса, листинг которого представлен ниже, не изменился. Сначала вызывается конструктор базового класса (суперкласса), после этого в переменную cparams загружаются ранее сохраненные значения регулируемых настроек интерфейса методом базового класса readComponentParams().

public JPanelForm(final JPanelActivator activator, 
                  final Locale locale) 
{
    super(activator, locale);
    readComponentParams();
}

Создание таблицы

Создание таблицы выполняется методом createGrid(). Сначала создается объект grid, у таблицы которого определяется наименование GRIDNAME, после чего восстанавливаются размеры колонок. Для получения описания размеров колонок таблицы (объект ComponentParams) используется родительский метод extractComponentParams с параметрами наименования класса и наименования объекта. Примеры использования Grid приведены в разделе описания библиотеки интерфейсных компонентов base-gui.

Листинг
private void createGrid() {
    // Создание таблицы
    grid = new Grid(column_classes, column_names);
    // Определение наименования таблицы
    grid.getTable().setName(GRIDNAME);
    // Настройка таблицы
    grid.setColumnsWidth     (column_width);
    grid.setColumnsAlign     (column_align);
    grid.setReorderingAllowed(false       );

    // Определение размеров колонок
    if (cparams.size() > 0) {
        ComponentParams cp;
        String          cls;
        cls = JTable.class.getSimpleName();
        cp = extractComponentParams(cls, GRIDNAME);
        if (cp != null) {
            String columns = cp.getColumns();
            String[] cols = columns.split(SEMICOLON);
            int cnt = grid.getTable().getColumnCount();
            if (cnt == cols.length) {
                int[] cw = new int[cols.length];
                try {
                    for (int i=0; i < cols.length; i++)
                        cw[i] = Integer.valueOf(cols[i]);
                    grid.setColumnsWidth(cw);
                } catch (Exception e) {}
            }
        }
    }
}

Создание интерфейса

Для создания интерфейсной панели используются три метода : createGUI(Container), createSplitPaneHorizontal(), createSplitPaneVertical(). Метод createGUI(Container) вызывается активатором бандла после того, как он «по подписке» получает от главного фрейма сообщение с контейнером (Container). В методе сначала выполняется обращение к суперклассу для размещения созданной панели в контейнере фрейма. После этого формируется интерфейс : определяются внутренние границы панели, создаются интерфейсные компоненты и размещаются на панели. Вызовом метода changeLocale(Locale) локализуются заголовки колонок таблицы.

Листинг
public void createGUI(Container container)
{
    super.createGUI(container);

    this.setVisible(false);
    Border border;
    border = BorderFactory.createEmptyBorder(2,2,2,2);
    this.setBorder (border);

    createGrid();
    createSplitPaneHorizontal();
    createSplitPaneVertical  ();

    this.add(split_h, BorderLayout.CENTER);
    ((JPanel)split_h.getRightComponent())
                    .add(split_v, BorderLayout.CENTER);
    changeLocale (locale);
    this.setVisible(true);
}
//---------------------------------------------------------
private void createSplitPaneHorizontal()
{
    split_h = new JSplitPane();
    split_h.setName(SPLITPANE_H);

    split_h.setOneTouchExpandable(false);
    split_h.setOrientation(JSplitPane.HORIZONTAL_SPLIT);

    if (cparams.size() == 0)
        split_h.setDividerLocation(DIVIDER_H);
    else {
        ComponentParams cp;
        String          cls;
        cls = JSplitPane.class.getSimpleName();
        cp = extractComponentParams(cls, SPLITPANE_H);
        if (cp != null)
            split_h.setDividerLocation(cp.getLocation());
        else
            split_h.setDividerLocation(DIVIDER_H);
    }
    JPanel pnlRight = new JPanel();

    pnlRight.setLayout(new BorderLayout());

    split_h.setLeftComponent (grid.asWidget());
    split_h.setRightComponent(pnlRight);
}
//---------------------------------------------------------
private void createSplitPaneVertical()
{
    split_v = new JSplitPane();
    split_v.setName(SPLITPANE_V);

    split_v.setOneTouchExpandable(false);
    split_v.setOrientation(JSplitPane.VERTICAL_SPLIT);		

    if (cparams.size() == 0)
        split_v.setDividerLocation(DIVIDER_V);
    else {
        ComponentParams cp;
        String          cls;
        cls = JSplitPane.class.getSimpleName();
        cp = extractComponentParams(cls, SPLITPANE_V);
        if (cp != null)
            split_v.setDividerLocation(cp.getLocation());
        else
        split_v.setDividerLocation(DIVIDER_V);
    }
    JPanel pnlTop    = new JPanel();
    JPanel pnlBottom = new JPanel();

    pnlTop   .setBackground(Color.blue );
    pnlBottom.setBackground(Color.green);

    split_v.setTopComponent   (pnlTop   );
    split_v.setBottomComponent(pnlBottom);		
}

Локализация интерфейса

Локализация интерфейса, а в нашем модуле только колонок таблицы, выполняется методом changeLocale(Locale). Этот метод вызывается при создании таблицы. Кроме этого, метод может быть вызван активатором после получения соответствующего сообщения об изменении в приложении текущего языка локализации.

Метод changeLocale читает локализованные свойства модуля методом loadProperties (path, locale) и вызывает соответствующий метод объекта Grid.loadProperties(Properties) для определения заголовков колонок.

Ресурсные файлы модуля должны включать соответствующие описания свойств колонок, определенные в массиве column_name.

public void changeLocale (Locale locale)
{
    this.locale = locale;
    Properties props = loadProperties(RSC,locale);
    grid.setLocale(props);
}

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

Конфигурация приложения

В конфигурацию приложения включим исходный бандл templ-jpanel, вновь созданный бандл templ-jpanela и модуль определения языка локализации form-locale.

Листинг configuration/bundles.ini

Список используемых в приложении бандлов определяем в файле configuration/bundles.ini.

bundles=org.apache.felix.eventadmin-1.4.8.jar@start, \
org.apache.felix.log-1.0.1.jar@start, \
util-resources-1.0.0.jar@start, \
util-logger-1.0.0.jar@start, \
base-gui-1.0.1.jar, \
base-jframe-1.0.0.jar, \
base-jpanel-1.0.0.jar, \
base-jdialog-1.0.0.jar, \
gui-menu-1.0.0.jar, \
gui-toolbar-1.0.0.jar, \
templ-jpanel-1.0.0.jar, \
templ-jpanela-1.0.0.jar, \
form-locale-1.0.0.jar, \
templ-jframe-1.0.0.jar@main

Листинг configuration/toolbar.xml

В файле configuration/toolbar.xml определим структуру панели инструментов и свяжем кнопки с вызываемыми при их нажатии бандлами.

Листинг
<?xml version="1.0" encoding="UTF-8"?>
<root name="root" rollover="true" borderpainted="true">
   <toolbar>
      <item name="toolbar.jpanel1" type="button" 
         image="configuration/resources/images/database.png"
         text="toolbar.jpanel1" textposition="bottom"
         width="96" height="64" 
         groupId="org.jabricks.templates"
         artifactId="templ-jpanela" version="1.0.0" />
      <item name="toolbar.jpanel2" type="button"
         image="configuration/resources/images/database.png"
         text="toolbar.jpanel2" textposition="bottom"
         width="96" height="64" 
         groupId="org.jabricks.templates"
         artifactId="templ-jpanel" version="1.0.0" />
    </toolbar>
    <toolbar>
      <item name="toolbar.settings" type="button"
         image="configuration/resources/images/gear.png"
         text="toolbar.settings" textposition="bottom" 
         width="96" height="64" 
         groupId="org.jabricks.locale"
         artifactId="form-locale" version="1.0.0" />
      <item name="toolbar.exit" type="button"
         image="configuration/resources/images/exit.png"
         text="toolbar.exit" textposition="bottom"
         width="96" height="64" />
    </toolbar>
</root>

Старт приложения

На следующем скриншоте представлен интерфейс приложения после старта модуля templ-jpanela, открытии окна смены языка локализации и перехода на английский язык.

Теперь Вы можете изменять регулируемые настройки интерфейса (размеры колонок таблицы, положения сплитеров), открывать другую панель и проделывать те же действия. После повторного открытия панели с измененными настройками Вы должны увидеть «последнее» состояние интерфейса модуля перед остановкой. Таким образом, модуль запоминает регулируемые настройки и восстанавливает их при очередном старте.

Помните, что смена панелей сопровождается остановкой бандла, т.е. переводом бандла в состояние RESOLVED. При очередном старте модуля нажатием на кнопку панели инструментов, т.е. переводе модуля в состояние STARTED, выполняется вызов метода активатора start, и модуль по-новому формирует свою интерфейсную панель.

Связанные страницы

Список уроков
Предыдующий, 12-й урок
Следующий, 14-й урок

Скачивание файлов

Необходимые бандлы, файлы конфигурации и файл описания инсталлируемых бандлов собраны и упакованы в один архивный файл configuration.lesson13.zip (400 Кб).

Скачайте и «разверните» архив configuration.lesson13.zip, перенесите файлы в структуру, представленную на странице описания платформы JaBricks.

Используемый в уроке бандл templ-jpanel можно скачать на странице описания templ-jpanel. Бандл templ-jpanela в виде проекта IDE Eclipse можно скачать здесь.

  Рейтинг@Mail.ru