qiyadeng

          專注于Java示例及教程
          posts - 84, comments - 152, trackbacks - 0, articles - 34

          使用Swing設計向導

          Posted on 2008-07-26 16:46 qiyadeng 閱讀(1907) 評論(2)  編輯  收藏

          向導在今天的桌面應用中非常常用。向導應該是個什么樣子呢?相信你應該很清楚,因為你使用過很多的向導。也許你使用過一些安裝程序向導或是一些程序的配置向導。這篇文章,我們會創建一個簡單的向導框架。

          一個向導包括很多Panel,每個Panel里面包含用戶的配置組件或是文本域或是選擇框等。用戶點擊”Next”或是”Back”按鈕,在各個Panel之間切換,輸入需要的信息。注意的是,當最后一個Panel是”Next”按鈕要變成”Finish”按鈕,并且再次按下的時候向導關閉。在向導關閉的時,發起向導的類要得到向導Panel中所有的數據。在任何情況下,用戶可以點擊”Cancel”按鈕關閉向導并丟棄前面所填的所有數據。

          看上去很簡單是嗎?對的,但是有些設計細節我們需要考慮。

          第一,向導中的每個Panel不是都需要訪問的,換句話說,如果向導包含1到5個Panel,點擊”Next”按鈕可以從第一個Panel依次到第五個Panel,但是有時候可能由于用戶的選項直接從第一個Panel跳到第五個Panel. 而且還有的情況是,假設向導中需要連接到遠程服務器或是遠程數據庫,如果連接不上的,那么就不能到達下一個Panel。這樣向導中的Panel就像是樹形,你從樹的根開始,通過不同的分支到達葉子節點,這時”Next”按鈕變成”Finish”按鈕。

          第二,有些時候Next按鈕和Back按鈕需要禁用。比如,第一個Panel出現的時候,back按鈕應該禁用,因為沒有上一個Panel。另外,當有些值必須輸入的時候,沒有輸入的情況下Panel中的Next按鈕應該為禁用。

          第三,輸入的數據需要一直保持到用戶完成向導或是取消。因為當用戶點擊Back按鈕會到上一個Panel時,上一個Panel填寫的數據應該能夠保持,并且再次使用Next按鈕時,本Panel中的數據也應該保持。

          有了這些設計細節,我們可以考慮設計自己的向導了。我們先規劃下我們將要完成的一些類。

          Wizard-這個類包含模型(model)和控制器(controller),其主要是一個對話框(JDialog),并且包含有Next,Back和Cancel按鈕。還有一個使用CardLayout布局管理的大組件,可以把各個Panel顯示在上面。想下圖的樣子:

          clip_image002

          Java.awt.Componet的子類,這個類一般是繼承了java.awt.Componet,通常是一個javax.swing.JPanel.這個類是用于顯示在wizard類中的大組件位置。下圖是其中一個Panel。

          clip_image004

          WizardPanelDescriptor-這第三個類用于關聯wizard和panel。這個需要類用戶繼承,并用于標識Panel.這個類指定了訪問下一個和前一個Panel的規則,并且在Panel的顯示前,現實中,和顯示后執行相應的動作。

          Wizard

          首先我們需要創建一個用于顯示向導對話框本身,它包含有三個按鈕Back,Next,Cancel.一般這些按鈕是按照從左到右的順序分布的,另外Cancel按鈕要離其他的兩個按鈕遠一點,這樣防止用戶不小心點擊到Cancel按鈕。接下來,就用需要一個布局,可以在同一個區域顯示各個Panel,在AWT中有CardLayout布局。

          在這個設計中,我們使用一個簡單的方法來檢測我們的數據。下面我們看看Wizard類:

          Public Class Wizard{

          private WizardModel wizardModel;

          private WizardController wizardController;

          private JDialog wizardDialog;

          private JPanel cardPanel;

          private CardLayout cardLayout;

          private JButton backButton;

          private JButton nextButton;

          private JButton cancelButton;

          private MainFrame mainFrame;

          private int returnCode;

          public Wizard(MainFrame owner) {

          this.mainFrame = owner;

          wizardModel = new WizardModel();

          wizardDialog = new JDialog(owner);

          Point np = owner.getLocation();

          wizardDialog.setLocation(np);

          initComponents();

          }

          }

          注意到initComponents()方法,這個方法是用于布置界面中的組件和按鈕的,并且把按鈕事件關聯到控制器中。

          private void initComponents() {

          JPanel buttonPanel = new JPanel();

          Box buttonBox = new Box(BoxLayout.X_AXIS);

          cardPanel = new JPanel();

          cardPanel.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));

          cardLayout = new CardLayout();

          cardPanel.setLayout(cardLayout);

          backButton = new JButton();

          nextButton = new JButton();

          cancelButton = new JButton();

          backButton.setActionCommand(BACK_BUTTON_ACTION_COMMAND);

          nextButton.setActionCommand(NEXT_BUTTON_ACTION_COMMAND);

          cancelButton.setActionCommand(CANCEL_BUTTON_ACTION_COMMAND);

          buttonPanel.setLayout(new BorderLayout());

          buttonPanel.add(separator, BorderLayout.NORTH);

          buttonBox.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));

          buttonBox.add(backButton);

          buttonBox.add(Box.createHorizontalStrut(10));

          buttonBox.add(nextButton);

          buttonBox.add(Box.createHorizontalStrut(30));

          buttonBox.add(cancelButton);

          buttonPanel.add(buttonBox, java.awt.BorderLayout.EAST);

          wizardDialog.getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH);

          wizardDialog.getContentPane().add(cardPanel, java.awt.BorderLayout.CENTER);

          }

          接下來,我們要把Componet Panel注冊到Wizard中。Wzard中使用registerWizardPanel()方法。我們知道CardLayout布局中包含有next(),previous()這樣的方法來回翻動Panel,然而我們需要的是樹形結構,而不是線性的結構,因此我們需要使用標識符來標識各個Panel對象。

          public void registerWizardPanel(Object id, WizardPanelDescriptor panel) {

          cardPanel.add(panel.getPanelComponent(), id);

          wizardMdel.registerPanel(id, panel);

          }

          最后wizard中是用setCurrentPanel(Object id)來設置,Wizard初始化時顯示的第一個Panel。剩下的就是一些事件處理,比較簡單。Wizard中大量的使用Wizard來保存數據,并使用WizardController來處理對話框本身的事件。

          WizardPanelDescriptor

          注冊到Wizard的每個方法都需要繼承WizardPanelDescriptor類,這個類包含一些方法可以把組件集成到Wizard向導中。以下的四個方法:是訪問組件和組件對象標識符的方法。

          public final void setPanelComponent(Component panel) {

          targetPanel = panel;

          }

          public final Component getPanelComponent() {

          return targetPanel;

          }

          public final Object getPanelDescriptorIdentifier() {

          return panelIdentifier;

          }

          public final void setPanelDescriptorIdentifier(Object id) {

          panelIdentifier = id;

          }

          下面是比較重要的一部分,就是每個繼承類都需要改寫的一些方法。包括控制Next,Back之后顯示的Panel。在每次Panel初始化的時候都會執行Next這個方法,當Next和Back方法中返回的是null之的時候Next和Back按鈕被禁用。因此,Next方法不能用于數據的校驗,需要有另外的方法,在這里使用了一個Validator方法,當然如果數據需要校驗,也需要在WizardPanelDescriptor子類中進行覆蓋。具體如下:

          public Object getNextPanelDescriptor() {

          return null;

          }

          public Object getBackPanelDescriptor() {

          return null;

          }

          public boolean validator(){

          return true;

          }

          另外提供三個方法,用于控制Panel顯示前,顯示中和顯示后的事件。

          public void aboutToDisplayPanel() {

          }

          public void displayingPanel() {

          }

          public void aboutToHidePanel() {

          }

          WizardPanelDescriptor

          clip_image007

          最后,用上圖來表示Wizard類和其他幾個類之間的關系圖,并展示了兩個實例。

          Feedback

          # re: 使用Swing設計向導  回復  更多評論   

          2008-10-17 12:00 by hb148
          Swing Wizard Framework
          https://wizard-framework.dev.java.net/

          # re: 使用Swing設計向導  回復  更多評論   

          2013-09-11 10:24 by 洛玻
          有該項目的詳細代碼嘛?你能發一份給我嘛?謝謝

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 阿拉尔市| 大埔区| 陇南市| 离岛区| 酒泉市| 澄迈县| 通化市| 宾阳县| 尉犁县| 昌平区| 东明县| 黎平县| 乌兰县| 亚东县| 新和县| 得荣县| 固原市| 萨嘎县| 拉萨市| 龙川县| 上虞市| 河曲县| 米泉市| 水城县| 赤壁市| 普陀区| 灵武市| 罗源县| 泽库县| 商丘市| 墨玉县| 东乡县| 宾阳县| 台湾省| 稷山县| 长治县| 长乐市| 东乡县| 鹿邑县| 巧家县| 南开区|