📄 wizard.java
字号:
package net.sf.dz.util.wizard;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener; import java.util.Iterator;import java.util.Map;import java.util.TreeMap;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTextPane;/** * An outer shell for the wizard framework. * * @author Copyright © <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2004 * @version $Id: Wizard.java,v 1.18 2004/07/23 19:06:21 vtt Exp $ */public class Wizard extends JPanel implements ActionListener { /** * The wizard processor. */ private final WizardProcessor wizardProcessor; /** * Current page label. */ private JLabel currentLabel; /** * Scroller for {@link #helpPanel helpPanel} */ private JScrollPane helpScroll; /** * This panel contains the help text (actually, an HTML viewer). */ private JTextPane helpPanel; /** * This panel contains the content panel and message label. */ private JPanel contentWrapper; /** * This panel contains the actual wizard page. */ private JPanel contentPanel; private GridBagLayout contentLayout; private GridBagConstraints contentCs; /** * Splitter between help (left) and content (right). */ private JSplitPane splitPane; /** * This panel contains the navigation buttons. */ private JPanel buttonPanel; /** * This panel contains the error and/or warning messages, if any. */ private JLabel messageLabel; /** * "Help" button. */ private JButton helpButton; /** * "Back" button. */ private JButton backButton; /** * "Next" button. */ private JButton nextButton; /** * "Finish" button. */ private JButton finishButton; /** * "Cancel" button. */ private JButton cancelButton; private WizardPage content[] = null; private WizardPage currentPage = null; private int currentOffset = 0; private Map context = new TreeMap(); public Wizard(WizardProcessor wizardProcessor) { if ( wizardProcessor == null ) { throw new IllegalArgumentException("Wizard processor can't be null"); } this.wizardProcessor = wizardProcessor; currentLabel = new JLabel("", JLabel.CENTER); helpPanel = new JTextPane(); helpPanel.setEditable(false); helpScroll = new JScrollPane(helpPanel); contentWrapper = new JPanel(); GridBagLayout layout = new GridBagLayout(); GridBagConstraints cs = new GridBagConstraints(); contentWrapper.setLayout(layout); cs.gridx = 0; cs.gridy = 0; cs.weightx = 1; cs.weighty = 1; cs.gridheight = 3; cs.fill = GridBagConstraints.BOTH; contentPanel = new JPanel(); layout.setConstraints(contentPanel, cs); contentWrapper.add(contentPanel); cs.gridy = 4; cs.gridheight = 1; cs.weighty = 0; messageLabel = new JLabel("", JLabel.CENTER); messageLabel.setVerticalAlignment(JLabel.CENTER); messageLabel.setForeground(java.awt.Color.RED); layout.setConstraints(messageLabel, cs); contentWrapper.add(messageLabel); contentLayout = new GridBagLayout(); contentCs = new GridBagConstraints(); contentPanel.setLayout(contentLayout); contentCs.fill = GridBagConstraints.BOTH; contentCs.gridx = 0; contentCs.gridy = 0; contentCs.weightx = 1; contentCs.weighty = 1; splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, false, helpScroll, contentWrapper); splitPane.setBorder(BorderFactory.createLoweredBevelBorder()); buttonPanel = createButtonPanel(); layout = new GridBagLayout(); cs = new GridBagConstraints(); this.setLayout(layout); cs.fill = GridBagConstraints.HORIZONTAL; cs.gridx = 0; cs.gridy = 0; cs.weightx = 1; cs.weighty = 0; layout.setConstraints(currentLabel, cs); this.add(currentLabel); cs.gridy++; cs.fill = GridBagConstraints.BOTH; cs.weighty = 1; layout.setConstraints(splitPane, cs); this.add(splitPane); cs.fill = GridBagConstraints.HORIZONTAL; cs.gridy++; cs.weighty = 0; layout.setConstraints(buttonPanel, cs); this.add(buttonPanel); } public void process(WizardPage content[]) { if ( content == null || content[0] == null ) { throw new IllegalArgumentException("Content is empty"); } // VT: FIXME: If there was content already, push it up the stack this.content = content; selectPage(content[currentOffset]); } private JPanel createButtonPanel() { JPanel bp = new JPanel(); JPanel filler = new JPanel(); helpButton = new JButton("Help"); backButton = new JButton("<< Back"); nextButton = new JButton("Next >>"); finishButton = new JButton("Finish"); cancelButton = new JButton("Cancel"); helpButton.addActionListener(this); backButton.addActionListener(this); nextButton.addActionListener(this); finishButton.addActionListener(this); cancelButton.addActionListener(this); GridBagLayout layout = new GridBagLayout(); GridBagConstraints cs = new GridBagConstraints(); bp.setLayout(layout); cs.fill = GridBagConstraints.HORIZONTAL; cs.gridx = 0; cs.gridy = 0; cs.weightx = 0; cs.weighty = 1; layout.setConstraints(helpButton, cs); bp.add(helpButton); cs.gridx++; cs.weightx = 1; layout.setConstraints(filler, cs); bp.add(filler); cs.gridx++; cs.weightx = 0; cs.weighty = 0; layout.setConstraints(backButton, cs); bp.add(backButton); cs.gridx++; layout.setConstraints(nextButton, cs); bp.add(nextButton); cs.gridx++; layout.setConstraints(finishButton, cs); bp.add(finishButton); cs.gridx++; layout.setConstraints(cancelButton, cs); bp.add(cancelButton); return bp; } public WizardPage getCurrentPage() { if ( currentPage == null ) { throw new IllegalArgumentException("Current page can't be null"); } return currentPage; } /** * Accept the button press and figure out what to do with it. * * If the button pressed is one of {@link #backButton Back}, {@link * #nextButton Next}, {@link #finishButton Finish} or {@link * #cancelButton Cancel}, it is processed locally (and possibly * * @param e Action event to process. */ public void actionPerformed(ActionEvent e) { try { Object source = e.getSource(); if ( helpButton.equals(source) ) { actionHelp(); return; } else if ( backButton.equals(source) ) { actionBack(); return; } else if ( nextButton.equals(source) ) { actionNext(); return; } else if ( finishButton.equals(source) ) { wizardProcessor.finish(context); System.exit(0); } else if ( cancelButton.equals(source) ) { // Just stop... System.exit(1); } else { // WHAT??? throw new IllegalArgumentException("Unexpected wizard button: " + e); } } catch ( Throwable t ) { System.err.println("Oops"); t.printStackTrace(); } } /** * Perform "Help" action. */ private void actionHelp() { } /** * Perform "Go back" action. */ private void actionBack() { // If the 'back' button is not enabled, we won't be here deselectPage(currentPage); currentOffset--; while ( !content[currentOffset].isEnabled() && currentOffset >= 0 ) { currentOffset--; } if ( !content[currentOffset].isEnabled() ) { throw new IllegalStateException("Can't go back - not a single page is enabled"); } currentPage = content[currentOffset]; selectPage(currentPage); } /** * Perform "Go next" action. */ private void actionNext() { System.err.println("Context:\n"); for ( Iterator i = context.keySet().iterator(); i.hasNext(); ) { Object key = i.next(); System.err.println(key.toString() + "=" + context.get(key)); } System.err.println("\n"); // First of all, we shouldn't be here if the current page doesn't // validate... So we won't check for that. Likewise for the 'is // last' check. deselectPage(currentPage); currentOffset++; while ( !content[currentOffset].isEnabled() && currentOffset < content.length ) { currentOffset++; } if ( !content[currentOffset].isEnabled() ) { throw new IllegalStateException("Can't go forward - not a single page is enabled"); } currentPage = content[currentOffset]; selectPage(currentPage); } private void selectPage(WizardPage page) { if ( !page.isEnabled() ) { throw new IllegalStateException("Attempt to select a page that is not enabled (" + page.getTitle() + ")"); } currentPage = page; // Let's see how many pages are enabled int enabled = 0; for ( int offset = 0; offset < content.length; offset++ ) { if ( content[offset] != null && content[offset].isEnabled() ) { enabled++; } } currentLabel.setText(currentPage.getTitle() + " (page " + (currentOffset + 1) + " of " + enabled + ")"); JPanel contentPane = currentPage.getContentPane(); contentLayout.setConstraints(contentPane, contentCs); contentPanel.add(contentPane); contentPanel.invalidate(); contentPanel.validate(); contentPanel.repaint(); currentPage.activate(); validateButtons(); } private void deselectPage(WizardPage page) { contentPanel.remove(page.getContentPane()); } /** * Make sure our buttons are appropriately enabled and/or disabled. * * This method is supposed to be called by {@link WizardPage wizard * pages} after processing their input events. */ public void validateButtons() { helpButton.setEnabled(content[currentOffset].getHelpURL() != null); backButton.setEnabled(currentOffset > 0); messageLabel.setText(currentPage.validate()); nextButton.setEnabled("".equals(messageLabel.getText()) && currentOffset < content.length - 1); boolean ok = true; for ( int offset = 0; offset < content.length; offset++ ) { // If the page is not enabled, it is irrelevant. We don't even // have to validate it. if ( !content[offset].isEnabled() ) { continue; } if ( !"".equals(content[offset].validate()) ) { System.err.println(content[offset].getTitle() + ": " + content[offset].validate()); ok = false; break; } } finishButton.setEnabled(ok); } public Map getContext() { return context; } public boolean isVisible(WizardPage page) { return (currentPage == page); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -