summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
blob: 6490180bc371718ba79852205da6335f38694a6c (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                      





                                                  

                                     




                                    





                                                                          
 
                                          
                                                                 

                                                 
                                          
                                     
                                           
                                            

                                                      




                                        

                                      
                                                              
                                                                     
                                              

                                                                                         

                                             
                                                                             
                                                                                  
                                                       



                                                                                              






                                                                       




                                                                                         
 
                                              
                                                                   
                                    


                                                       
                                
                                                       
                                                                             
                                           



                                                                
                                                                              
                                         


                                                                
                                                                              
                                             


                                                                  
                                                                              
                                           


                                                                  
                                                                              
                                           

                         

         








                                                       
                         
                 

                                          

         
                                            
                                        
                                                              


                                              
                                                 







                                      


                                                                 
                                      











                                                                 

                                                











                                                                                       
                                            
                                                                                         






                                                          
                                                                                                        


                                                               
                                                
 
                                                       




                                               

         





                                                                   
                                                                         
                                                   



                                        



                                                        
                                             



                                                                          









                                                  
                                             

                                                              
                                                                        
                                                                                                
                                                                                                    


                 

                                                                        
          

                                                                        



                                                 


                                                                                    
          





                                                    
                              
                                                         

                                                     
                                                                     




                                                                      




                                                                      
                                                         






                                                  
                                        
                                           





                                                                   


                                                             
                                  
                 


                                         

                                                     
                                  

                               


                                           
                                                                     



                                                



                                                                   
                                          



                                                          
                                                                                                        


                                                                 
                         


                 





                                                



                                            
           

                                                             
          
                  
           
                                             


                            


                                                                               
          
                                                                             
                    


                                        

         



                                                                                 


                                                                                 
          
                                                                              
                                   
           

                                              
         



















                                                                   

 
package org.openslx.dozmod.gui.wizard;

import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.I18n;
import org.openslx.dozmod.gui.helper.StatusHeader;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;

public abstract class Wizard extends JDialog {

	/**
	 * Version for serialization.
	 */
	private static final long serialVersionUID = 1436816291272809418L;

	private final StatusHeader header;
	private final List<WizardPage> pages = new ArrayList<>();
	private WizardPage postFinishPage = null;
	private boolean isPostFinish = false;
	private final JPanel contentPanel;
	private int currentPage = -1;
	private boolean needsLayout = true;
	private boolean isCancelled = false;
	// Reference if an out of order page is shown.
	protected WizardPage outOfOrderPage = null;

	private final JButton btnPrev;
	private final JButton btnNext;
	private final JButton btnCancel;
	private final JButton btnFinish;

	public Wizard(Window parent) {
		super(parent, ModalityType.APPLICATION_MODAL);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setLayout(new BorderLayout());

		this.header = new StatusHeader(getContentPane(), "<titel>", "<message>");
		// Buttons in footer
		JPanel footer = new JPanel();
		footer.setLayout(new BoxLayout(footer, BoxLayout.LINE_AXIS));
		footer.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		footer.add(Box.createHorizontalGlue());
		btnPrev = new JButton(I18n.WIZARD.getString("Wizard.Button.prev.text"));
		btnNext = new JButton(I18n.WIZARD.getString("Wizard.Button.next.text"));
		btnCancel = new JButton(I18n.WIZARD.getString("Wizard.Button.cancel.text"));
		btnFinish = new JButton(I18n.WIZARD.getString("Wizard.Button.finish.text.0"));
		footer.add(btnPrev);
		footer.add(btnNext);
		footer.add(Box.createRigidArea(new Dimension(10, 10)));
		footer.add(btnCancel);
		footer.add(Box.createRigidArea(new Dimension(5, 5)));
		footer.add(btnFinish);
		add(footer, BorderLayout.PAGE_END);
		// Add content panel
		contentPanel = new JPanel();
		contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
		contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		add(contentPanel, BorderLayout.CENTER);

		// Scale window with font size
		setPreferredSize(Gui.getScaledDimension(550, 420));
		setResizable(false);
		pack();
		Gui.centerShellOverShell(parent, this);

		// Window events
		addWindowListener(new WindowAdapter() {
			@Override public void windowClosing(WindowEvent we) {
				doCancel();
			}
		});
		// Äkschns
		btnNext.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				doNext();
			}
		});
		btnPrev.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				doPrevious();
			}
		});
		btnCancel.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				doCancel();
			}
		});
		btnFinish.addActionListener(new ActionListener() {
			@Override public void actionPerformed(ActionEvent e) {
				doFinish();
			}
		});
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
			if (needsLayout) {
				needsLayout = false;
				pack();
				if (!pages.isEmpty()) {
					showPage(0);
				}
			}
		}

		super.setVisible(visible);
	}

	protected void showPage(int index) {
		if (currentPage != -1) {
			WizardPage old = getPage(currentPage);
			old.onPageLeave();
			old.setVisible(false);
		}
		WizardPage page = getPage(index);
		page.onPageEnter();
		page.setVisible(true);
		currentPage = index;
		updateHeader(page);
		updateButtons(page);
		validate();
	}

	// Show an out of order page e.g. for converting an image
	public void showOutOfOrderPage(WizardPage page) {
		WizardPage old = getPage(currentPage);
		outOfOrderPage = page;
		old.onPageLeave();
		old.setVisible(false);

		page.onPageEnter();
		page.setVisible(true);
		updateHeader(page);
		updateButtons(page);
		validate();
	}

	// Show an out of order page e.g. for converting an image
	/**
	 * @param newPage to return to.
	 * @param oldPage that should be hidden.
	 */
	public void returnAfterOutOfOrderPage(WizardPage newPage, WizardPage oldPage) {
		oldPage.onPageLeave();
		oldPage.setVisible(false);

		newPage.onPageEnter();
		newPage.setVisible(true);
		updateHeader(newPage);
		updateButtons(newPage);
		validate();
	}

	void updateHeader(WizardPage page) {
		if (!isPostFinish && (currentPage == -1 || getPage(currentPage) != page))
			return;
		String pageTitle = page.getTitle();
		String pageDesc = page.getMessage();
		if (pageTitle == null)
			pageTitle = "Step " + currentPage;
		if (pageDesc == null)
			pageDesc = "";
		header.updateHeader(pageTitle, pageDesc, page.getMessageIcon(), page.getMessageColor());
		setTitle(getWindowTitle() + " - " + pageTitle);
	}

	public abstract String getWindowTitle();

	protected final void addPage(WizardPage page) {
		contentPanel.add(page);
		if (!pages.isEmpty()) {
			page.setVisible(false);
		}
		pages.add(page);
	}

	// For adding pages which are not in the normal linear flow
	protected final void addOutOfOrderPage(WizardPage page) {
		contentPanel.add(page);
		page.setVisible(false);
	}

	protected final void removePages(List<WizardPage> currentPages) {
		for (WizardPage i : currentPages) {
			pages.remove(i);
		}
	}

	protected void addSummaryPage(WizardPage page) {
		postFinishPage = page;
	}

	void updateButtons(WizardPage page) {
		if (isPostFinish) {
			btnFinish.setEnabled(postFinishPage.isComplete());
			return;
		}
		// State of finish button
		boolean canFinish = true;
		for (WizardPage p : pages) {
			if (!p.isComplete()) {
				canFinish = false;
				break;
			}
		}
		btnFinish.setEnabled(canFinish);
		// State of next button
		if (outOfOrderPage != null) {
			btnNext.setEnabled(page.isComplete());
		}
		if (currentPage != -1 && getPage(currentPage) == page) {
			btnNext.setEnabled(currentPage + 1 < pages.size() && page.isComplete());
			btnPrev.setEnabled(currentPage > 0 && getPage(currentPage - 1).canComeBack);
		}
	}

	/**
	 * Returns whether the page currently shown is the summary page.
	 *
	 * @return whether the page currently shown is the summary page.
	 */
	protected final boolean isSummaryPage() {
		return isPostFinish;
	}

	/**
	 * Returns true if the wizard was cancelled. Mostly useful in onPageLeave to
	 * distinguish what's happening.
	 *
	 * @return true if the wizard was cancelled.
	 */
	public final boolean isCancelled() {
		return isCancelled;
	}

	public void doNext() {
		if (isPostFinish || !btnNext.isEnabled())
			return;
		if (currentPage + 1 < pages.size()) {
			if (!getPage(currentPage).wantNextOrFinish())
				return; // Page canceled the operation
			showPage(currentPage + 1);
		}
	}

	// protected void returnAfterOutOfOrderPage(int previousPage){
	// 	showPage(previousPage);
	// }

	protected void doPrevious() {
		if (isPostFinish || !btnPrev.isEnabled())
			return;
		if (currentPage > 0) {
			showPage(currentPage - 1);
		}
	}

	protected final void doCancel() {
		if (onCancelRequest()) {
			isCancelled = true;
			if (currentPage != -1) {
				getPage(currentPage).onPageLeave();
			}
			if (isPostFinish) {
				postFinishPage.onPageLeave();
			}
			if (outOfOrderPage != null) {
				outOfOrderPage.onPageLeave();
			}
			cleanup();
		}
	}

	protected final void doFinish() {
		if (isPostFinish) {
			postFinishPage.onPageLeave();
			cleanup();
			return;
		}
		if (!btnFinish.isEnabled())
			return;
		if (currentPage != -1) {
			if (!getPage(currentPage).wantNextOrFinish())
				return;
		}
		if (wantFinish()) {
			if (currentPage != -1) {
				getPage(currentPage).onPageLeave();
			}
			postFinishPage = performFinish();
			if (postFinishPage == null) {
				cleanup();
			} else {
				isPostFinish = true;
				btnPrev.setVisible(false);
				btnNext.setVisible(false);
				btnFinish.setText(I18n.WIZARD.getString("Wizard.Button.finish.text.1"));
				postFinishPage.setVisible(false);
				contentPanel.add(postFinishPage);
				showPage(-1);
			}
		}
	}

	private WizardPage getPage(int index) {
		if (isPostFinish && index == -1)
			return postFinishPage;
		return pages.get(index);
	}

	/*
	 * Callback to wizard implementation
	 */

	/**
	 * User clicked cancel or (X) - when returning false,
	 * wizard will stay open
	 *
	 * @return
	 */
	protected boolean onCancelRequest() {
		return true;
	}

	/**
	 * Called when user clicks finish. Override to do final checks and take
	 * appropriate actions.
	 *
	 * @return <code>true</code> if finish is allowed, <code>false</code>
	 * otherwise
	 */
	protected boolean wantFinish() {
		return true;
	}

	/**
	 * Called so the wizard can perform finishing steps. This is called after
	 * wantFinish() returned true and onPageLeave was called on the currently
	 * visible wizard step.
	 * If a wizard page is returned, it will serve as a summary page shown to
	 * the user within the wizard frame. The prev and next buttons will
	 * disappear, and the finish button will change to a close button.
	 *
	 * @return A wizard page that serves as a summary page, or null if the
	 * wizard should just close
	 */
	protected WizardPage performFinish() {
		return null;
	}
	
	/**
	 * Called when this wizard is closed, either by aborting or
	 * by finishing it.
	 */
	private final void cleanup()
	{
		doCleanup();
		dispose();
		pages.clear();
		postFinishPage = null;
		outOfOrderPage = null;
	}

	/**
	 * Force all derived wizards to think about what
	 * references they might want to free when they're
	 * being closed.
	 */
	protected abstract void doCleanup();

}