最近要急着用javaswing去设计一个用户帐号创建的向导页面!类似foxmail的!!然后在网上找了一个向导模版!不过高人只给了代码,没附带例子!哎,看了半天也不知道怎么去弄!用了一些java的新技术,求大牛们看看。给点思路把!

解决方案 »

  1.   


    /**
     * 
     */
    package com.gordon.ui.wizard;import java.awt.BorderLayout;
    import java.awt.CardLayout;
    import java.awt.Window;
    import java.awt.event.KeyEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.EnumMap;
    import java.util.Map;import javax.swing.Box;
    import javax.swing.Icon;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSeparator;
    import javax.swing.JTextArea;
    import javax.swing.border.EmptyBorder;import com.gordon.ui.wizard.Card.StepID;/**
     * @author Administrator
     * 
     */
    public final class Wizard extends JDialog implements PropertyChangeListener {

    private static final long serialVersionUID = 847520613043597065L;
    private JPanel cardContentPane; // 每一步的内容面板
    private CardLayout cardLayout;
    private CardHeadPane cardHeadPane; // 每一步的描述给信息
    private NavigationBar buttonPane; private WizardHandler wizardHandler;
    private WizardModel wizardModel; private String wizardTitle;

    public Wizard(Window parent, String title) {
    super(parent);
    wizardTitle = title;
    wizardHandler = new WizardHandler(this);
    wizardModel = new WizardModel();
    wizardModel.addPropertyChangeListener(this); // TODO:增加将对话框放置在主屏幕中间
    // TODO:取消ESC键的响应 // 初始化主框架
    doLayoutUI();
    } private void doLayoutUI() {
    cardContentPane = new JPanel();
    cardLayout = new CardLayout();
    cardContentPane.setLayout(cardLayout);
    cardHeadPane = new CardHeadPane();
    buttonPane = new NavigationBar(wizardHandler); this.setLayout(new BorderLayout());
    this.add(cardHeadPane, BorderLayout.NORTH);
    this.add(cardContentPane, BorderLayout.CENTER);
    this.add(buttonPane, BorderLayout.SOUTH);
    } public void showWizard() {
    Card card = wizardModel.getCardBy(StepID.FirstCard);
    if (null == card || !card.doInitTask()) {
    return;
    } this.setCurrentCard(StepID.FirstCard);
    this.setModal(true);
    this.pack();
    this.setVisible(true);
    } public WizardModel getModel() {
    return this.wizardModel;
    } public void setButtonEnable(EWizardButton buttonE, boolean enable) {
    JButton button = buttonPane.getButtonBy(buttonE);
    if (null != button) {
    button.setEnabled(enable);
    }
    } public void addCard(StepID stepID, Card card) {
    card.setCurrentStepID(stepID);
    cardContentPane.add(card.getCardView(), stepID.name());
    card.setWizard(this);
    wizardModel.addCard(stepID, card);
    } void setCurrentCard(StepID stepID) {
    if (null == stepID) {
    return;
    } wizardModel.setCurrentCard(stepID);
    cardLayout.show(cardContentPane, stepID.name());
    wizardModel.getCurrentCard().showing();
    } public void propertyChange(PropertyChangeEvent evt) {
    if (evt.getPropertyName().equals(
    WizardModel.CURRENT_CARD_IDENTIFIER_PROPERTY)) {
    Card card = wizardModel.getCurrentCard();
    cardHeadPane.update(card.getCardHead());
    String title = wizardTitle + "  " + card.getWizardStep();
    this.setTitle(title);
    if (wizardModel.arrivedFirstCard()) {
    buttonPane.update(EWizardButton.Next, EWizardButton.Cancel,
    EWizardButton.Help);
    } else if (wizardModel.arraivedFinishCard()) {
    buttonPane.update(EWizardButton.Previous, EWizardButton.Finish,
    EWizardButton.Help);
    } else {
    buttonPane.update(EWizardButton.Previous, EWizardButton.Next,
    EWizardButton.Cancel, EWizardButton.Help);
    }
    }
    } /**
     * 按钮枚举
     * 
     * @author Administrator
     */
    enum EWizardButton {
    Previous("PREVIOUS_COMMAND", KeyEvent.VK_P), Next("NEXT_COMMAND",
    KeyEvent.VK_N), Cancel("CANCEL_COMMAND", KeyEvent.VK_C), Finish(
    "FINISH_COMMAND", KeyEvent.VK_F), Help("HELP_COMMAND",
    KeyEvent.VK_H);
           
    private String command; private int memonic;

    private EWizardButton(String command, int memonic) {
    this.command = command;
    this.memonic = memonic;
    } public String getCommand() {
    return command;
    } public int getMemonic() {
    return memonic;
    } public String getText() {
    return this.name();
    } /**
     * 根据按钮的命令码获取对应的枚举
     * 
     * @param command
     *            按钮的命令码
     * @return
     */
    public static EWizardButton getEWizardButtonBy(String command) {
    for (EWizardButton buttonE : EWizardButton.values()) {
    if (buttonE.getCommand().equals(command)) {
    return buttonE;
    }
    } return null;
    } } /**
     * 向导对话框的顶部描述面板的信息封装,包括描述,图标,当前步骤的子标题
     * 
     * 由Card的实现子类返回当前步骤的信息描述
     */
    public static class CardHead {
    public CardHead(String title, String details) {
    this.stepTitle = title;
    this.details = details;
    } public CardHead(String title, String details, Icon icon) {
    this(title, details);
    this.icon = icon;
    } public String getDetails() {
    return details;
    } public Icon getIcon() {
    return icon;
    } public String getTitle() {
    return stepTitle;
    } private String stepTitle;
    private Icon icon;
    private String details;
    } /**
     * 向导对话框的顶部描述面板,信息显示由实现的Card子类返回
     */
    private class CardHeadPane extends JPanel {
    private static final long serialVersionUID = -7173107387328821161L; public CardHeadPane() {
    doLayoutUI();
    } private void doLayoutUI() {
    titleLabel = new JLabel();
    detailsArea = new JTextArea();
    iconLable = new JLabel(); JPanel detailAreaPane = new JPanel(new BorderLayout());
    detailAreaPane.add(titleLabel, BorderLayout.NORTH);
    detailAreaPane.add(detailsArea, BorderLayout.CENTER);
    this.setLayout(new BorderLayout());
    this.add(iconLable, BorderLayout.WEST);
    this.add(detailAreaPane, BorderLayout.CENTER);
    this.add(new JSeparator(), BorderLayout.SOUTH);
    } public void update(CardHead cardHead) {
    titleLabel.setText(cardHead.getTitle());
    iconLable.setIcon(cardHead.getIcon());
    detailsArea.setText(cardHead.getDetails());
    this.revalidate();
    this.repaint();
    } private JLabel titleLabel; private JTextArea detailsArea; private JLabel iconLable;
    } /**
     * 向导底部按钮导航区的面板布局,显示的按钮由当前步骤而决定
     * 
     * 有三种风格: 第一步面板中只有下一步、取消、帮助 最后一步面板只有上一步、完成、帮助、 中间每一步面板包括上一步、下一步、取消、帮助
     * 
     * @author Administrator
     */
    class NavigationBar extends JPanel {
    public NavigationBar(WizardHandler handler) {
    doLayoutUI(handler);
    } private void doLayoutUI(WizardHandler handler) {
    for (EWizardButton wizardButtonE : EWizardButton.values()) {
    JButton button = new JButton(wizardButtonE.getText());
    button.setActionCommand(wizardButtonE.getCommand());
    button.setMnemonic(wizardButtonE.getMemonic());
    button.addActionListener(handler);
    stepBtnPane.put(wizardButtonE, button);
    } buttonPane = Box.createHorizontalBox();
    Box buttonBox = Box.createHorizontalBox();
    buttonBox.add(Box.createHorizontalGlue());
    buttonBox.add(buttonPane);
    buttonBox.setBorder(new EmptyBorder(8, 10, 8, 10)); this.setLayout(new BorderLayout());
    this.add(new JSeparator(), BorderLayout.NORTH);
    this.add(buttonBox, BorderLayout.CENTER);
    } public void update(final EWizardButton... buttons) {
    EWizardButton[] stepButtons = buttons;
    if (null == stepButtons || 0 == stepButtons.length) {
    stepButtons = new EWizardButton[] { EWizardButton.Previous,
    EWizardButton.Next, EWizardButton.Cancel,
    EWizardButton.Help };
    } buttonPane.removeAll();
    int index = 0;
    for (EWizardButton buttonE : stepButtons) {
    index++;
    buttonPane.add(stepBtnPane.get(buttonE));
    if (index != stepButtons.length) {
    buttonPane.add(Box.createHorizontalStrut(4));
    }
    }
    this.revalidate();
    this.repaint();
    } /**
     * 根据按钮的枚举返回对应按钮实例
     * 
     * @param buttonE
     *            按钮枚举
     * @return JButton 按钮实例
     */
    public JButton getButtonBy(EWizardButton buttonE) {
    return stepBtnPane.get(buttonE);
    } private static final long serialVersionUID = -6353833271412606367L;
    private Map<EWizardButton, JButton> stepBtnPane = new EnumMap<EWizardButton, JButton>(
    EWizardButton.class); private Box buttonPane;
    }
    }
      

  2.   


    /**
     * 
     */
    package com.gordon.ui.wizard;import javax.swing.JPanel;import com.gordon.ui.wizard.Wizard.CardHead;/**
     * @author Administrator
     * 
     */
    public abstract class Card { /**
     * 面板的步骤标识符,其目地是为了实现对整个向导流中按钮的显示控制,子类不需要关心面板需要显示哪几个按钮
     */
    public static enum StepID {
    FirstCard, SecondCard, ThirdCard, FourCard, FiveCard, SixCard, SevenCard, EightCard, NineCard, TenCard;
    } public Card() {
    cardView = new JPanel();
    } public Card(JPanel cardView) {
    this.cardView = cardView;
    } /**
     * 设置当前面板显示内容
     * 
     * @param mainPane
     */
    public final void setCardView(JPanel mainPane) {
    this.cardView = mainPane;
    } /**
     * 获取当前面板显示内容
     * 
     * @return mainPane
     */
    final JPanel getCardView() {
    return this.cardView;
    } /**
     * 子类实现,提供当前步骤流总计有多少步,可能根据不同的流程,总的步骤不一样,由子类提供
     * 
     * @return int 返回当前向导流总的步骤数
     */
    protected abstract int getTotalSteps(); /**
     * 子类实现,指明当前处于向导流中的第几步?
     * 
     * @return int 返回当前所处的步骤
     */
    protected abstract int getCurrentStep(); /**
     * 子类实现,返回当前步骤在向导页面顶部上的步骤说明信息:包括当前步骤的标题,详细描述以及图标
     * 
     * @return
     */
    protected abstract CardHead getCardHead(); /**
     * 设置当前步骤ID
     * @param stepID
     */
    void setCurrentStepID(StepID stepID) {
    currentStepID = stepID;
    } /**
     * 获取当前步骤ID
     * 
     * @return
     */
    StepID getCurrentStepID() {
    return currentStepID;
    } /**
     * 获取下一步面板的标志符, 可以根据该标识符,找到上一步面板实例对象
     */
    protected abstract StepID getNextCardStepID(); /**
     * 获取上一步面板的标志符, 可以根据该标识符,找到上一步面板实例对象
     */
    protected abstract StepID getPreviousStepID(); /**
     * 子类覆盖实现:离开当前面板到下一面板时回调此方法,做一些离开此面板前的工作。 如数据收集工作,下发命令工作
     * 
     * @return true: 能够正常进入下一页面, false:不能进入下一页面
     */
    protected boolean onNextCommand() {
    return true;
    } /**
     * 子类覆盖实现:离开当前面板时到上一步时回调此方法,做一些离开此面板前的工作。 如密码的清理工作 如数据收集工作
     * 
     * @return true: 能够正常回到上一页面, false:不能回到上一页面
     */
    protected boolean onPreviousCommand() {
    return true;
    } /**
     * 响应完成按钮命令。Card子类覆盖实现,以提供完成前的处理工作:如提醒用户做什么操作,或想系统发送一条后台命令等
     * 
     * @return
     */
    protected boolean onCancelCommand() {
    return true;
    } /**
     * 响应完成按钮命令。Card子类覆盖实现,以提供取消前的处理工作:如警告用户任务未完成。
     */
    protected boolean onFinishCommand() {
    return true;
    } /**
     * 子类实现:进入下一页面前做一些初始化工作
     * 
     * @return
     */
    protected boolean doInitTask() {
    return true;
    } /**
     * 子类实现:进入页面后,可能才开始更新数据,或者启动一些后台任务。如升级处的进入页面后有一些后台任务
     */
    protected void showing() {
    } /**
     * 获取向导对话框标题上的当前步骤与总步骤的显示
     * 
     * @return
     */
    String getWizardStep() {
    int totalSteps = getTotalSteps();
    int currentStep = getCurrentStep(); return "Step" + currentStep + "/" + totalSteps;
    } /**
     * 设置当前的向导对话框
     * 
     * @param wizard
     */
    void setWizard(Wizard wizard) {
    this.wizard = wizard;
    } /**
     * @return 获取当前的向导对话框
     */
    protected Wizard getWizard() {
    return this.wizard;
    } private Wizard wizard; private JPanel cardView; private StepID currentStepID;
    }