Package org.gocha.gui

Source Code of org.gocha.gui.GuiKeeper

/*******************************************************************************
gocha.org-lib-java Библеотека общего назначения
(с) Камнев Георгий Павлович 2010 GPLv2

Данная программа является свободным программным обеспечением. Вы вправе
распространять ее и/или модифицировать в соответствии с условиями версии 2
либо по вашему выбору с условиями более поздней версии
Стандартной Общественной Лицензии GNU, опубликованной Free Software Foundation.

Мы распространяем данную программу в надежде на то, что она будет вам полезной,
однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ,
в том числе ГАРАНТИИ ТОВАРНОГО СОСТОЯНИЯ ПРИ ПРОДАЖЕ
и ПРИГОДНОСТИ ДЛЯ ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ.
Для получения более подробной информации ознакомьтесь
со Стандартной Общественной Лицензией GNU.

Вместе с данной программой вы должны были получить экземпляр
Стандартной Общественной Лицензии GNU.
Если вы его не получили, сообщите об этом в Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*******************************************************************************/

package org.gocha.gui;

import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import org.gocha.types.PropertyController;
import org.gocha.types.ToStringConverter;
import org.gocha.types.ToValueConvertor;
import org.gocha.types.ValueController;

/**
* Хранит свойства указанного обекта в текстовом файле в виде ключ/значение. <br/>
* Сохраняет состояние объекта (компонента awt) при закрытии окна (и смене видимости)
* ; записывает в файл при выходе (ApplicationGlobal.fireExit).
* @author gocha
* @see org.gocha.gui.ApplicationGlobal#fireExit(java.lang.Object)
*/
public class GuiKeeper implements Closeable
{
    private Object owner = null;
    private String[] ownerProperties = null;
    private String propertyPrefix = null;

    /**
     * Конструктор
     */
    private GuiKeeper(){
        initSave();
    }

    @Override
    protected void finalize() throws Throwable
    {
        try{
            close();
//            System.out.println("GuiKeeper.finalize");
        }catch(IOException e){
        }
        super.finalize();
    }

    /**
     * Сохраняет указанные свойства и отключает слушателей
     * @throws IOException Ошибка сохранения
     */
    @Override
    public void close() throws IOException
    {
        if( owner==null )return;
        if( ownerProperties==null )return;

        if( owner instanceof JComponent ){
            ((JComponent)owner).removeAncestorListener(ancestorListener);
        }

        if( owner instanceof Window ){
            ((Window)owner).removeWindowListener(windowListener);
        }

        storeProperties();

        owner = null;
        ownerProperties = null;
        propertyPrefix = null;
    }

    private static Collection<GuiKeeper> keepers = new HashSet<GuiKeeper>();

    /**
     * Создает хранителя свойств указанного объекта
     * @param propertyPrefix Префикс
     * @param owner Объект
     * @param properties Свойства
     * @return Хранит свойства
     */
    public static GuiKeeper keepProperties(Runnable failedRestore,JFrame owner,String ... properties){
        if (owner == null) {
            throw new IllegalArgumentException("owner == null");
        }
        return keepProperties(failedRestore, owner.getClass().getName()+":", owner, properties );
    }

    public static Runnable centerWindow(Window wnd){
        return centerWindow(wnd, -1, -1);
    }

