Статьи

Расширенное руководство по SmartGWT, часть 2

Это вторая часть моего руководства по быстрой разработке пользовательского интерфейса с помощью SmartGWT . В первой части урока мы создали базовую схему интерфейса и добавили несколько основных компонентов. Пришло время заняться этим и использовать всю мощь SmartGWT .

Прежде чем мы продолжим, давайте вспомним, как выглядит созданный нами интерфейс:

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

Нам придется пересмотреть некоторые из существующих классов, чтобы определить дополнительные функционально для них. Давайте начнем с класса NavigationArea. Там мы использовали класс SectionStack для создания аккордеона. Тем не менее, каждый из разделов стека содержал просто метку. Мы собираемся добавить что-то более полезное, мудрое навигация. Мы будем использовать дерево для панели навигации, где каждый лист будет по существу представлять действие. Для этого мы собираемся расширить класс TreeGrid , определив конкретные характеристики для нашей реализации. Следовательно, вот класс «NavigationTreeGrid»:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.javacodegeeks.smartgwt.appui.client.ui.widgets;
 
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.TreeModelType;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeNode;
import com.smartgwt.client.widgets.tree.events.NodeClickEvent;
import com.smartgwt.client.widgets.tree.events.NodeClickHandler;
 
public class NavigationTreeGrid extends TreeGrid {
     
    public NavigationTreeGrid() {
         
        setNodeIcon("arrow_down.png"); 
        setFolderIcon("arrow_up.png"); 
        setShowOpenIcons(false);
        setShowDropIcons(false);
        setShowSelectedStyle(true); 
        setShowPartialSelection(true); 
        setCascadeSelection(false);
        setCanSort(false);
        setShowConnectors(true);
        setShowHeader(false);
        setLoadDataOnDemand(false);
        setSelectionType(SelectionStyle.SINGLE);
         
        Tree data = new Tree();
        data.setModelType(TreeModelType.CHILDREN);
         
        data.setRoot(
                new TreeNode("root",
                        new TreeNode("File",
                                new TreeNode("FileChild")),
                        new TreeNode("Edit",
                                new TreeNode("EditChild",
                                        new TreeNode("EditGrandChild"))),
                        new TreeNode("Window"))
        );
 
        setData(data);
         
        addNodeClickHandler(new NodeClickHandler() {           
            @Override
            public void onNodeClick(NodeClickEvent event) {
                String name = event.getNode().getName();
                SC.say("Node Clicked: " + name);
            }
        });
         
    }
 
}

Сначала мы определим некоторые атрибуты для нашего дерева, более важное из которых:

  • setShowConnectors : Определяет, должны ли отображаться соединительные линии, иллюстрируя иерархию дерева.
  • setClosedIconSuffix : этот суффикс добавляется к предоставленному имени значка и по умолчанию «закрыт», поэтому вам лучше использовать пользовательское значение и переопределить его.
  • setSelectionType : Определяет поведение щелкающего выбора сетки, т.е. можно ли выбрать несколько элементов в данный момент времени.

Кроме того, методы setNodeIcon и setFolderIcon используются для установки соответствующего значка для каждого узла в зависимости от того, является ли он родительским или конечным узлом.

Затем мы создаем экземпляр Tree , который по сути является моделью данных, представляющей набор объектов, связанных в иерархию. Каждый узел дерева реализован с помощью класса TreeNode, и мы устанавливаем корневой узел с помощью метода setRoot . Обратите внимание, что каждый узел может быть построен с использованием имени и массива объектов, таким образом, используя рекурсивный подход, мы можем создать все дерево в одну строку. Затем мы передаем TreeGrid данные из нашего дерева, используя метод setData . Наконец, мы регистрируем обработчик для событий щелчка узла и реализуем интерфейс NodeClickHandler , создавая всплывающее окно с именем узла.

Чтобы использовать наше вновь созданное дерево, мы возвращаемся к нашему классу «NavigationArea» и изменяем следующие строки:

