/* * 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.util; import icy.common.listener.weak.WeakComponentListener; import icy.common.listener.weak.WeakIcyFrameListener; import icy.common.listener.weak.WeakWindowListener; import icy.gui.component.ExternalizablePanel; import icy.gui.component.ExternalizablePanel.StateListener; import icy.gui.component.ExternalizablePanel.WeakStateListener; import icy.gui.frame.IcyFrame; import icy.gui.frame.IcyFrameAdapter; import icy.gui.frame.IcyFrameEvent; import icy.gui.main.MainFrame; import icy.preferences.IcyPreferences; import icy.preferences.XMLPreferences; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JComponent; import javax.swing.JFrame; /** * Load and Save you window position in the registry * * @author fab & stephane */ public class WindowPositionSaver { final private static String ID_EXTERNALIZED = "Externalized"; final private static String ID_PANELIZED = "Panelized"; final private static String ID_XC = "XC"; final private static String ID_YC = "YC"; final private static String ID_WC = "WidthC"; final private static String ID_HC = "HeightC"; final private static String ID_XI = "XI"; final private static String ID_YI = "YI"; final private static String ID_WI = "WidthI"; final private static String ID_HI = "HeightI"; final private static String ID_MAXIMIZEDI = "MaximizedI"; final private static String ID_XE = "XE"; final private static String ID_YE = "YE"; final private static String ID_WE = "WidthE"; final private static String ID_HE = "HeightE"; final private static String ID_MAXIMIZEDE = "MaximizedE"; final XMLPreferences preferences; final private MainFrame mainFrame; final private IcyFrame icyFrame; final private ExternalizablePanel extPanel; final private JFrame jFrame; final private JComponent component; final private boolean hasLoc; final private boolean hasDim; final WindowAdapter windowAdapter; final IcyFrameAdapter icyFrameAdapter; final ComponentAdapter componentAdapter; final StateListener stateListener; private WindowPositionSaver(final MainFrame mainFrame, final IcyFrame icyFrame, final ExternalizablePanel extPanel, final JFrame jFrame, final JComponent component, final String key, final Point defLoc, final Dimension defDim) { preferences = IcyPreferences.root().node(key); this.mainFrame = mainFrame; this.icyFrame = icyFrame; this.extPanel = extPanel; this.jFrame = jFrame; this.component = component; hasLoc = defLoc != null; hasDim = defDim != null; // directly load location and dimension if (hasLoc) loadLocation(defLoc); if (hasDim) loadDimension(defDim); loadState(); // keep hard reference on it componentAdapter = new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { // event comes from panel itself if ((extPanel == null) || (e.getSource() == extPanel)) saveAll(); } @Override public void componentMoved(ComponentEvent e) { // event comes from panel itself if ((extPanel == null) || (e.getSource() == extPanel)) saveAll(); } @Override public void componentShown(ComponentEvent e) { // correctly save internalized / externalized state saveAll(); } @Override public void componentHidden(ComponentEvent e) { // correctly save internalized / externalized state saveAll(); } }; // keep hard reference on it windowAdapter = new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { saveAll(); } }; // keep hard reference on it icyFrameAdapter = new IcyFrameAdapter() { @Override public void icyFrameClosing(IcyFrameEvent e) { saveAll(); } }; // keep hard reference on it stateListener = new StateListener() { @Override public void stateChanged(ExternalizablePanel source, boolean externalized) { saveAll(); } }; if (mainFrame != null) { mainFrame.addWindowListener(new WeakWindowListener(windowAdapter)); mainFrame.addComponentListener(new WeakComponentListener(componentAdapter)); } else if (icyFrame != null) { icyFrame.addFrameListener(new WeakIcyFrameListener(icyFrameAdapter)); icyFrame.addComponentListener(new WeakComponentListener(componentAdapter)); } else if (extPanel != null) { extPanel.addComponentListener(new WeakComponentListener(componentAdapter)); extPanel.addStateListener(new WeakStateListener(stateListener)); extPanel.getFrame().addFrameListener(new WeakIcyFrameListener(icyFrameAdapter)); extPanel.getFrame().addComponentListener(new WeakComponentListener(componentAdapter)); } else if (jFrame != null) { jFrame.addWindowListener(new WeakWindowListener(windowAdapter)); jFrame.addComponentListener(new WeakComponentListener(componentAdapter)); } else if (component != null) { component.addComponentListener(new WeakComponentListener(componentAdapter)); } } public WindowPositionSaver(MainFrame frame, String key, Point defLoc, Dimension defDim) { this(frame, null, null, null, null, key, defLoc, defDim); } public WindowPositionSaver(MainFrame frame, String key, Point defLoc) { this(frame, null, null, null, null, key, defLoc, null); } public WindowPositionSaver(MainFrame frame, String key, Dimension defDim) { this(frame, null, null, null, null, key, null, defDim); } public WindowPositionSaver(IcyFrame frame, String key, Point defLoc, Dimension defDim) { this(null, frame, null, null, null, key, defLoc, defDim); } public WindowPositionSaver(IcyFrame frame, String key, Point defLoc) { this(null, frame, null, null, null, key, defLoc, null); } public WindowPositionSaver(IcyFrame frame, String key, Dimension defDim) { this(null, frame, null, null, null, key, null, defDim); } public WindowPositionSaver(ExternalizablePanel extPanel, String key, Point defLoc, Dimension defDim) { this(null, null, extPanel, null, null, key, defLoc, defDim); } public WindowPositionSaver(ExternalizablePanel extPanel, String key, Point defLoc) { this(null, null, extPanel, null, null, key, defLoc, null); } public WindowPositionSaver(ExternalizablePanel extPanel, String key, Dimension defDim) { this(null, null, extPanel, null, null, key, null, defDim); } public WindowPositionSaver(JFrame frame, String key, Point defLoc, Dimension defDim) { this(null, null, null, frame, null, key, defLoc, defDim); } public WindowPositionSaver(JFrame frame, String key, Point defLoc) { this(null, null, null, frame, null, key, defLoc, null); } public WindowPositionSaver(JFrame frame, String key, Dimension defDim) { this(null, null, null, frame, null, key, null, defDim); } public WindowPositionSaver(JComponent component, String key, Point defLoc, Dimension defDim) { this(null, null, null, null, component, key, defLoc, defDim); } public WindowPositionSaver(JComponent component, String key, Point defLoc) { this(null, null, null, null, component, key, defLoc, null); } public WindowPositionSaver(JComponent component, String key, Dimension defDim) { this(null, null, null, null, component, key, null, defDim); } // void checkPosition() // { // final Rectangle rect; // // ComponentUtil.fixPosition(rect, rect); // // // only for frame // if (mainFrame != null) // ComponentUtil.fixP // rect = mainFrame.getBounds(); // else if (icyFrame != null) // rect = icyFrame.getBounds(); // // check position only for frame // else if ((extPanel != null) && extPanel.isExternalized()) // rect = extPanel.getFrame().getBounds(); // else if (jFrame != null) // rect = jFrame.getBounds(); // else // return; // // if (fixPosition(rect)) // { // if (mainFrame != null) // mainFrame.setBounds(rect); // else if (icyFrame != null) // icyFrame.setBounds(rect); // // check position only for frame // else if ((extPanel != null) && extPanel.isExternalized()) // extPanel.getFrame().setBounds(rect); // else if (jFrame != null) // jFrame.setBounds(rect); // } // } // // public static boolean fixPosition(Rectangle rect) // { // Rectangle desktopRect = SystemUtil.getDesktopBounds(); // boolean result = false; // int limit; // // limit = (int) (desktopRect.getMaxX() - DESKTOP_MARGIN); // if (rect.x >= limit) // { // rect.x = limit; // result = true; // } // else // { // limit = (int) desktopRect.getMinX(); // if (((rect.x + rect.width) - DESKTOP_MARGIN) < limit) // { // rect.x = DESKTOP_MARGIN - rect.width; // result = true; // } // } // limit = (int) (desktopRect.getMaxY() - DESKTOP_MARGIN); // if (rect.y >= limit) // { // rect.y = limit; // result = true; // } // else // { // limit = (int) desktopRect.getMinY(); // if (rect.y < limit) // { // rect.y = limit; // result = true; // } // } // // return result; // } public XMLPreferences getPreferences() { return preferences; } public void loadLocation(Point defaultPos) { final int x, y; if (defaultPos == null) { x = 0; y = 0; } else { x = defaultPos.x; y = defaultPos.y; } final Point positionC = new Point(preferences.getInt(ID_XC, x), preferences.getInt(ID_YC, y)); final Point positionI = new Point(preferences.getInt(ID_XI, x), preferences.getInt(ID_YI, y)); final Point positionE = new Point(preferences.getInt(ID_XE, x), preferences.getInt(ID_YE, y)); if (mainFrame != null) { mainFrame.setLocation(positionE); } else if (icyFrame != null) { icyFrame.setLocationInternal(positionI); icyFrame.setLocationExternal(positionE); } else if (extPanel != null) { extPanel.setLocation(positionC); // get the panel frame final IcyFrame f = extPanel.getFrame(); f.setLocationInternal(positionI); f.setLocationExternal(positionE); } else if (jFrame != null) { jFrame.setLocation(positionE); } else if (component != null) { component.setLocation(positionC); } } public void loadDimension(Dimension defaultDim) { final int w, h; if (defaultDim == null) { w = 300; h = 300; } else { w = defaultDim.width; h = defaultDim.height; } // minimum size is 10 pixels int widthC = Math.max(preferences.getInt(ID_WC, w), 10); int heightC = Math.max(preferences.getInt(ID_HC, h), 10); int widthI = Math.max(preferences.getInt(ID_WI, w), 10); int heightI = Math.max(preferences.getInt(ID_HI, h), 10); int widthE = Math.max(preferences.getInt(ID_WE, w), 10); int heightE = Math.max(preferences.getInt(ID_HE, h), 10); final Dimension dimC = new Dimension(widthC, heightC); final Dimension dimI = new Dimension(widthI, heightI); final Dimension dimE = new Dimension(widthE, heightE); if (mainFrame != null) { // set size only else we cannot pack anymore the frame for detached mode mainFrame.setSize(dimE); } else if (icyFrame != null) { icyFrame.setPreferredSizeExternal(dimE); icyFrame.setSizeExternal(dimE); icyFrame.setPreferredSizeInternal(dimI); icyFrame.setSizeInternal(dimI); } else if (extPanel != null) { extPanel.setPreferredSize(dimC); // get the panel frame final IcyFrame f = extPanel.getFrame(); f.setPreferredSizeExternal(dimE); f.setSizeExternal(dimE); f.setPreferredSizeInternal(dimI); f.setSizeInternal(dimI); } else if (jFrame != null) { jFrame.setPreferredSize(dimE); jFrame.setSize(dimE); } else if (component != null) { component.setPreferredSize(dimC); } } public void loadState() { // default is internalized and panelized final boolean externalized = preferences.getBoolean(ID_EXTERNALIZED, false); final boolean panelized = preferences.getBoolean(ID_PANELIZED, true); final boolean maximizedE = preferences.getBoolean(ID_MAXIMIZEDE, false); final boolean maximizedI = preferences.getBoolean(ID_MAXIMIZEDI, false); if (mainFrame != null) { ComponentUtil.setMaximized(mainFrame, maximizedE); } else if (icyFrame != null) { if (externalized) icyFrame.externalize(); else icyFrame.internalize(); icyFrame.setMaximizedExternal(maximizedE); icyFrame.setMaximizedInternal(maximizedI); } else if (extPanel != null) { // get the panel frame final IcyFrame f = extPanel.getFrame(); if (externalized) f.externalize(); else f.internalize(); f.setMaximizedExternal(maximizedE); f.setMaximizedInternal(maximizedI); if (panelized) extPanel.internalize(); else extPanel.externalize(); } else if (jFrame != null) { ComponentUtil.setMaximized(jFrame, maximizedE); } } public void saveLocation() { if (mainFrame != null) { if (!(ComponentUtil.isMaximized(mainFrame) || ComponentUtil.isMinimized(mainFrame))) { preferences.putInt(ID_XE, mainFrame.getX()); preferences.putInt(ID_YE, mainFrame.getY()); } } else if (icyFrame != null) { if (!(icyFrame.isMaximizedExternal() || icyFrame.isMinimizedExternal())) { preferences.putInt(ID_XE, icyFrame.getXExternal()); preferences.putInt(ID_YE, icyFrame.getYExternal()); } if (!(icyFrame.isMaximizedInternal() || icyFrame.isMinimizedInternal())) { preferences.putInt(ID_XI, icyFrame.getXInternal()); preferences.putInt(ID_YI, icyFrame.getYInternal()); } } else if (extPanel != null) { preferences.putInt(ID_XC, extPanel.getX()); preferences.putInt(ID_YC, extPanel.getY()); // get the panel frame final IcyFrame f = extPanel.getFrame(); if (!(f.isMaximizedExternal() || f.isMinimizedExternal())) { preferences.putInt(ID_XE, f.getXExternal()); preferences.putInt(ID_YE, f.getYExternal()); } if (!(f.isMaximizedInternal() || f.isMinimizedInternal())) { preferences.putInt(ID_XI, f.getXInternal()); preferences.putInt(ID_YI, f.getYInternal()); } } else if (jFrame != null) { if (!(ComponentUtil.isMaximized(jFrame) || ComponentUtil.isMinimized(jFrame))) { preferences.putInt(ID_XE, jFrame.getX()); preferences.putInt(ID_YE, jFrame.getY()); } } else if (component != null) { preferences.putInt(ID_XC, component.getX()); preferences.putInt(ID_YC, component.getY()); } } public void saveDimension() { if (mainFrame != null) { if (!(ComponentUtil.isMaximized(mainFrame) || ComponentUtil.isMinimized(mainFrame))) { final Dimension dim; if (mainFrame.isDetachedMode()) dim = new Dimension(mainFrame.getWidth(), mainFrame.getPreviousHeight()); else dim = mainFrame.getSize(); preferences.putInt(ID_WE, dim.width); preferences.putInt(ID_HE, dim.height); } } else if (icyFrame != null) { if (!(icyFrame.isMaximizedExternal() || icyFrame.isMinimizedExternal())) { preferences.putInt(ID_WE, icyFrame.getWidthExternal()); preferences.putInt(ID_HE, icyFrame.getHeightExternal()); } if (!(icyFrame.isMaximizedInternal() || icyFrame.isMinimizedInternal())) { preferences.putInt(ID_WI, icyFrame.getWidthInternal()); preferences.putInt(ID_HI, icyFrame.getHeightInternal()); } } else if (extPanel != null) { preferences.putInt(ID_WC, extPanel.getWidth()); preferences.putInt(ID_HC, extPanel.getHeight()); // get the panel frame final IcyFrame f = extPanel.getFrame(); if (!(f.isMaximizedExternal() || f.isMinimizedExternal())) { preferences.putInt(ID_WE, f.getWidthExternal()); preferences.putInt(ID_HE, f.getHeightExternal()); } if (!(f.isMaximizedInternal() || f.isMinimizedInternal())) { preferences.putInt(ID_WI, f.getWidthInternal()); preferences.putInt(ID_HI, f.getHeightInternal()); } } else if (jFrame != null) { if (!(ComponentUtil.isMaximized(jFrame) || ComponentUtil.isMinimized(jFrame))) { preferences.putInt(ID_WE, jFrame.getWidth()); preferences.putInt(ID_HE, jFrame.getHeight()); } } else if (component != null) { preferences.putInt(ID_WC, component.getWidth()); preferences.putInt(ID_HC, component.getHeight()); } } public void saveState() { if (mainFrame != null) { final boolean b; if (mainFrame.isDetachedMode()) b = mainFrame.getPreviousMaximized(); else b = ComponentUtil.isMaximized(mainFrame); preferences.putBoolean(ID_MAXIMIZEDE, b); } if (icyFrame != null) { preferences.putBoolean(ID_EXTERNALIZED, icyFrame.isExternalized()); preferences.putBoolean(ID_MAXIMIZEDI, icyFrame.isMaximizedInternal()); preferences.putBoolean(ID_MAXIMIZEDE, icyFrame.isMaximizedExternal()); } else if (extPanel != null) { preferences.putBoolean(ID_PANELIZED, extPanel.isInternalized()); // get the panel frame final IcyFrame f = extPanel.getFrame(); preferences.putBoolean(ID_EXTERNALIZED, f.isExternalized()); preferences.putBoolean(ID_MAXIMIZEDI, f.isMaximizedInternal()); preferences.putBoolean(ID_MAXIMIZEDE, f.isMaximizedExternal()); } else if (jFrame != null) { preferences.putBoolean(ID_MAXIMIZEDE, ComponentUtil.isMaximized(jFrame)); } } public void saveAll() { if (hasLoc) saveLocation(); if (hasDim) saveDimension(); saveState(); } }