/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.gui.component; import icy.common.listener.weak.WeakListener; import icy.gui.frame.IcyFrame; import icy.gui.frame.IcyFrameAdapter; import icy.gui.frame.IcyFrameEvent; import icy.gui.util.WindowPositionSaver; import icy.main.Icy; import icy.util.StringUtil; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.HeadlessException; import java.awt.Point; import java.util.EventListener; import javax.swing.JPanel; import javax.swing.WindowConstants; /** * Externalizable panel component.<br> * Basically this is a JPanel you can externalize and display in an IcyFrame.<br> * * @author Stephane */ public class ExternalizablePanel extends JPanel { public static class WeakStateListener extends WeakListener<StateListener> implements StateListener { public WeakStateListener(StateListener listener) { super(listener); } @Override public void removeListener(Object source) { if (source != null) ((ExternalizablePanel) source).removeStateListener(this); } @Override public void stateChanged(ExternalizablePanel source, boolean externalized) { final StateListener listener = getListener(source); if (listener != null) listener.stateChanged(source, externalized); } } public static interface StateListener extends EventListener { public void stateChanged(ExternalizablePanel source, boolean externalized); } public class Frame extends IcyFrame { public Frame(String title) throws HeadlessException { super(title, true, true, true, true); setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addFrameListener(new IcyFrameAdapter() { @Override public void icyFrameClosing(IcyFrameEvent e) { super.icyFrameClosing(e); // ignore the event when frame is manually closed or application is exiting if (!(closed || Icy.isExiting())) { if (ExternalizablePanel.this.isExternalized()) ExternalizablePanel.this.internalizeInternal(); } } }); setLayout(new BorderLayout()); setSize(400, 400); } } /** * */ private static final long serialVersionUID = -7690543443681714719L; /** * extern frame */ protected final Frame frame; /** * parent component */ private Container parent; /** * internals */ private boolean internalizationAutorized; private boolean externalizationAutorized; boolean closed; // we need to keep reference on it as the object only use weak reference final WindowPositionSaver positionSaver; /** * Create a new externalizable panel. * * @param title * title for the associated frame. * @param key * save key, used for WindowPositionSaver.<br> * Set to null or empty string disable parameter saving. * @param defLoc * the default location for the frame (externalized state) * @param defDim * the default dimension for the frame (externalized state) */ public ExternalizablePanel(String title, String key, Point defLoc, Dimension defDim) { super(); frame = new Frame(title); parent = null; internalizationAutorized = true; externalizationAutorized = true; closed = false; // use window position saver with default parameters if (!StringUtil.isEmpty(key)) positionSaver = new WindowPositionSaver(this, "frame/" + key, defLoc, defDim); else positionSaver = null; } /** * Create a new externalizable panel. * * @param title * title for the associated frame. * @param key * save key, used for WindowPositionSaver.<br> * Set to null or empty string disable parameter saving. */ public ExternalizablePanel(String title, String key) { // default location and dimension for extern frame this(title, key, new Point(200, 200), new Dimension(400, 300)); } public ExternalizablePanel(String title) { this(title, null); } public ExternalizablePanel() { this("", null); } @Override public void addNotify() { super.addNotify(); // set parent on first attachment if (parent == null) { final Container p = getParent(); if ((p != frame.getInternalFrame().getContentPane()) && (p != frame.getExternalFrame().getContentPane())) parent = p; } } /** * Close the panel (close and release associated frames and resources). */ public void close() { closed = true; frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); frame.close(); } /** * Manual parent set */ public void setParent(Container value) { parent = value; } /** * @return the internalizationAutorized */ public boolean isInternalizationAutorized() { return internalizationAutorized; } /** * @param internalizationAutorized * the internalizationAutorized to set */ public void setInternalizationAutorized(boolean internalizationAutorized) { this.internalizationAutorized = internalizationAutorized; } /** * @return the externalizationAutorized */ public boolean isExternalizationAutorized() { return externalizationAutorized; } /** * @param externalizationAutorized * the externalizationAutorized to set */ public void setExternalizationAutorized(boolean externalizationAutorized) { this.externalizationAutorized = externalizationAutorized; } /** * Externalize panel in an independent frame */ public void externalize() { if (isInternalized()) externalizeInternal(); } /** * Internalize panel (remove from independent frame) */ public void internalize() { if (isExternalized()) internalizeInternal(); } /** * Externalize panel (internal method) */ void externalizeInternal() { if (!externalizationAutorized) return; // externalize if (parent != null) { parent.remove(this); parent.validate(); } frame.add(this, BorderLayout.CENTER); frame.validate(); frame.addToDesktopPane(); frame.setVisible(true); // notify fireStateChange(true); } /** * Internalize panel (internal method) */ void internalizeInternal() { if (!internalizationAutorized) return; // internalize frame.setVisible(false); frame.remove(this); frame.validate(); frame.removeFromMainDesktopPane(); if (parent != null) { parent.add(this); parent.validate(); } // notify fireStateChange(false); } /** * Switch from internalized <--> externalized state and vice versa */ public void switchState() { if (isExternalized()) internalizeInternal(); else externalizeInternal(); } public boolean isInternalized() { return !frame.isVisible(); } public boolean isExternalized() { return frame.isVisible(); } /** * @return the frame */ public IcyFrame getFrame() { return frame; } // /** // * Implement getMinimumSize method for external frame only // */ // public Dimension getMinimumSizeExternal() // { // return frame.getMinimumSize(); // } // // /** // * Implement getMaximumSize method for external frame only // */ // public Dimension getMaximumSizeExternal() // { // return frame.getMaximumSize(); // } // // /** // * Implement getPreferredSize method for external frame only // */ // public Dimension getPreferredSizeExternal() // { // return frame.getPreferredSize(); // } // // /** // * Implement getSize method for external frame only // */ // public Dimension getSizeExternal() // { // return frame.getSize(); // } // // /** // * Implement getHeight method for external frame only // */ // public int getHeightExternal() // { // return frame.getHeight(); // } // // /** // * Implement getWidth method for external frame only // */ // public int getWidthExternal() // { // return frame.getWidth(); // } // // /** // * Implement getLocation method for external frame only // */ // public Point getLocationExternal() // { // return frame.getLocation(); // } // // /** // * Implement getBounds method for external frame only // */ // public Rectangle getBoundsExternal() // { // return frame.getBounds(); // } // // /** // * Implement setLocation method for external frame only // */ // public void setLocationExternal(final Point p) // { // frame.setLocation(p); // } // // /** // * Implement setLocation method for external frame only // */ // public void setLocationExternal(final int x, final int y) // { // frame.setLocation(x, y); // } // // /** // * Implement setSize method for external frame only // */ // public void setSizeExternal(final Dimension d) // { // frame.setSize(d); // } // // /** // * Implement setSize method for external frame only // */ // public void setSizeExternal(final int width, final int height) // { // frame.setSize(width, height); // } // // /** // * Implement setPreferredSize method for external frame only // */ // public void setPreferredSizeExternal(final Dimension d) // { // frame.setPreferredSize(d); // } // // /** // * Implement setMinimumSize method for external frame only // */ // public void setMinimumSizeExternal(final Dimension d) // { // frame.setMinimumSize(d); // } // // /** // * Implement setMaximumSize method for external frame only // */ // public void setMaximumSizeExternal(final Dimension d) // { // frame.setMaximumSize(d); // } /** * Fire state change event */ private void fireStateChange(boolean externalized) { for (StateListener l : listenerList.getListeners(StateListener.class)) l.stateChanged(this, externalized); } /** * Implement addFrameListener method */ public void addStateListener(StateListener l) { listenerList.add(StateListener.class, l); } /** * Implement removeFrameListener method */ public void removeStateListener(StateListener l) { listenerList.remove(StateListener.class, l); } }