001package jmri.jmrix.configurexml;
002
003import javax.swing.UIManager;
004import javax.swing.UnsupportedLookAndFeelException;
005import jmri.configurexml.AbstractXmlAdapter;
006import jmri.configurexml.ConfigXmlManager;
007import jmri.configurexml.XmlAdapter;
008import jmri.jmrix.ConnectionConfig;
009import jmri.jmrix.JmrixConfigPane;
010import org.jdom2.Element;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Handle XML persistance of layout connections.
016 * <p>
017 * This class is named as being the persistant form of the JmrixConfigPane
018 * class, but there's no object of that form created or used. Instead, this
019 * interacts forwards to a similar class in one of the protocol-specific
020 * packages, e.g. jmrix.easydcc.serialdriver.configurexml
021 *
022 * @author Bob Jacobsen Copyright: Copyright (c) 2003
023 */
024public class JmrixConfigPaneXml extends AbstractXmlAdapter {
025
026    public JmrixConfigPaneXml() {
027    }
028
029    /**
030     * Forward to the configurexml class for the specific object type.
031     */
032    @Override
033    public Element store(Object o) {
034        ConnectionConfig oprime = ((JmrixConfigPane) o).getCurrentObject();
035        if (oprime == null) {
036            return null;
037        }
038        String adapter = ConfigXmlManager.adapterName(oprime);
039        log.debug("forward to {}", adapter);
040        try {
041            XmlAdapter x = (XmlAdapter) Class.forName(adapter).getDeclaredConstructor().newInstance();
042            return x.store(oprime);
043        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | java.lang.reflect.InvocationTargetException e) {
044            log.error("Exception: ", e);
045            return null;
046        }
047    }
048
049    @Override
050    public Element store(Object o, boolean shared) {
051        return this.store(o);
052    }
053
054    @Override
055    public boolean load(Element shared, Element perNode) {
056        boolean result = true;
057        UIManager.LookAndFeelInfo[] plafs = UIManager.getInstalledLookAndFeels();
058        java.util.Hashtable<String, String> installedLAFs = new java.util.Hashtable<String, String>(plafs.length);
059        for (UIManager.LookAndFeelInfo plaf : plafs) {
060            installedLAFs.put(plaf.getName(), plaf.getClassName());
061        }
062        String name = shared.getAttribute("LAFclass").getValue();
063        String className = installedLAFs.get(name);
064        log.debug("GUI selection: {} class name: {}", name, className);
065        // set the GUI
066        if (className != null) {
067            try {
068                if (!className.equals(UIManager.getLookAndFeel().getClass().getName())) {
069                    log.debug("set GUI to {},{}", name, className);
070                    updateLookAndFeel(name, className);
071                } else {
072                    log.debug("skip updateLAF as already has className=={}", className);
073                }
074            } catch (Exception ex) {
075                log.error("Exception while setting GUI look & feel", ex);
076                result = false;
077            }
078        }
079        return result;
080    }
081
082    /**
083     * Change the look-and-feel to the specified class. Alert the user if there
084     * were problems loading the PLAF.
085     *
086     * @param name      (String) the presentable name for the class
087     * @param className (String) the className to be fed to the UIManager
088     */
089    public void updateLookAndFeel(String name, String className) {
090        try {
091            // Set the new look and feel, and update the sample message to reflect it.
092            UIManager.setLookAndFeel(className);
093        } catch (Exception e) {
094            String errMsg;
095            if (e instanceof UnsupportedLookAndFeelException) {
096                errMsg = "is not supported on this platform.";
097            } else if (e instanceof ClassNotFoundException) {
098                errMsg = "could not be found.";
099            } else {
100                errMsg = "could not be loaded.";
101            }
102
103            log.error("The {} look-and-feel {}",name,errMsg);
104
105        }
106    }
107
108    /**
109     * Update static data from XML file
110     *
111     * @param element Top level Element to unpack.
112     * @param o       ignored
113     */
114    @Override
115    public void load(Element element, Object o) {
116        jmri.jmrit.symbolicprog.ProgDefault.setDefaultProgFile(element.getAttribute("defaultFile").getValue());
117    }
118
119    // initialize logging
120    private final static Logger log = LoggerFactory.getLogger(JmrixConfigPaneXml.class);
121
122}