Tạo một ngôn ngữ mô tả UI XML
Xây dựng UI (giao diện người dùng) và khung làm việc đi kèm trong ngôn ngữ
Java
Arron Ferguson, Giảng viên, British Columbia Institute of Technology
Tóm tắt: Việc viết ra các GUI (giao diện người dùng đồ hoạ) bằng mã chương
trình có thể thường dẫn đến các lựa chọn thiết kế lộn xộn, đến lượt nó lại trở nên
mờ nhạt giữa các logic nghiệp vụ (business logic) và mã UI. Hãy khám phá cách
tạo một bộ thẻ UI XML khai báo với một khung làm việc Java™ đi kèm mà phân
tích cú pháp, xác thực, xây dựng, và cuối cùng là liên kết các thành phần GUI
được mô tả đến các quy tắc nghiệp vụ vào lúc chạy.
61 trang |
Chia sẻ: phuongt97 | Lượt xem: 531 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Bài giảng Tạo một ngôn ngữ mô tả UI XML, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ác vị trí trong lưới. Tất cả các kích thước của các thành phần được
chứa tham chiếu đến độ rộng và độ lớn bao nhiêu ô mà mỗi thành phần nằm trong
lưới. Các định nghĩa của thành phần là có tính mô tả cao ở chỗ chúng định nghĩa
các đặc tính chứ không phải là logic về cách các đặc tính đó đã được sử dụng hoặc
tạo. Một vài điểm thú vị nữa trong tài liệu này là:
Các MenuItem có thể có nhanh chóng các phím nóng (quick keys), chẳng
hạn như Ctrl-X để thoát khỏi ứng dụng.
Window có các hội thoại, nhưng, theo mặc định, các hội thoại này không
nhìn thấy được đến khi nào người dùng gọi ra.
Tất cả các vùng chứa (thí dụ một Panel) phải có các bố trí và phải quy định
số hàng và cột ở bố trí đó.
Liệt kê 8. Trình duyệt Web UI XML
<xui:XUI xmlns:xui=""
xmlns:xsi=""
xsi:schemaLocation=" ../../xui.xsd"
id="">
<xui:Window id="window_0" name="XUI Web Browser" x="200" y="20"
width="800"
height="600" visible="true">
<xui:Panel x="0" y="0" width="1" height="1" id="panel_0" name="main
panel"
idref="window_0">
<xui:HypertextPane x="1" y="0" width="8" height="7" id="hyper_0"
uri="">
<xui:Button x="0" y="0" width="1" height="1" id="button_0" label="Back"
enabled="true" orientation="horizontal">
<xui:Button x="0" y="3" width="1" height="1" id="button_1" label="Home"
enabled="true" orientation="horizontal">
<xui:Button x="0" y="7" width="1" height="1" id="button_2"
label="Forward" enabled="true" orientation="horizontal">
<xui:OpenFileDialog x="10" y="10" width="400" height="300"
id="filedialog_0" idref="window_0" visible="false">
html
htm
<xui:SaveFileDialog x="10" y="10" width="400" height="300"
id="savedialog_0" idref="window_0" visible="false">
html
htm
<xui:CustomDialog x="200" y="200" width="320" height="160"
id="customdialog_1" idref="window_0" name="Exit Purnama Browser"
modal="true" visible="false">
<xui:Panel x="0" y="0" width="1" height="1" id="panel_2"
name="Quit Panel" idref="customdialog_0">
<xui:Label id="label_0" x="1" y="1" width="3" height="1"
justified="center" text="Do you really want to exit?">
<xui:Button x="2" y="1" width="1" height="1" id="button_3"label="Yes"
enabled="true" orientation="horizontal">
<xui:Button x="2" y="3" width="1" height="1" id="button_4" label="No"
enabled="true" orientation="horizontal">
<xui:CustomDialog x="100" y="100" width="300" height="300"
id="customdialog_0" idref="window_0" name="Bookmarks" modal="false"
visible="false">
<xui:Panel x="0" y="0" width="1" height="1" id="panel_1"
name="bookmarks panel" idref="customdialog_0">
<xui:List x="0" y="0" width="1" height="1" id="list_0" enabled="true"
itemSelected="0" scrolling="vertical">
<xui:Menu id="menu_0" idref="menuBar_0" enabled="true"
isPopupMenu="false" isSubMenu="false" label="File">
<xui:MenuItem id="mi_1" idref="menu_0" enabled="true" label="Open
URL"
checked="false">
<xui:MenuItem id="mi_0" idref="menu_0" enabled="true" label="Save"
checked="false">
<xui:MenuItem id="mi_2" idref="menu_0" enabled="true" label="Exit"
checked="false">
<xui:Menu id="menu_1" idref="menuBar_0" enabled="true"
isPopupMenu="false" isSubMenu="false" label="Bookmarks">
<xui:MenuItem id="mi_3" idref="menu_1" enabled="true"
label="Add Bookmark" checked="false">
<xui:MenuItem id="mi_4" idref="menu_0" enabled="true"
label="Manage Bookmarks" checked="false">
<xui:Menu id="menu_2" idref="hyper_0" enabled="true"
isPopupMenu="true"
isSubMenu="false" label="">
<xui:MenuItem id="mi_5" idref="menu_2" enabled="true"
label="Save As ..." checked="false">
<xui:MenuItem id="mi_6" idref="menu_2" enabled="true" label="Previous"
checked="false">
<xui:MenuItem id="mi_7" idref="menu_2" enabled="true" label="Next"
checked="false">
<xui:MenuItem id="mi_8" idref="menu_2" enabled="true" label="Home"
checked="false">
<xui:MenuItem id="mi_9" idref="menu_2" enabled="true"
label="Bookmark"
checked="false">
Dĩ nhiên, không có trình duyệt nào có giá trị mà không có sự tương tác người
dùng, nó ở bên cạnh.
Logic mô hình mã Java trình duyệt Web
Trong Liệt kê 8, phần tử Resource chứa tên của lớp mà hoạt động như một điểm
vào mô hình ứng dụng. Tên được cho là BrowserModel và như vậy, trên phần Java
còn lại, liên tục, tên của lớp được biên dịch phải phù hợp. Nó gồm không gian tên
mà, trong trường hợp này là không gian tên mặc định.
Bất kỳ lớp nào do đó cũng có thể hoạt động như điểm vào phần mô hình của ứng
dụng cho đến khi tên của nó cũng giống như giá trị thuộc tính class của phần tử
Resource. Để tương tác người dùng được buộc chính xác vào thời gian chạy, lớp
đang thực hiện phải theo một số nguyên tắc sau:
Có một phương thức với ký hiệu sau đây: public void init(XUI document).
Thực hiện giao diện xử lý sự kiện phù hợp để nghe các sự kiện (chẳng hạn
như ActionModel để cài đặt các XUIButton).
Sử dụng các giá trị id của các phần tử XML để tham khảo các thành phần
GUI. (Việc này có thể tực hiện bằng cách sử dụng một vài phương thức
khác nhau tìm thấy trong lớp XUI.)
Tự bổ sung như một thính giả vào thành phần thích hợp. Tất cả các thành
phần tạo sự kiện trong khung làm việc này, chẳng hạn như cài đặt lớp
XUIButton thực hiện XUIEventSource, và do đó, tạo các sự kiện UI.
Trong Liệt kê 9, lớp BrowserModel thực hiện khởi tạo của nó trong phương thức
init. Việc này gồm việc tham chiếu đến các thành phần qua các giá trị id, tạo các
mục của trình đơn chứa các đánh dấu URL Web, và tự bổ sung như một thính giả
vào thành các phần thông qua phương thức addEventListener. BrowserModel có
thể tự bổ sung như một thính giả vì nó là một XUIModel (ActionModel là một
kiểu con của XUIModel). Nó cũng đáng được đề cập là lớp
XUIComponentFactory đưa ra nhiều phương thức để tạo các thành phần XUI.
Liệt kê 9. Liệt kê mã bộ phận: khởi tạo
...
import org.purnamaproject.xui.binding.ActionModel;
...
public class BrowserModel implements ActionModel, TextModel, WindowModel,
ListActionModel {
...
private XUI xui;
...
public void init(XUI document) {
xui = document;
...
bookmarksList = (XUIList)xui.getXUIComponent("list_0");
homeButton = (XUIButton)xui.getXUIComponent("button_1");
...
List bookmarks = bookmarksList.getItems();
for(int i = 0; i < bookmarks.size(); i++) {
String url = (String)bookmarks.get(i);
XUIMenuItem aMenuItem = XUIComponentFactory.makeMenuItem(url);
bookmarksMenu.addMenuItem(aMenuItem);
linkModel.addSource(aMenuItem);
aMenuItem.addEventListener(linkModel);
}
...
homeButton.addEventListener(this);
...
}
...
}
Đi sâu hơn nữa, Liệt kê 10 trình bày mã xử lý sự kiện cho các thành phần khác
nhau. Ví dụ:
openMenuItem sẽ làm cho một fileDialog xuất hiện (một hội thoại theo
kiểu để mở một trang Web được lưu cục bộ).
homeButton và popuphomeMenuItem (nhấn chuột phải để truy cập trong
Window) cả hai thành phần gọi ra phương thức doHome cho phép điều
khiển trực tiếp trình duyệt đến giá trị thuộc tính uri của phần tử
HypertextPane (từ Liệt kê 8).
fileDialog sẽ nạp một tệp mới và sau đó tăng biến index mà được sử dụng
bởi queue của ứng dụng để theo dõi các trang Web được vào trước đó.
Liệt kê 10. Liệt kê mã bộ phận: Xử lý sự kiện
public void action(XUIComponent component)
{
if(component == openMenuItem) {
fileDialog.setVisible(true);
} else if(component == homeButton || component == popuphomeMenuItem)
{
doHome();
} else if(component == prevButton || component == popupprevMenuItem) {
doPrevious();
} else if(component == nextButton || component == popupnextMenuItem) {
doNext();
} else if(component == fileDialog) {
if(fileDialog.getSelectedFile() !=null)
hyperTextPane.setURL(fileDialog.getSelectedFileAsURL());
index++;
if(index != queue.size()) {
nextButton.setEnabled(false);
popupnextMenuItem.setEnabled(false);
for(int i = index; i < queue.size(); i++) {
queue.remove(i);
}
}
queue.add(hyperTextPane.getURL());
prevButton.setEnabled(true);
popupprevMenuItem.setEnabled(true);
} else if(component == saveDialog) {
try {
FileOutputStream fos = new
FileOutputStream(saveDialog.getSelectedFile());
hyperTextPane.getDocument().writeTo(fos);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
} else if(component == popupsaveasMenuItem || component ==
saveMenuItem) {
saveDialog.setVisible(true);
} else if(component == popupbookmarkMenuItem || component ==
bookmarkMenuItem) {
doBookmark(hyperTextPane.getURL());
} else if(component == notDontExit) {
exitDialog.setVisible(false);
browserWindow.setVisible(true);
} else if(component == yesExit) {
System.exit(0);
} else if(component == exitMenuItem) {
exitDialog.setVisible(true);
} else if(component == manageBookmarksMenuItem) {
bookmarksDialog.setVisible(true);
}
}
Ứng dụng cuối cùng (trong Hình 2) trình bày một trình duyệt Web cơ sở cho phép
bạn hiển thị các trang cục bộ, các trang dựa trên web, và các trang Web được vào
trước đó, cộng với khả năng quản lý các đánh dấu.
Hình 2. Ảnh chụp màn hình của trình duyệt Web
Bạn sẽ tìm thấy một vài mẫu ứng dụng khác trong mục Tải về cho bài này.
Các hiểu biết và thách thức
Giải pháp này hứng thú, cách tiếp cận khá lý tưởng: các vấn đề về an toàn trong
khung làm việc này đã được bỏ qua. Gọi lại các API nạp vô hại một tệp JAR từ bất
kỳ URI nào. Gọi lại phần tử Resource hiển thị trong Liệt kê 8. Kiểu này theo nghĩa
đen là anyURI. Nó có nghĩa là tệp cục bộ, tệp trên mạng, tệp trên Internet. Bất cứ
đâu. Một ứng dụng có nên tin cậy vào các quy tắc nghiệp vụ ở bất kỳ nơi nào
không? Rõ ràng là bạn muốn xem xét một số loại hình mẫu an ninh để hạn chế
việc nạp các tài nguyên không tin cậy. Một cách để nhằm vào vấn đề này là hạn
chế các URI để tham chiếu một bảng tra cứu. Giải pháp khác (sạch sẽ hơn) là sử
dụng các giấy chứng nhận kiểu số.
Cuối cùng, cân nhắc việc nạp của các định dạng XML khác theo định dạng UI
XML mô tả này. Lược đồ XML hỗ trợ việc này tùy theo việc sử dụng các không
gian tên được yêu cầu. Thí dụ bạn có thể nhúng vào một định dạng XML riêng rẽ
để trình bày đồ thị véc-tơ có thể phóng to thu nhỏ được (scalable vector graphics)
trong tài liệu XML.
Kết luận
Bài viết này đề cập đến định nghĩa một ngôn ngữ UI XML mô tả và nó trông như
thế nào. Nó giới thiệu một khung làm việc Java đi kèm cũng như mẫu ứng dụng —
trình duyệt Web. Cuối cùng, nó đưa ra các vấn đề an toàn và các mối quan tâm.
Việc tạo các UI XML mô tả chắc chắn là không mới. Tuy nhiên nó là một lĩnh vực
phát triển phần mềm đang trưởng thành và trở nên phổ biến hơn. Một bổ sung nữa
là việc tạo các UI XML mô tả giúp thúc đẩy việc tái sử dụng phần mềm và tính
mô-đun.
Tải về
Mô tả Tên Kích thước Phương thức tải
XUI XSD and Java API for article1 xui.zip 30KB HTTP
Thông tin về phương thức tải
Ghi chú
1. Tệp.zip này chứa toàn bộ mã nguồn cho dự án này, tệp dựng Apache Ant,
lược đồ XML, các thí dụ, và các thư viện bên thứ ba (các JAR) mà bài viết
này tham khảo và sử dụng.
Mục lục
Giới thiệu
XML mô tả
Hỗ trợ khung làm việc Java
Khung làm việc hoạt động
Các hiểu biết và thách thức
Kết luận
Các file đính kèm theo tài liệu này:
- tao_mot_ngon_ngu_mo_ta_ui_xml.pdf