All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tutorial.C2_DockFrontendBasics_02_PersistentLayout Maven / Gradle / Ivy

The newest version!
package tutorial;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;

import tutorial.support.ColorDockable;
import tutorial.support.JTutorialFrame;
import tutorial.support.TextDockable;
import tutorial.support.Tutorial;
import bibliothek.extension.gui.dock.theme.SmoothTheme;
import bibliothek.gui.DockFrontend;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.event.DockFrontendAdapter;
import bibliothek.gui.dock.station.split.SplitDockGrid;
import bibliothek.gui.dock.themes.NoStackTheme;
import bibliothek.util.xml.XElement;
import bibliothek.util.xml.XIO;

@Tutorial( title="Persistent Layout", id="DFPersistentLayout" )
public class C2_DockFrontendBasics_02_PersistentLayout {
	public static void main( String[] args ){
		/* You already have seen how a layout can be persistently stored using 
		 * the class DockSituation or PredefinedDockSituation. But maybe the
		 * user would like to store more than one layout, and maybe you don't
		 * like to setup a DockSituation all the times.
		 * 
		 * DockFrontend offers methods to store more than one layout persistently,
		 * the user just has to give the different layouts a name. The methods
		 * responsible for handling layouts are:
		 * 
		 *   - write/read: writes/reads all the stored layouts and the current
		 *       layout from/to a file.
		 *   - save/load/delete: saves, loads or deletes a layout, each layout
		 *       is identified by a unique String
		 *   - setEntryLayout: if set to true, then a Dockables location gets 
		 *       stored every time "save" is called. If set to false, then
		 *       the location gets only stored if "write" is called. 
		 *       
		 * This example allows you to experiment with the save/load/delete and
		 * shows what data is stored when you use the write/read methods. */
		
		/* Setting up a frame, a frontend, a DockStation and some Dockables */
		JTutorialFrame frame = new JTutorialFrame( C2_DockFrontendBasics_02_PersistentLayout.class );
		DockFrontend frontend = new DockFrontend( frame );
		frame.destroyOnClose( frontend );
		frontend.getController().setTheme( new NoStackTheme( new SmoothTheme() ) );

		SplitDockStation station = new SplitDockStation();
		frame.add( station );
		frontend.addRoot( "split", station );
		
		/* Prepare the Dockables we are going to put onto "station" */
		Dockable red = new ColorDockable( "Red", Color.RED, 2.5f );
		Dockable green =  new ColorDockable( "Green", Color.GREEN, 2.5f );
		Dockable blue = new ColorDockable( "Blue", Color.BLUE, 2.5f );		
		Dockable yellow = new ColorDockable( "Yellow", Color.YELLOW, 2.5f );
		Dockable cyan = new ColorDockable( "Cyan", Color.CYAN, 2.5f );
		Dockable magenta = new ColorDockable( "Magenta", Color.MAGENTA, 2.5f );
		
		/* We will show the persistent data on this JTextArea */
		TextDockable layout = new TextDockable( "File" );
		
		/* Never forget to register all Dockables at the DockFrontend */
		frontend.addDockable( "red", red );
		frontend.addDockable( "green", green );
		frontend.addDockable( "blue", blue );
		frontend.addDockable( "yellow", yellow );
		frontend.addDockable( "cyan", cyan );
		frontend.addDockable( "magenta", magenta );
		frontend.addDockable( "file", layout );
		
		/* Adding the Dockables to "station" */
		SplitDockGrid grid = new SplitDockGrid();
		grid.addDockable( 0, 0, 40, 100, red, green, blue );
		grid.setSelected( 0, 0, 40, 100, green );
		grid.addDockable( 40, 0, 60, 30, yellow );
		grid.addDockable( 40, 30, 20, 70, cyan );
		grid.addDockable( 60, 30, 40, 70, magenta );
		grid.addDockable( -40, 0, 40, 100, layout );
		
		station.dropTree( grid.toTree() );
	
		/* We build a menu that allows us to call the different methods easily */
		JMenu menu = new JMenu( "Layout" );
		
		/* The ReadAction calls DockFrontend.readXML */
		ReadAction read = new ReadAction( frontend, layout );
		menu.add( read );
		
		/* The WriteAction calls DockFrontend.writeXML */
		menu.add( new WriteAction( frontend, layout, read ) );
		menu.addSeparator();
		
		/* The LoadAction calls DockFrontend.load */
		menu.add( new LoadAction( frontend ) );
		
		/* The SaveAction calls DockFrontend.save() */
		menu.add( new SaveAction( frontend ) );
		
		/* The SaveAsAction calls DockFrontend.save(...) */
		menu.add( new SaveAsAction( frontend ) );
		
		/* Finally the DeleteAction calls DockFrontend.delete */
		menu.add( new DeleteAction( frontend ) );
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.add( menu );
		frame.setJMenuBar( menuBar );
		frame.setVisible( true );
	}
	