    public static Runnable centerWindow(Window wnd,double widthAspect,double heightAspect){
        if (wnd == null) {
            throw new IllegalArgumentException("wnd==null");
        }

        final Window _wnd = wnd;
        final double _widthAspect = widthAspect;
        final double _heightAspect = heightAspect;

        final WindowListener l = new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e)
            {
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                int screenX = ge.getCenterPoint().x * 2;
                int screenY = ge.getCenterPoint().y * 2;

                int newWidth = -1;
                int newHeight = -1;
                if( _widthAspect>=0 ) newWidth = (int)((double)screenX * _widthAspect);
                if( _heightAspect>=0 ) newHeight = (int)((double)screenY * _heightAspect);
                if( newWidth==0 )newWidth = 1;
                if( newHeight==0 )newHeight = 1;

                Dimension size = _wnd.getSize();
                if( newWidth > 0 ) size.width = newWidth;
                if( newHeight > 0 ) size.height = newHeight;
                if( newWidth > 0 || newHeight>0 )_wnd.setSize(size);

                GuiUtil.centerWindow(_wnd);
                _wnd.removeWindowListener(this);
            }
        };

        Runnable r = new Runnable() {
            @Override
            public void run() {
                _wnd.addWindowListener(l);
            }
        };

        return r;
    }

    public static GuiKeeper keepLocationAndSize(Window wnd){
        if (wnd == null) {
            throw new IllegalArgumentException("wnd == null");
        }
        final Window w = wnd;
        final WindowListener l = new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e)
            {
                GuiUtil.centerWindow(w);
                w.removeWindowListener(this);
            }
        };
        Runnable f = new Runnable() {
            @Override
            public void run()
            {
                if( !w.isVisible() ){
                    w.addWindowListener(l);
                }
            }
        };
        return keepProperties(f, wnd.getClass().getName()+":", wnd, "location", "size");
    }

    /**
     * Создает хранителя свойств указанного объекта
     * @param propertyPrefix Префикс
     * @param owner Объект
     * @param properties Свойства
     * @return Хранит свойства
     */
    public static GuiKeeper keepProperties(Runnable failedRestore,String propertyPrefix,Object owner,String ... properties){
        if (owner == null) {
            throw new IllegalArgumentException("owner == null");
        }
        GuiKeeper keeper = new GuiKeeper();
        keeper.owner = owner;
        keeper.ownerProperties = properties;
        keeper.propertyPrefix = propertyPrefix;
        keeper.restoreProperties(failedRestore);
       
        if( owner instanceof JComponent ){
            ((JComponent)owner).addAncestorListener(keeper.ancestorListener);
        }

        if( owner instanceof Window ){
            ((Window)owner).addWindowListener(keeper.windowListener);
        }

        keepers.add(keeper);

        return keeper;
    }

    private AncestorListener ancestorListener = new AncestorListener() {
        @Override
        public void ancestorAdded(AncestorEvent event){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void ancestorRemoved(AncestorEvent event){
            storeProperties();
        }
        @Override
        public void ancestorMoved(AncestorEvent event){
            storeProperties();
        }
    };

    private WindowListener windowListener = new WindowListener() {
        @Override
        public void windowOpened(WindowEvent e){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void windowClosing(WindowEvent e){
            storeProperties();
        }
        @Override
        public void windowClosed(WindowEvent e){
            storeProperties();
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void windowIconified(WindowEvent e){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void windowDeiconified(WindowEvent e){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void windowActivated(WindowEvent e){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public void windowDeactivated(WindowEvent e){
//            throw new UnsupportedOperationException("Not supported yet.");
        }
    };

    private org.gocha.types.TypesConverters convertors = org.gocha.types.DefaultTypesConvertors.instance();
   
    public void restoreProperties(Runnable failedRestore){
        if( owner==null )return;
        if( ownerProperties==null )return;

        int restoreCount = 0;
        for( ValueController vc : PropertyController.buildControllers(owner) ){
            String propName = vc.getName();
            boolean setProperty = false;
            for( String p : ownerProperties ){
                if( p==null )continue;
                if( p.equals(propName) ){
                    setProperty = true;
                }
            }
            if( !setProperty )continue;

            String key = propertyPrefix==null ? propName : propertyPrefix + propName;
            String textValue = getProperty(key);
            if( textValue==null )continue;

            ToValueConvertor conv = convertors.toValueFor(vc.getType());
            if( conv==null )continue;

            try{
                Object objValue = conv.convertToValue(textValue);
                if( objValue==null )continue;
                vc.setValue(objValue);
                restoreCount++;
            }catch(Throwable e){
                Logger.getLogger(GuiKeeper.class.getName()).log(Level.WARNING,null,e);
            }
        }

        if( restoreCount<ownerProperties.length ){
            if( failedRestore!=null )failedRestore.run();
        }
    }
   
    public void storeProperties(){
        if( owner==null )return;
        if( ownerProperties==null )return;

        for( ValueController vc : PropertyController.buildControllers(owner) ){
            String propName = vc.getName();
            boolean getProperty = false;
            for( String p : ownerProperties ){
                if( p==null )continue;
                if( p.equals(propName) ){
                    getProperty = true;
                }
            }
            if( !getProperty )continue;

            ToStringConverter conv = convertors.toStringFrom(vc.getType());
            if( conv==null )continue;

            try{
                Object objValue = vc.getValue();
                if( objValue==null )continue;

                String key = propertyPrefix==null ? propName : propertyPrefix + propName;
                String textValue = conv.convertToString(objValue);
                if( textValue==null )continue;

                setProperty(key, textValue);
            }catch(Throwable e){
                Logger.getLogger(GuiKeeper.class.getName()).log(Level.WARNING,null,e);
            }
        }
    }
   
    private final static String fileName = "guiKeeper.xml";
    private static File file = null;

    private static File file(){
        if( file==null ){
            File dir = ApplicationGlobal.instance().getLocalApplicationDirectory();
            if( dir!=null ){
                file = new File(dir,fileName);
            }else{
                Logger.getLogger(GuiKeeper.class.getName()).log(Level.SEVERE,"Не указан каталог appDir, или указан не верно");
            }
        }
        return file;
    }

    private void initSave(){
        if( attachedSaved )return;
        AutoClose.instance().add(saveOnExit);
        attachedSaved = true;
    }
   
    private static boolean attachedSaved = false;

    private static Runnable saveOnExit = new Runnable() {
        @Override
        public void run(){
            for( GuiKeeper k : keepers ){
                try{
                    k.close();
                }catch(IOException e){}
            }
            keepers.clear();
            savePropertiesToFile();
        }
    };

    private static void setProperty(String key,String value){
        if( key==null )return;
        if( value==null ){
            properties().remove(key);
            return;
        }
        properties().put(key, value);
    }

    private static String getProperty(String key){
        if( key==null )return key;
        return properties().getProperty(key);
    }

    private static Properties properties = null;
    private static Properties properties(){
        if( properties!=null )return properties;
        properties = new Properties();
        File f = file();
        if( f!=null && f.exists() && f.canRead() && f.isFile() ){
            FileInputStream fis = null;
            try{
                fis = new FileInputStream(f);
                properties.loadFromXML(fis);
                fis.close();
            }catch(Exception e){
                Logger.getLogger(GuiKeeper.class.getName()).log(Level.SEVERE,null,e);
            }
        }
        return properties;
    }

    private static boolean savePropertiesToFile(){
        File f = file();
        if( f==null )return false;
       
        if( properties==null ){
            if( f.exists() && f.isFile() && f.canWrite() ){
                try{
                    f.delete();
                }catch(Exception e){
                    Logger.getLogger(GuiKeeper.class.getName()).log(Level.SEVERE,null,e);
                }
            }
            return true;
        }
       
        boolean overwrite = false;
        if( f.exists() && f.isFile() && f.canWrite() )overwrite = true;
        if( !f.exists() )overwrite = true;
        if( overwrite ){
            FileOutputStream fos = null;
            try{
                fos = new FileOutputStream(f);
                properties.storeToXML(fos, "gui properties");
                fos.close();
                return true;
            }catch(Exception e){
                Logger.getLogger(GuiKeeper.class.getName()).log(Level.SEVERE,null,e);
            }
        }else{
            Logger.getLogger(GuiKeeper.class.getName()).warning("can't overwrite "+f.toString());
        }
        return false;
    }
}
TOP

Related Classes of org.gocha.gui.GuiKeeper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.