Công nghệ Java - Tạo một ngôn ngữ mô tả UI XML
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ácthành phần GUI
được mô tả đến các quy tắc nghiệp vụ vào lúc chạy.
" 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
File đính kèm:
- Công nghệ Java - Tạo một ngôn ngữ mô tả UI XML.pdf