	/* This abstract action stores a DockFrontend to be used by its subclasses */
	public static abstract class FrontendAction extends AbstractAction{
		protected DockFrontend frontend;
		
		public FrontendAction( String text, DockFrontend frontend ){
			putValue( NAME, text );
			this.frontend = frontend;
		}
	}
	
	/* This action opens a dialog on which the user can choose one of the available
	 * layouts. The subclass decides what todo with the layout. */
	public static abstract class FrontendLayoutListAction extends FrontendAction{
		public FrontendLayoutListAction( String text, DockFrontend frontend ){
			super( text, frontend );
			
			/* A listener to "frontend" will tell us when there are layouts
			 * available and when not */
			frontend.addFrontendListener( new DockFrontendAdapter() {
				@Override
				public void saved( DockFrontend frontend, String name ){
					setEnabled( !frontend.getSettings().isEmpty() );
				}
				
				@Override
				public void deleted( DockFrontend frontend, String name ){
					setEnabled( !frontend.getSettings().isEmpty() );		
				}
				
				@Override
				public void read( DockFrontend frontend, String name ){
					setEnabled( !frontend.getSettings().isEmpty() );
				}
			});
			setEnabled( !frontend.getSettings().isEmpty() );
		}
		
		public void actionPerformed( ActionEvent e ){
			/* "getSettings" gets us an unmodifiable Set containing the names
			 * of all the available layouts */
			Set settings = frontend.getSettings();
			String[] list = settings.toArray( new String[ settings.size() ] );
			Arrays.sort( list );
			
			String layout = (String)JOptionPane.showInputDialog( frontend.getController().findRootWindow(), 
					"Choose one", "Input", JOptionPane.INFORMATION_MESSAGE, null, list, frontend.getCurrentSetting() );
			if( layout != null ){
				action( layout );
			}
		}
		
		protected abstract void action( String settingName );
	}
	
	public static class SaveAction extends FrontendAction{
		public SaveAction( DockFrontend frontend ){
			super( "Save", frontend );
		}
		public void actionPerformed( ActionEvent e ){
			/* "save()" stores the current layout using the name of the last loaded layout. If there
			 * is no last loaded layout then we have choose a name */
			if( frontend.getCurrentSetting() == null ){
				String name = JOptionPane.showInputDialog( frontend.getController().findRootWindow(), "Please input name of layout" );
				if( name != null ){
					frontend.save( name );
				}
			}
			else{
				frontend.save();
			}
		}
	}
	
	public static class SaveAsAction extends FrontendAction{
		public SaveAsAction( DockFrontend frontend ){
			super( "Save As...", frontend );
		}
		
		public void actionPerformed( ActionEvent e ){
			String name = JOptionPane.showInputDialog( frontend.getController().findRootWindow(), "Please input name of layout" );
			if( name != null ){
				frontend.save( name );
			}
		}
	}
	
	public static class LoadAction extends FrontendLayoutListAction{
		public LoadAction( DockFrontend frontend ){
			super( "Load", frontend );
		}
		
		@Override
		protected void action( String settingName ){
			/* Cannot say much about that, just calling "load" with one of the
			 * available layouts */
			frontend.load( settingName );	
		}
	}
	
	public static class DeleteAction extends FrontendLayoutListAction{
		public DeleteAction( DockFrontend frontend ){
			super( "Delete", frontend );
		}
		
		@Override
		protected void action( String settingName ){
			frontend.delete( settingName );
		}
	}
	
	public static class WriteAction extends FrontendAction{
		private TextDockable target;
		private ReadAction opposite;
		
		public WriteAction( DockFrontend frontend, TextDockable target, ReadAction opposite ){
			super( "Write", frontend );
			this.target = target;
			this.opposite = opposite;
			opposite.setEnabled( false );
		}
		
		public void actionPerformed( ActionEvent e ){
			/* We convert all available layouts and the current layout to xml and
			 * show the text on our TextDockable */
			XElement xroot = new XElement( "layout" );
			frontend.writeXML( xroot );
			target.setText( xroot.toString() );
			opposite.setEnabled( true );
		}
	}
	
	public static class ReadAction extends FrontendAction{
		private TextDockable source;
		
		public ReadAction( DockFrontend frontend, TextDockable source ){
			super( "Read", frontend );
			this.source = source;
		}
		
		public void actionPerformed( ActionEvent e ){
			try{
				/* "read" does not delete already existing layouts, so we clean up
				 * before applying a new set of layouts. */
				Set layouts = frontend.getSettings();
				String[] keys = layouts.toArray( new String[ layouts.size() ] );
				for( String key : keys ){
					frontend.delete( key );
				}
				
				/* And now we can safely apply the old layouts */
				XElement xroot = XIO.read( source.getText() );
				frontend.readXML( xroot );
			}
			catch( IOException ex ){
				ex.printStackTrace();
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy