package info.opencards.ui; import com.thoughtworks.xstream.XStream; import info.opencards.Utils; import java.awt.*; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.util.HashMap; import java.util.Map; import java.util.prefs.Preferences; /** * Manages persistent window layouts over different sessions. * * @author Holger Brandl */ public class LayoutRestorer extends ComponentAdapter { private static LayoutRestorer instance; private final Map<Component, String> windows2Names = new HashMap<Component, String>(); /** * Returns a new ConfigurationManager or a previously created one. */ public synchronized static LayoutRestorer getInstance() { if (instance == null) instance = new LayoutRestorer(); return instance; } /** * Request the window-layout of a window called <code>windowName</code>. */ public Rectangle getBounds(String windowName, Component comp, Rectangle rect) { assert windowName != null; Rectangle winBounds = null; String xmlBound = Utils.getPrefs().get(windowName, null); if (xmlBound != null) winBounds = (Rectangle) new XStream().fromXML(xmlBound); if (winBounds == null || isOutOfScreen(winBounds)) { if (rect == null) rect = new Rectangle(100, 100, 200, 150); // create new instance, put it into the map an serialize it winBounds = new Rectangle(rect); updateLayout(windowName, winBounds); } assert comp != null; comp.addComponentListener(this); windows2Names.put(comp, windowName); return winBounds; } private boolean isOutOfScreen(Rectangle winBounds) { boolean isInScreen = false; for (GraphicsDevice graphDevice : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) { if (graphDevice.getDefaultConfiguration().getBounds().contains(winBounds)) isInScreen = true; } return !isInScreen; } private void updateLayout(String windowName, Rectangle winBounds) { Preferences preferences = Utils.getPrefs(); preferences.put(windowName, new XStream().toXML(winBounds)); // Utils.flushPrefs(); } public void componentResized(ComponentEvent e) { compLayoutChanged(e); } public void componentMoved(ComponentEvent e) { compLayoutChanged(e); } private void compLayoutChanged(ComponentEvent e) { Component comp = e.getComponent(); String curWinName = windows2Names.get(comp); Rectangle curBounds = comp.getBounds(); updateLayout(curWinName, curBounds); } }