001package jmri.jmrit.display.layoutEditor.configurexml; 002 003import java.awt.Color; 004import java.util.List; 005 006import javax.swing.JFrame; 007 008import jmri.ConfigureManager; 009import jmri.InstanceManager; 010import jmri.configurexml.AbstractXmlAdapter; 011import jmri.configurexml.XmlAdapter; 012import jmri.jmrit.dispatcher.DispatcherFrame; 013import jmri.jmrit.display.EditorManager; 014import jmri.jmrit.display.Positionable; 015import jmri.jmrit.display.layoutEditor.*; 016import jmri.util.ColorUtil; 017import jmri.util.swing.JmriJOptionPane; 018 019import org.jdom2.*; 020 021/** 022 * Handle configuration for LayoutEditor panes. 023 * <p> 024 * Based in part on PanelEditorXml.java 025 * 026 * @author Dave Duchamp Copyright (c) 2007 027 * @author George Warner Copyright (c) 2017-2018 028 */ 029public class LayoutEditorXml extends AbstractXmlAdapter { 030 031 public LayoutEditorXml() { 032 } 033 034 /** 035 * Default implementation for storing the contents of a LayoutEditor. 036 * 037 * @param o Object to store, of type LayoutEditor 038 * @return Element containing the complete info 039 */ 040 @Override 041 public Element store(Object o) { 042 LayoutEditor p = (LayoutEditor) o; 043 044 Element panel = new Element("LayoutEditor"); 045 046 panel.setAttribute("class", getClass().getName()); 047 panel.setAttribute("name", p.getLayoutName()); 048 if (InstanceManager.getDefault(jmri.util.gui.GuiLafPreferencesManager.class).isEditorUseOldLocSize()) { 049 panel.setAttribute("x", "" + p.gContext.getUpperLeftX()); 050 panel.setAttribute("y", "" + p.gContext.getUpperLeftY()); 051 panel.setAttribute("windowheight", "" + p.gContext.getWindowHeight()); 052 panel.setAttribute("windowwidth", "" + p.gContext.getWindowWidth()); 053 } else { 054 // Use real location and size 055 java.awt.Point loc = p.getLocation(); 056 panel.setAttribute("x", "" + loc.x); 057 panel.setAttribute("y", "" + loc.y); 058 059 java.awt.Dimension size = p.getSize(); 060 panel.setAttribute("windowheight", "" + size.height); 061 panel.setAttribute("windowwidth", "" + size.width); 062 } 063 panel.setAttribute("panelheight", "" + p.gContext.getLayoutHeight()); 064 panel.setAttribute("panelwidth", "" + p.gContext.getLayoutWidth()); 065 panel.setAttribute("sliders", "" + (p.getScroll() ? "yes" : "no")); // deprecated 066 panel.setAttribute("scrollable", "" + p.getScrollable()); 067 panel.setAttribute("editable", "" + (p.isEditable() ? "yes" : "no")); 068 panel.setAttribute("positionable", "" + (p.allPositionable() ? "yes" : "no")); 069 panel.setAttribute("controlling", "" + (p.allControlling() ? "yes" : "no")); 070 panel.setAttribute("animating", "" + (p.isAnimating() ? "yes" : "no")); 071 panel.setAttribute("showhelpbar", "" + (p.getShowHelpBar() ? "yes" : "no")); 072 panel.setAttribute("drawgrid", "" + (p.getDrawGrid() ? "yes" : "no")); 073 panel.setAttribute("snaponadd", "" + (p.getSnapOnAdd() ? "yes" : "no")); 074 panel.setAttribute("snaponmove", "" + (p.getSnapOnMove() ? "yes" : "no")); 075 panel.setAttribute("antialiasing", "" + (p.getAntialiasingOn() ? "yes" : "no")); 076 panel.setAttribute("turnoutcircles", "" + (p.getTurnoutCircles() ? "yes" : "no")); 077 panel.setAttribute("tooltipsnotedit", "" + (p.getTooltipsNotEdit() ? "yes" : "no")); 078 panel.setAttribute("tooltipsinedit", "" + (p.getTooltipsInEdit() ? "yes" : "no")); 079 panel.setAttribute("mainlinetrackwidth", "" + p.gContext.getMainlineBlockWidth()); //saves wrong value for backwards compatability with pre-LayoutTrackDrawingOptions 080 panel.setAttribute("xscale", Float.toString((float) p.gContext.getXScale())); 081 panel.setAttribute("yscale", Float.toString((float) p.gContext.getYScale())); 082 panel.setAttribute("sidetrackwidth", "" + p.gContext.getSidelineBlockWidth()); //saves wrong value for backwards compatability with pre-LayoutTrackDrawingOptions 083 panel.setAttribute("defaulttrackcolor", p.getDefaultTrackColor()); 084 panel.setAttribute("defaultoccupiedtrackcolor", p.getDefaultOccupiedTrackColor()); 085 panel.setAttribute("defaultalternativetrackcolor", p.getDefaultAlternativeTrackColor()); 086 panel.setAttribute("defaulttextcolor", p.getDefaultTextColor()); 087 String turnoutCircleColor = p.getTurnoutCircleColor(); 088 panel.setAttribute("turnoutcirclecolor", turnoutCircleColor); 089 String turnoutCircleThrownColor = p.getTurnoutCircleThrownColor(); 090 // optional attributes 091 if (!turnoutCircleColor.equals(turnoutCircleThrownColor)) { 092 panel.setAttribute("turnoutcirclethrowncolor", turnoutCircleThrownColor); 093 } 094 if (p.isTurnoutFillControlCircles()) { 095 panel.setAttribute("turnoutfillcontrolcircles", "yes"); 096 } 097 098 panel.setAttribute("turnoutcirclesize", "" + p.getTurnoutCircleSize()); 099 panel.setAttribute("turnoutdrawunselectedleg", (p.isTurnoutDrawUnselectedLeg() ? "yes" : "no")); 100 panel.setAttribute("turnoutbx", Float.toString((float) p.getTurnoutBX())); 101 panel.setAttribute("turnoutcx", Float.toString((float) p.getTurnoutCX())); 102 panel.setAttribute("turnoutwid", Float.toString((float) p.getTurnoutWid())); 103 panel.setAttribute("xoverlong", Float.toString((float) p.getXOverLong())); 104 panel.setAttribute("xoverhwid", Float.toString((float) p.getXOverHWid())); 105 panel.setAttribute("xovershort", Float.toString((float) p.getXOverShort())); 106 panel.setAttribute("autoblkgenerate", "" + (p.getAutoBlockAssignment() ? "yes" : "no")); 107 if (p.getBackgroundColor() != null) { 108 panel.setAttribute("redBackground", "" + p.getBackgroundColor().getRed()); 109 panel.setAttribute("greenBackground", "" + p.getBackgroundColor().getGreen()); 110 panel.setAttribute("blueBackground", "" + p.getBackgroundColor().getBlue()); 111 } 112 panel.setAttribute("gridSize", "" + p.gContext.getGridSize()); 113 panel.setAttribute("gridSize2nd", "" + p.gContext.getGridSize2nd()); 114 115 p.resetDirty(); 116 panel.setAttribute("openDispatcher", p.getOpenDispatcherOnLoad() ? "yes" : "no"); 117 panel.setAttribute("useDirectTurnoutControl", p.getDirectTurnoutControl() ? "yes" : "no"); 118 if (p.isHighlightCursor()) { 119 panel.setAttribute("highlightCursor", "yes"); 120 } 121 122 // store layout track drawing options 123 try { 124 LayoutTrackDrawingOptions ltdo = p.getLayoutTrackDrawingOptions(); 125 Element e = jmri.configurexml.ConfigXmlManager.elementFromObject(ltdo); 126 if (e != null) { 127 panel.addContent(e); 128 } 129 } catch (Exception e) { 130 log.error("Error storing contents element: ", e); 131 } 132 133 // note: moving zoom attribute into per-window user preference 134 //panel.setAttribute("zoom", Double.toString(p.getZoom())); 135 int num; 136 137 // include contents (Icons and Labels) 138 List<Positionable> contents = p.getContents(); 139 for (Positionable sub : contents) { 140 if (sub != null && sub.storeItem()) { 141 try { 142 Element e = jmri.configurexml.ConfigXmlManager.elementFromObject(sub); 143 if (e != null) { 144 panel.addContent(e); 145 } 146 } catch (Exception e) { 147 log.error("Error storing contents element: ", e); 148 } 149 } else { 150 log.warn("Null entry found when storing panel contents."); 151 } 152 } 153 154 // include LayoutTracks 155 List<LayoutTrack> layoutTracks = p.getLayoutTracks(); 156 num = layoutTracks.size(); 157 if (log.isDebugEnabled()) { 158 log.debug("N LayoutTrack elements: {}", num); 159 } 160 161 162 163 // Previous write order was 164 // LayoutTurnout) && !(item instanceof LayoutSlip) 165 // TrackSegment 166 // PositionablePoint 167 // LevelXing 168 // LayoutSlip 169 // LayoutTurntable 170 171 // write order specified for compatibility 172 for (LayoutTrackView lv : p.getLayoutTurnoutViews()) { 173 if (! (lv instanceof LayoutSlipView) ) 174 storeOne(panel, lv); 175 } 176 for (LayoutTrackView lv : p.getTrackSegmentViews()) {storeOne(panel, lv); } 177 for (LayoutTrackView lv : p.getPositionablePointViews()) {storeOne(panel, lv); } 178 for (LayoutTrackView lv : p.getLevelXingViews()) {storeOne(panel, lv); } 179 for (LayoutTrackView lv : p.getLayoutSlipViews()) {storeOne(panel, lv); } 180 for (LayoutTrackView lv : p.getLayoutTurntableViews()) {storeOne(panel, lv); } 181 for (LayoutTrackView lv : p.getLayoutTraverserViews()) {storeOne(panel, lv); } 182 183 // include Layout Shapes 184 for (LayoutShape ls : p.getLayoutShapes()) {storeOne(panel, ls); } 185 186 return panel; 187 } // store 188 189 190 private void storeOne(Element panel, Object item) { 191 try { 192 Element e = jmri.configurexml.ConfigXmlManager.elementFromObject(item); 193 if (e != null) { 194 panel.addContent(e); 195 } 196 } catch (Exception ex) { 197 log.error("Error storing layout item: {}", item, ex); 198 } 199 } 200 201 @Override 202 public void load(Element element, Object o) { 203 log.error("Invalid method called"); 204 } 205 206 /** 207 * Create a LayoutEditor object, then register and fill it, then pop it in a 208 * JFrame 209 * 210 * @param shared Top level Element to unpack. 211 */ 212 @Override 213 public boolean load(Element shared, Element perNode) { 214 if (java.awt.GraphicsEnvironment.isHeadless()) { 215 return true; 216 } 217 218 boolean result = true; 219 Attribute a; 220 // find coordinates 221 int x = 0; 222 int y = 0; 223 // From this version onwards separate sizes for window and panel are used 224 int windowHeight = 400; 225 int windowWidth = 300; 226 int panelHeight = 340; 227 int panelWidth = 280; 228 int sidetrackwidth = 3; 229 int mainlinetrackwidth = 3; 230 try { 231 if ((a = shared.getAttribute("x")) != null) { 232 x = a.getIntValue(); 233 } 234 if ((a = shared.getAttribute("y")) != null) { 235 y = a.getIntValue(); 236 } 237 238 // For compatibility with previous versions, try and 239 // see if height and width tags are contained in the file 240 if ((a = shared.getAttribute("height")) != null) { 241 windowHeight = a.getIntValue(); 242 panelHeight = windowHeight - 60; 243 } 244 if ((a = shared.getAttribute("width")) != null) { 245 windowWidth = a.getIntValue(); 246 panelWidth = windowWidth - 18; 247 } 248 249 // For files created by the new version, 250 // retrieve window and panel sizes 251 if ((a = shared.getAttribute("windowheight")) != null) { 252 windowHeight = a.getIntValue(); 253 } 254 if ((a = shared.getAttribute("windowwidth")) != null) { 255 windowWidth = a.getIntValue(); 256 } 257 if ((a = shared.getAttribute("panelheight")) != null) { 258 panelHeight = a.getIntValue(); 259 } 260 if ((a = shared.getAttribute("panelwidth")) != null) { 261 panelWidth = a.getIntValue(); 262 } 263 264 mainlinetrackwidth = shared.getAttribute("mainlinetrackwidth").getIntValue(); 265 sidetrackwidth = shared.getAttribute("sidetrackwidth").getIntValue(); 266 } catch (DataConversionException e) { 267 log.error("failed to convert LayoutEditor attribute"); 268 result = false; 269 } 270 271 double xScale = 1.0; 272 double yScale = 1.0; 273 if ((a = shared.getAttribute("xscale")) != null) { 274 try { 275 xScale = (Float.parseFloat(a.getValue())); 276 } catch (NumberFormatException e) { 277 log.error("failed to convert xscale attribute to float - {}", a.getValue()); 278 result = false; 279 } 280 } 281 if ((a = shared.getAttribute("yscale")) != null) { 282 try { 283 yScale = (Float.parseFloat(a.getValue())); 284 } catch (NumberFormatException e) { 285 log.error("failed to convert yscale attribute to float - {}", a.getValue()); 286 result = false; 287 } 288 } 289 290 // find the name 291 String name = ""; 292 if ((a = shared.getAttribute("name")) != null) { 293 name = a.getValue(); 294 } 295 if (InstanceManager.getDefault(EditorManager.class).contains(name)) { 296 JFrame frame = new JFrame("DialogDemo"); 297 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 298 log.warn("File contains a panel with the same name ({}) as an existing panel", name); 299 int n = JmriJOptionPane.showConfirmDialog(frame, 300 Bundle.getMessage("DuplicatePanel", name), 301 Bundle.getMessage("DuplicatePanelTitle"), 302 JmriJOptionPane.YES_NO_OPTION); 303 if (n != JmriJOptionPane.YES_OPTION ) { 304 return false; 305 } 306 } 307 308 // If available, override location and size with machine dependent values 309 if (!InstanceManager.getDefault(jmri.util.gui.GuiLafPreferencesManager.class).isEditorUseOldLocSize()) { 310 jmri.UserPreferencesManager prefsMgr = InstanceManager.getNullableDefault(jmri.UserPreferencesManager.class); 311 if (prefsMgr != null) { 312 String windowFrameRef = "jmri.jmrit.display.layoutEditor.LayoutEditor:" + name; 313 314 java.awt.Point prefsWindowLocation = prefsMgr.getWindowLocation(windowFrameRef); 315 if (prefsWindowLocation != null) { 316 x = (int) prefsWindowLocation.getX(); 317 y = (int) prefsWindowLocation.getY(); 318 } 319 320 java.awt.Dimension prefsWindowSize = prefsMgr.getWindowSize(windowFrameRef); 321 if (prefsWindowSize != null && prefsWindowSize.getHeight() != 0 && prefsWindowSize.getWidth() != 0) { 322 windowHeight = (int) prefsWindowSize.getHeight(); 323 windowWidth = (int) prefsWindowSize.getWidth(); 324 } 325 } 326 } 327 328 LayoutEditor panel = new LayoutEditor(name); 329 panel.setLayoutName(name); 330 InstanceManager.getDefault(EditorManager.class).add(panel); 331 332 // create the objects 333 panel.gContext.setMainlineTrackWidth(mainlinetrackwidth); 334 panel.gContext.setSidelineTrackWidth(sidetrackwidth); 335 panel.gContext.setXScale(xScale); 336 panel.gContext.setYScale(yScale); 337 338 String color = ColorUtil.ColorDarkGray; 339 try { 340 if ((a = shared.getAttribute("defaulttrackcolor")) != null) { 341 color = a.getValue(); 342 } 343 panel.setDefaultTrackColor(ColorUtil.stringToColor(color)); 344 } catch (IllegalArgumentException e) { 345 panel.setDefaultTrackColor(Color.BLACK); 346 log.error("Invalid defaulttrackcolor {}; using black", color); 347 } 348 349 color = ColorUtil.ColorBlack; 350 try { 351 if ((a = shared.getAttribute("defaulttextcolor")) != null) { 352 color = a.getValue(); 353 } 354 panel.setDefaultTextColor(ColorUtil.stringToColor(color)); 355 } catch (IllegalArgumentException e) { 356 panel.setDefaultTextColor(Color.BLACK); 357 log.error("Invalid defaulttextcolor {}; using black", color); 358 } 359 360 color = "track"; //default to using use default track color for circle color 361 try { 362 if ((a = shared.getAttribute("turnoutcirclecolor")) != null) { 363 color = a.getValue(); 364 } 365 panel.setTurnoutCircleColor(ColorUtil.stringToColor(color)); 366 } catch (IllegalArgumentException e) { 367 panel.setTurnoutCircleColor(Color.BLACK); 368 log.error("Invalid color {}; using black", color); 369 } 370 371 // default to using turnout circle color just set 372 try { 373 if ((a = shared.getAttribute("turnoutcirclethrowncolor")) != null) { 374 color = a.getValue(); 375 } 376 panel.setTurnoutCircleThrownColor(ColorUtil.stringToColor(color)); 377 } catch (IllegalArgumentException e) { 378 panel.setTurnoutCircleThrownColor(Color.BLACK); 379 log.error("Invalid color {}; using black", color); 380 } 381 382 try { // the "turnoutfillcontrolcircles" attribute has a default="no" value in the schema; 383 // it will always return a "no" attribute if the attribute is not present. 384 panel.setTurnoutFillControlCircles(shared.getAttribute("turnoutfillcontrolcircles").getBooleanValue()); 385 } catch (DataConversionException e) { 386 log.warn("unable to convert turnoutfillcontrolcircles attribute"); 387 } catch (NullPointerException e) { // considered normal if the attribute is not present 388 log.debug("missing turnoutfillcontrolcircles attribute"); 389 } 390 391 if ((a = shared.getAttribute("turnoutcirclesize")) != null) { 392 try { 393 panel.setTurnoutCircleSize(a.getIntValue()); 394 } catch (DataConversionException e) { 395 log.warn("unable to convert turnoutcirclesize"); 396 } 397 } 398 399 try { 400 panel.setTurnoutDrawUnselectedLeg(shared.getAttribute("turnoutdrawunselectedleg").getBooleanValue()); 401 } catch (DataConversionException e) { 402 log.warn("unable to convert turnoutdrawunselectedleg attribute"); 403 } catch (NullPointerException e) { // considered normal if the attribute is not present 404 log.debug("missing turnoutdrawunselectedleg attribute"); 405 } 406 407 // turnout size parameters 408 if ((a = shared.getAttribute("turnoutbx")) != null) { 409 try { 410 panel.setTurnoutBX(Float.parseFloat(a.getValue())); 411 } catch (NumberFormatException e) { 412 log.error("failed to convert turnoutbx to float - {}", a.getValue()); 413 result = false; 414 } 415 } 416 417 if ((a = shared.getAttribute("turnoutcx")) != null) { 418 try { 419 panel.setTurnoutCX(Float.parseFloat(a.getValue())); 420 } catch (NumberFormatException e) { 421 log.error("failed to convert turnoutcx to float - {}", a.getValue()); 422 result = false; 423 } 424 } 425 426 if ((a = shared.getAttribute("turnoutwid")) != null) { 427 try { 428 panel.setTurnoutWid(Float.parseFloat(a.getValue())); 429 } catch (NumberFormatException e) { 430 log.error("failed to convert turnoutwid to float - {}", a.getValue()); 431 result = false; 432 } 433 } 434 435 if ((a = shared.getAttribute("xoverlong")) != null) { 436 try { 437 panel.setXOverLong(Float.parseFloat(a.getValue())); 438 } catch (NumberFormatException e) { 439 log.error("failed to convert xoverlong to float - {}", a.getValue()); 440 result = false; 441 } 442 } 443 if ((a = shared.getAttribute("xoverhwid")) != null) { 444 try { 445 panel.setXOverHWid(Float.parseFloat(a.getValue())); 446 } catch (NumberFormatException e) { 447 log.error("failed to convert xoverhwid to float - {}", a.getValue()); 448 result = false; 449 } 450 } 451 if ((a = shared.getAttribute("xovershort")) != null) { 452 try { 453 panel.setXOverShort(Float.parseFloat(a.getValue())); 454 } catch (NumberFormatException e) { 455 log.error("failed to convert xovershort to float - {}", a.getValue()); 456 result = false; 457 } 458 } 459 // grid size parameter 460 if ((a = shared.getAttribute("gridSize")) != null) { 461 try { 462 panel.gContext.setGridSize(Integer.parseInt(a.getValue())); 463 } catch (NumberFormatException e) { 464 log.error("failed to convert gridSize to int - {}", a.getValue()); 465 result = false; 466 } 467 } 468 469 // second grid size parameter 470 if ((a = shared.getAttribute("gridSize2nd")) != null) { 471 try { 472 panel.gContext.setGridSize2nd(Integer.parseInt(a.getValue())); 473 } catch (NumberFormatException e) { 474 log.error("failed to convert gridSize2nd to int - {}", a.getValue()); 475 result = false; 476 } 477 } 478 479 try { 480 panel.setAllPositionable(shared.getAttribute("positionable").getBooleanValue()); 481 } catch (DataConversionException e) { 482 log.warn("unable to convert positionable attribute"); 483 } catch (NullPointerException e) { // considered normal if the attribute is not present 484 log.debug("missing positionable attribute"); 485 486 } 487 488 try { 489 panel.setAllControlling(shared.getAttribute("controlling").getBooleanValue()); 490 } catch (DataConversionException e) { 491 log.warn("unable to convert controlling attribute"); 492 } catch (NullPointerException e) { // considered normal if the attribute is not present 493 log.debug("missing controlling attribute"); 494 } 495 496 try { 497 panel.setTurnoutAnimation(shared.getAttribute("animating").getBooleanValue()); 498 } catch (DataConversionException e) { 499 log.warn("unable to convert animating attribute"); 500 } catch (NullPointerException e) { // considered normal if the attribute is not present 501 log.debug("missing animating attribute"); 502 } 503 504 try { 505 panel.setDrawGrid(shared.getAttribute("drawgrid").getBooleanValue()); 506 } catch (DataConversionException e) { 507 log.warn("unable to convert drawgrid attribute"); 508 } catch (NullPointerException e) { // considered normal if the attribute is not present 509 log.debug("missing drawgrid attribute"); 510 } 511 512 try { 513 panel.setSnapOnAdd(shared.getAttribute("snaponadd").getBooleanValue()); 514 } catch (DataConversionException e) { 515 log.warn("unable to convert snaponadd attribute"); 516 } catch (NullPointerException e) { // considered normal if the attribute is not present 517 log.debug("missing snaponadd attribute"); 518 } 519 520 try { 521 panel.setSnapOnMove(shared.getAttribute("snaponmove").getBooleanValue()); 522 } catch (DataConversionException e) { 523 log.warn("unable to convert snaponmove attribute"); 524 } catch (NullPointerException e) { // considered normal if the attribute is not present 525 log.debug("missing snaponmove attribute"); 526 } 527 528 try { 529 panel.setTurnoutCircles(shared.getAttribute("turnoutcircles").getBooleanValue()); 530 } catch (DataConversionException e) { 531 log.warn("unable to convert turnoutcircles attribute"); 532 } catch (NullPointerException e) { // considered normal if the attribute is not present 533 log.debug("missing turnoutcircles attribute"); 534 } 535 536 try { 537 panel.setTooltipsNotEdit(shared.getAttribute("tooltipsnotedit").getBooleanValue()); 538 } catch (DataConversionException e) { 539 log.warn("unable to convert tooltipsnotedit attribute"); 540 } catch (NullPointerException e) { // considered normal if the attribute is not present 541 log.debug("missing tooltipsnotedit attribute"); 542 } 543 544 try { 545 panel.setAutoBlockAssignment(shared.getAttribute("autoblkgenerate").getBooleanValue()); 546 } catch (DataConversionException e) { 547 log.warn("unable to convert autoblkgenerate attribute"); 548 } catch (NullPointerException e) { // considered normal if the attribute is not present 549 log.debug("missing autoblkgenerate attribute"); 550 } 551 552 try { 553 panel.setTooltipsInEdit(shared.getAttribute("tooltipsinedit").getBooleanValue()); 554 } catch (DataConversionException e) { 555 log.warn("unable to convert tooltipsinedit attribute"); 556 } catch (NullPointerException e) { // considered normal if the attribute is not present 557 log.debug("missing tooltipsinedit attribute"); 558 } 559 560 // set default track color 561 if ((a = shared.getAttribute("defaulttrackcolor")) != null) { 562 try { 563 panel.setDefaultTrackColor(ColorUtil.stringToColor(a.getValue())); 564 } catch (IllegalArgumentException e) { 565 panel.setDefaultTrackColor(Color.darkGray); 566 log.error("Invalid defaulttrackcolor {}; using 'darkGray'", a.getValue()); 567 } 568 } 569 // set default occupied track color 570 if ((a = shared.getAttribute("defaultoccupiedtrackcolor")) != null) { 571 try { 572 panel.setDefaultOccupiedTrackColor(ColorUtil.stringToColor(a.getValue())); 573 } catch (IllegalArgumentException e) { 574 panel.setDefaultOccupiedTrackColor(Color.red); 575 log.error("Invalid defaultoccupiedtrackcolor {}; using 'red'", a.getValue()); 576 } 577 } 578 // set default alternative track color 579 if ((a = shared.getAttribute("defaultalternativetrackcolor")) != null) { 580 try { 581 panel.setDefaultAlternativeTrackColor(ColorUtil.stringToColor(a.getValue())); 582 } catch (IllegalArgumentException e) { 583 panel.setDefaultAlternativeTrackColor(Color.white); 584 log.error("Invalid defaultalternativetrackcolor {}; using 'white'", a.getValue()); 585 } 586 } 587 try { 588 int red = shared.getAttribute("redBackground").getIntValue(); 589 int blue = shared.getAttribute("blueBackground").getIntValue(); 590 int green = shared.getAttribute("greenBackground").getIntValue(); 591 Color backgroundColor = new Color(red, green, blue); 592 panel.setDefaultBackgroundColor(backgroundColor); 593 panel.setBackgroundColor(backgroundColor); 594 } catch (DataConversionException e) { 595 log.warn("Could not parse color attributes!"); 596 } catch (NullPointerException e) { // considered normal if the attributes are not present 597 log.debug("missing background color attributes"); 598 } 599 600 try { 601 panel.setDirectTurnoutControl(shared.getAttribute("useDirectTurnoutControl").getBooleanValue()); 602 } catch (DataConversionException e) { 603 log.warn("unable to convert Layout Editor useDirectTurnoutControl attribute"); 604 } catch (NullPointerException e) { // considered normal if the attribute is not present 605 log.debug("missing useDirectTurnoutControl attribute"); 606 } 607 608 try { 609 panel.setHighlightCursor(shared.getAttribute("highlightCursor").getBooleanValue()); 610 } catch (DataConversionException e) { 611 log.warn("unable to convert highlightCursor attribute"); 612 } catch (NullPointerException e) { // considered normal if the attribute is not present 613 log.debug("missing highlightCursor attribute"); 614 } 615 616 617 // Set editor's option flags, load content after 618 // this so that individual item flags are set as saved 619 panel.initView(); 620 621 622 // load the contents 623 for (Element item : shared.getChildren()) { 624 // get the class, hence the adapter object to do loading 625 String adapterName = item.getAttribute("class").getValue(); 626 adapterName = jmri.configurexml.ConfigXmlManager.currentClassName(adapterName); 627 628 if (log.isDebugEnabled()) { 629 String id = "<null>"; 630 try { 631 id = item.getAttribute("name").getValue(); 632 log.debug("Load {} for [{}] via {}", id, panel.getName(), adapterName); 633 } catch (NullPointerException e) { 634 log.debug("Load layout object for [{}] via {}", panel.getName(), adapterName); 635 log.debug("Load layout object for [{}] via {}", panel.getName(), adapterName); 636 } catch (RuntimeException e) { 637 throw e; 638 } catch (Exception e) { 639 } 640 } 641 try { 642 // get the class name, including migrations 643 adapterName = jmri.configurexml.ConfigXmlManager.currentClassName(adapterName); 644 // get the adapter object 645 XmlAdapter adapter = (XmlAdapter) Class.forName(adapterName).getDeclaredConstructor().newInstance(); 646 // and load with it 647 adapter.load(item, panel); 648 if (!panel.loadOK()) { 649 result = false; 650 } 651 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException 652 | jmri.configurexml.JmriConfigureXmlException 653 | java.lang.reflect.InvocationTargetException e) { 654 log.error("Exception while loading {}", item.getName(), e); 655 result = false; 656 } 657 } 658 panel.disposeLoadData(); // dispose of url correction data 659 660 // final initialization of objects 661 panel.setConnections(); 662 663 // display the results 664 try { 665 // set first since other attribute use this setting 666 panel.setAllEditable(shared.getAttribute("editable").getBooleanValue()); 667 } catch (DataConversionException e) { 668 log.warn("unable to convert editable attribute"); 669 } catch (NullPointerException e) { // considered normal if the attribute is not present 670 log.debug("missing editable attribute"); 671 } 672 673 try { 674 panel.setShowHelpBar(shared.getAttribute("showhelpbar").getBooleanValue()); 675 } catch (DataConversionException e) { 676 log.warn("unable to convert showhelpbar attribute"); 677 } catch (NullPointerException e) { // considered normal if the attribute is not present 678 log.debug("missing showhelpbar attribute"); 679 } 680 681 try { 682 panel.setAntialiasingOn(shared.getAttribute("antialiasing").getBooleanValue()); 683 } catch (DataConversionException e) { 684 log.warn("unable to convert antialiasing attribute"); 685 } catch (NullPointerException e) { // considered normal if the attribute is not present 686 log.debug("missing antialiasing attribute"); 687 } 688 689 // set contents state 690 String slValue = "both"; 691 try { 692 boolean value = shared.getAttribute("sliders").getBooleanValue(); 693 slValue = value ? "both" : "none"; 694 } catch (DataConversionException e) { 695 log.warn("unable to convert sliders attribute"); 696 } catch (NullPointerException e) { // considered normal if the attribute is not present 697 log.debug("missing sliders attribute"); 698 } 699 if ((a = shared.getAttribute("scrollable")) != null) { 700 slValue = a.getValue(); 701 } 702 panel.setScroll(slValue); 703 704 panel.pack(); 705 panel.setLayoutDimensions(windowWidth, windowHeight, x, y, panelWidth, panelHeight); 706 panel.setVisible(true); // always show the panel 707 708 // make a pass over positionables, setting (re)setting their font style. 709 // This is to bypass a problem on Windows, where bold labels need to have 710 // this done after pack() to avoid sizing issues. 711 for (jmri.jmrit.display.Positionable label : panel.getContents()) { 712 var popup = label.getPopupUtility(); 713 if (popup != null) { // encountered in some testing 714 popup.setFontStyle(popup.getFontStyle()); 715 } 716 } 717 718 panel.resetDirty(); 719 720 // register the resulting panel for later configuration 721 ConfigureManager cm = InstanceManager.getNullableDefault(jmri.ConfigureManager.class); 722 if (cm != null) { 723 cm.registerUser(panel); 724 } 725 //open Dispatcher frame if any Transits are defined, and open Dispatcher flag set on 726 if (jmri.InstanceManager.getDefault(jmri.TransitManager.class).getNamedBeanSet().size() > 0) { 727 try { 728 boolean value = shared.getAttribute("openDispatcher").getBooleanValue(); 729 panel.setOpenDispatcherOnLoad(value); 730 if (value) { 731 // Create the DispatcherFrame instance. 732 // This is a trigger for LoadXmlConfigAction to call loadAtStartup. 733 InstanceManager.getDefault(DispatcherFrame.class); 734 } 735 } catch (DataConversionException e) { 736 log.warn("unable to convert openDispatcher attribute"); 737 } catch (NullPointerException e) { // considered normal if the attribute is not present 738 log.debug("No openDispatcher attribute"); 739 } 740 } 741 return result; 742 } // load 743 744 @Override 745 public int loadOrder() { 746 return jmri.Manager.PANELFILES; 747 } 748 749 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutEditorXml.class); 750 751}