001package jmri.jmrit.swing.meter.configurexml; 002 003import java.awt.GraphicsEnvironment; 004import java.util.List; 005import java.util.UUID; 006 007import jmri.InstanceManager; 008import jmri.Meter; 009import jmri.MeterManager; 010import jmri.configurexml.JmriConfigureXmlException; 011import jmri.jmrit.swing.meter.MeterFrame; 012import jmri.jmrit.swing.meter.MeterFrameManager; 013 014import org.jdom2.Attribute; 015import org.jdom2.Element; 016 017import javax.annotation.Nonnull; 018 019/** 020 * Stores MeterFrames to the panel file. 021 * @author Daniel Bergqvist Copyright (c) 2020 022 */ 023public class MeterFrameManagerXml extends jmri.configurexml.AbstractXmlAdapter { 024 025 private final EnumIO<MeterFrame.Unit> unitEnumMap = new EnumIoNames<>(MeterFrame.Unit.class); 026 027 public MeterFrameManagerXml() { 028 } 029 030 @Override 031 public Element store(Object o) { 032 Element meterFrames = new Element("meterFrames"); 033 setStoreElementClass(meterFrames); 034 035 for (MeterFrame frame : MeterFrameManager.getInstance().getMeterFrames()) { 036 meterFrames.addContent(storeMeterFrame(frame)); 037 } 038 039 return meterFrames; 040 } 041 042 public Element storeMeterFrame(MeterFrame frame) { 043 Element e = new Element("meterFrame"); 044 045 Element e2 = new Element("uuid"); 046 e2.addContent(frame.getUUID().toString()); 047 e.addContent(e2); 048 049 e2 = new Element("meter"); 050 if (frame.getMeter() == null) { 051 return e; // apparently user did not assign a real world meter; do not save 052 } 053 e2.addContent(frame.getMeter().getSystemName()); // this should be a NamedBeanHandle 054 e.addContent(e2); 055 056 e.setAttribute("unit", unitEnumMap.outputFromEnum(frame.getUnit())); 057 e.setAttribute("integer-digits", Integer.toString(frame.getNumIntegerDigits())); 058 e.setAttribute("decimal-digits", Integer.toString(frame.getNumDecimalDigits())); 059 e.setAttribute("x", Integer.toString(frame.getX())); 060 e.setAttribute("y", Integer.toString(frame.getY())); 061 e.setAttribute("width", Integer.toString(frame.getWidth())); 062 e.setAttribute("height", Integer.toString(frame.getHeight())); 063 064 return e; 065 } 066 067 /** 068 * Subclass provides implementation to create the correct top element, 069 * including the type information. Default implementation is to use the 070 * local class here. 071 * 072 * @param meterFrames The top-level element being created 073 */ 074 public void setStoreElementClass(Element meterFrames) { 075 meterFrames.setAttribute("class", this.getClass().getName()); // NOI18N 076 } 077 078 /** {@inheritDoc} */ 079 @Override 080 public boolean load(@Nonnull Element shared, Element perNode) throws JmriConfigureXmlException { 081 // Don't create frames if headless 082 if (GraphicsEnvironment.isHeadless()) return true; 083 084 List<Element> frames = shared.getChildren("meterFrame"); 085 086 for (Element elem : frames) { 087 String uuidStr = elem.getChild("uuid").getText(); 088 String meterSystemName = elem.getChild("meter").getText(); // This should be a NamedBeanHandle, but may not exist yet 089 Meter meter = InstanceManager.getDefault(MeterManager.class).getBySystemName(meterSystemName); 090 UUID uuid = UUID.fromString(uuidStr); 091 MeterFrame frame = MeterFrameManager.getInstance().getByUUID(uuid); 092 if (frame == null) { 093 log.debug("creating frame for uuid: {}, selected meter: {}", uuidStr, meterSystemName); 094 frame = new MeterFrame(uuid); 095 frame.initComponents(); 096 } 097 if (meter != null) { 098 frame.setMeter(meter); 099 } else { 100 log.debug("selected meter '{}' not (yet) defined, remembering for later.", meterSystemName); 101 frame.setInitialMeterName(meterSystemName); 102 } 103 104 Attribute a = elem.getAttribute("unit"); 105 if (a != null) frame.setUnit(unitEnumMap.inputFromAttribute(a)); 106 107 frame.setNumIntegerDigits(getAttributeIntegerValue(elem, "integer-digits", 3)); 108 frame.setNumDecimalDigits(getAttributeIntegerValue(elem, "decimal-digits", 0)); 109 110 frame.setLocation( 111 Integer.parseInt(elem.getAttributeValue("x")), 112 Integer.parseInt(elem.getAttributeValue("y"))); 113 frame.setSize( 114 Integer.parseInt(elem.getAttributeValue("width")), 115 Integer.parseInt(elem.getAttributeValue("height"))); 116 frame.setVisible(true); 117 } 118 119 return true; 120 } 121 122 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MeterFrameManagerXml.class); 123 124}