1
2
3
4
5
6
7
...
SectionStackSection section1 = new SectionStackSection("Section 1");
section1.setExpanded(true);
final NavigationTreeGrid navigationTreeGrid = new NavigationTreeGrid();
navigationTreeGrid.setHeight100();
section1.addItem(navigationTreeGrid);
...

Давайте посмотрим, как это меняет наш интерфейс в области навигации:

При щелчке по одному из узлов появляется окно с соответствующим именем:

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

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

Теперь мы собираемся вернуться к классу «MainArea» и добавить в него три разных панели вкладок. Первый будет содержать произвольные элементы HTML, ко второму будет прикреплено меню, а третий будет содержать пользовательский вертикальный аккордеон. Давайте посмотрим, как это делается:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.javacodegeeks.smartgwt.appui.client.ui;
 
import com.javacodegeeks.smartgwt.appui.client.ui.widgets.CustomAccordion;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.Side;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartgwt.client.widgets.toolbar.ToolStripMenuButton;
 
public class MainArea extends VLayout {
 
    final TabSet topTabSet = new TabSet();
 
    public MainArea() {
         
        super();
        this.setOverflow(Overflow.HIDDEN);
         
        topTabSet.setTabBarPosition(Side.TOP); 
        topTabSet.setTabBarAlign(Side.LEFT);
         
        ToolStrip toolStrip = new ToolStrip();
        toolStrip.setWidth100();
         
        ToolStripButton iconButton = new ToolStripButton();
        iconButton.setTitle("MyButton");
        toolStrip.addButton(iconButton);       
         
        MenuItem[] itemArray = new MenuItem[4];
 
        itemArray[0] = new MenuItem("MenuItem1");
        Menu menu1 = new Menu();
        menu1.setData(new MenuItem("SubMenuItem11"), new MenuItem("SubMenuItem12"));
        itemArray[0].setSubmenu(menu1);
 
        itemArray[1] = new MenuItem("MenuItem2");
        Menu menu2 = new Menu();
        menu2.setData(new MenuItem("SubMenuItem21"), new MenuItem("SubMenuItem22"));
        itemArray[1].setSubmenu(menu2);
         
        Menu parentMenu = new Menu(); 
        parentMenu.setCanSelectParentItems(true); 
        parentMenu.setData(itemArray);
         
        ToolStripMenuButton menuButton =
             new ToolStripMenuButton("Menu", parentMenu);
        toolStrip.addMenuButton(menuButton);
         
        VLayout hlayout = new VLayout();
        hlayout.addMember(toolStrip);
        hlayout.addMember(new HTMLFlow("Tab3"));
         
        addTabToTopTabset("Tab1", new HTMLFlow("Tab1"), true);
        addTabToTopTabset("Tab2", hlayout, true);       
        addTabToTopTabset("Tab3", new CustomAccordion(), true);
         
        this.addMember(topTabSet);
         
    }
     
    private void addTabToTopTabset(String title, Canvas pane, boolean closable) {
        Tab tab = createTab(title, pane, closable);
        topTabSet.addTab(tab);
        topTabSet.selectTab(tab);
    }
     
    private Tab createTab(String title, Canvas pane, boolean closable) {
        Tab tab = new Tab(title);
        tab.setCanClose(closable);
        tab.setPane(pane);
        return tab;
    }
     
}

Вещи, чтобы отметить здесь. Во-первых, мы используем ToolStrip , который на самом деле является полосой, к которой можно прикрепить различные виджеты (кнопки, меню и т. Д.). Определенные классы могут быть добавлены только на панель инструментов. Например, если вы хотите добавить кнопку, вам нужно создать экземпляр ToolStripButton . Точно так же к нему можно прикрепить целое меню . После создания экземпляра класса меню мы используем класс MenuItem для добавления к нему компонентов. Наконец, меню инкапсулируется в ToolStripMenuButton, а затем, наконец, добавляется в панель инструментов.

