Java tutorial
/** * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.codesourcery.jasm16.ide.ui.viewcontainers; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import de.codesourcery.jasm16.ide.IApplicationConfig; import de.codesourcery.jasm16.ide.ui.MenuManager; import de.codesourcery.jasm16.ide.ui.MenuManager.MenuEntry; import de.codesourcery.jasm16.ide.ui.utils.SizeAndLocation; import de.codesourcery.jasm16.ide.ui.utils.UIUtils; import de.codesourcery.jasm16.ide.ui.views.IView; import de.codesourcery.jasm16.ide.ui.views.IViewStateListener; /** * A view container that inherits from {@link JFrame} and uses {@link JInternalFrame}s to display * it's children. * * @author tobias.gierke@code-sourcery.de */ public class Perspective extends JFrame implements IViewContainer { private static final Logger LOG = Logger.getLogger(Perspective.class); private final JDesktopPane desktop = new JDesktopPane(); private final List<InternalFrameWithView> views = new ArrayList<InternalFrameWithView>(); private final String id; private final ViewContainerHelper helper = new ViewContainerHelper(); private final ViewContainerManager viewContainerManager; private final IApplicationConfig applicationConfig; private final MenuManager menuManager = new MenuManager() { @Override public void menuBarChanged() { setJMenuBar(menuManager.getMenuBar()); } }; protected final class InternalFrameWithView { public final JInternalFrame frame; public final IView view; private final InternalFrameListener frameListener; public InternalFrameWithView(JInternalFrame frame, final IView view) { this.view = view; this.frame = frame; if (view instanceof IViewStateListener) { frameListener = new InternalFrameAdapter() { @Override public void internalFrameActivated(InternalFrameEvent e) { ((IViewStateListener) view).viewVisible(); } @Override public void internalFrameDeactivated(InternalFrameEvent e) { ((IViewStateListener) view).viewHidden(); } }; frame.addInternalFrameListener(frameListener); } else { frameListener = null; } } public void dispose() { final SizeAndLocation sizeAndLoc = new SizeAndLocation(frame.getLocation(), frame.getSize()); applicationConfig.storeViewCoordinates(getUniqueID(view), sizeAndLoc); frame.dispose(); if (frameListener != null) { frame.removeInternalFrameListener(frameListener); } LOG.debug("dispose(): Disposing " + view); view.dispose(); } } private final String getUniqueID(IView view) { return getID() + "." + view.getID(); } @Override public void setBlockAllUserInput(boolean yesNo) { UIUtils.setBlockAllUserInput(this, yesNo); } @Override public final void dispose() { disposeHook(); final SizeAndLocation sizeAndLoc = new SizeAndLocation(getLocation(), getSize()); applicationConfig.storeViewCoordinates(getID(), sizeAndLoc); final List<InternalFrameWithView> views = new ArrayList<InternalFrameWithView>(this.views); for (InternalFrameWithView v : views) { disposeView(v.view); } super.dispose(); viewContainerManager.disposeAllExcept(this); helper.fireViewContainerClosed(this); try { this.applicationConfig.saveConfiguration(); } catch (IOException e) { LOG.error("dispose(): Failed to save view coordinates", e); } } protected void disposeHook() { } public Perspective(String id, final ViewContainerManager viewContainerManager, IApplicationConfig appConfig) { super("jASM16 DCPU emulator V" + de.codesourcery.jasm16.compiler.Compiler.getVersionNumber()); if (viewContainerManager == null) { throw new IllegalArgumentException("viewContainerManager must not be null"); } if (appConfig == null) { throw new IllegalArgumentException("appConfig must not be null"); } if (StringUtils.isBlank(id)) { throw new IllegalArgumentException("ID must not be NULL/blank."); } this.viewContainerManager = viewContainerManager; this.id = id; this.applicationConfig = appConfig; setPreferredSize(new Dimension(400, 200)); getContentPane().add(desktop); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setBackground(Color.BLACK); setForeground(Color.GREEN); desktop.setBackground(Color.BLACK); desktop.setForeground(Color.GREEN); menuManager.addEntry(new MenuEntry("File/Quit") { @Override public void onClick() { dispose(); try { applicationConfig.saveConfiguration(); } catch (IOException e) { e.printStackTrace(); } finally { System.exit(0); } } }); final SizeAndLocation sizeAndLoc = applicationConfig.getViewCoordinates(getID()); if (sizeAndLoc != null) { setLocation(sizeAndLoc.getLocation()); setSize(sizeAndLoc.getSize()); setPreferredSize(sizeAndLoc.getSize()); } else { setPreferredSize(new Dimension(600, 800)); pack(); } setJMenuBar(menuManager.getMenuBar()); } @Override public void disposeView(IView view) { for (Iterator<InternalFrameWithView> it = this.views.iterator(); it.hasNext();) { InternalFrameWithView frame = it.next(); if (frame.view == view) { frame.dispose(); it.remove(); return; } } } @Override public IView addView(final IView view) { if (view == null) { throw new IllegalArgumentException("view must not be NULL"); } final JInternalFrame internalFrame = new JInternalFrame(view.getTitle(), true, true, true, true); internalFrame.setBackground(Color.BLACK); internalFrame.setForeground(Color.GREEN); internalFrame.getContentPane().add(view.getPanel(this)); SizeAndLocation sizeAndLoc = applicationConfig.getViewCoordinates(getUniqueID(view)); if (sizeAndLoc != null) { internalFrame.setSize(sizeAndLoc.getSize()); internalFrame.setLocation(sizeAndLoc.getLocation()); } else { internalFrame.setSize(200, 150); internalFrame.setLocation(0, 0); internalFrame.pack(); } internalFrame.setVisible(true); final InternalFrameWithView frameAndView = new InternalFrameWithView(internalFrame, view); final InternalFrameListener listener = new InternalFrameAdapter() { @Override public void internalFrameClosing(InternalFrameEvent e) { disposeView(view); } }; internalFrame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); internalFrame.addInternalFrameListener(listener); views.add(frameAndView); desktop.add(internalFrame); return view; } @Override public List<IView> getViews() { final List<IView> result = new ArrayList<IView>(); for (InternalFrameWithView frame : this.views) { result.add(frame.view); } return result; } @Override public void setTitle(IView view, String title) { for (InternalFrameWithView frame : this.views) { if (frame.view == view) { frame.frame.setTitle(title); break; } } } @Override public IView getViewByID(String viewId) { if (StringUtils.isBlank(viewId)) { throw new IllegalArgumentException("viewId must not be blank/null"); } for (InternalFrameWithView frame : this.views) { if (frame.view.getID().equals(viewId)) { return frame.view; } } return null; } @Override public final void toFront(IView view) { for (InternalFrameWithView frame : this.views) { if (frame.view.getID().equals(view.getID())) { frame.frame.toFront(); return; } } } @Override public MenuManager getMenuManager() { return menuManager; } @Override public final String getID() { return id; } @Override public void addViewContainerListener(IViewContainerListener listener) { helper.addViewContainerListener(listener); } @Override public void removeViewContainerListener(IViewContainerListener listener) { helper.removeViewContainerListener(listener); } }