Что касается вкладок, API очень прост. Мы используем метод addTab класса TabSet для добавления новых вкладок и метод selectTab для выбора конкретной вкладки. На самой вкладке мы можем использовать метод setPane, чтобы указать панель, связанную с конкретной вкладкой. Чтобы определить, должна ли вкладка обеспечивать значок для закрытия самой себя, используется метод setCanClose .

Наконец, давайте посмотрим класс «CustomAccordion», который в основном представляет собой вертикальный аккордеон.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.javacodegeeks.smartgwt.appui.client.ui.widgets;
 
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
 
public class CustomAccordion extends SectionStack {
  
 public CustomAccordion() {
   
     this.setWidth100();
     this.setVisibilityMode(VisibilityMode.MUTEX);
     this.setShowExpandControls(false);
     this.setAnimateSections(true);
      
     SectionStackSection section1 = new SectionStackSection("TabSection1");
     section1.setExpanded(true);
     HTMLFlow htmlFlow1 = new HTMLFlow(); 
     htmlFlow1.setOverflow(Overflow.AUTO); 
     htmlFlow1.setPadding(10); 
     htmlFlow1.setContents("TabSection1");    
     section1.addItem(htmlFlow1);
      
     SectionStackSection section2 = new SectionStackSection("TabSection2"); 
     section2.setExpanded(false); 
     HTMLFlow htmlFlow2 = new HTMLFlow(); 
     htmlFlow2.setOverflow(Overflow.AUTO); 
     htmlFlow2.setPadding(10); 
     htmlFlow2.setContents("TabSection2"); 
     section2.addItem(htmlFlow2);
      
     SectionStackSection section3 = new SectionStackSection("TabSection3"); 
     section3.setExpanded(false);
     HTMLFlow htmlFlow3 = new HTMLFlow(); 
     htmlFlow3.setOverflow(Overflow.AUTO); 
     htmlFlow3.setPadding(10); 
     htmlFlow3.setContents("TabSection3");   
     section3.addItem(htmlFlow3);
      
     this.addSection(section1); 
     this.addSection(section2); 
     this.addSection(section3);
   
 }
 
}

Ничего из того, что мы не видели раньше, мы используем класс SectionStack для создания аккордеона и добавления к нему SectionStackSection . Класс HTMLFlow используется для отображения содержимого HTML, которое должно расширяться до его естественного размера без прокрутки.

Запустите конфигурацию Eclipse и наведите браузер на указанный URL:

http://127.0.0.1:8888/AwesomeSmartGWTUIProject.html?gwt.codesvr=127.0.0.1:9997

Давайте теперь посмотрим, как выглядит каждая вкладка:

* Tab1: очень просто и понятно.

* Tab2: эта вкладка содержит панель инструментов с кнопкой и приложенным к ней меню.

* Tab3: эта вкладка включает в себя вертикальный аккордеон с тремя отдельными секциями.

И вот как выглядит весь пользовательский интерфейс:

Мы подошли к концу этого урока, поэтому давайте вернемся к тому, что мы сделали. Сначала мы создали основной макет пользовательского интерфейса, определив определенные области и добавив соответствующие вложенные макеты. Каждый суб-макет был обработан отдельно. Для области заголовка мы добавили логотип приложения слева и имя пользователя, вошедшего в систему, справа. Для области навигации мы использовали аккордеон, который заключил дерево в одну из его секций. Дерево может иметь произвольное количество детей, внуков и т. Д., Но вы не должны выходить за его пределы. Наконец, для основного макета мы использовали вкладки, чтобы максимально использовать область экрана. Были созданы три предопределенные вкладки, каждая из которых содержит различные виджеты. Обратите внимание, что панель навигации должна быть связана с основной областью. Это может быть достигнуто путем создания новой вкладки всякий раз, когда пользователь нажимает на один из листьев дерева.

Это все, ребята. Вы можете найти здесь окончательный проект Eclipse. Если вам понравилось, не забудьте поделиться! Ура!

Статьи по Теме :