001package jmri.jmrit.display; 002 003import java.awt.Color; 004import java.awt.Dimension; 005import java.awt.image.BufferedImage; 006 007import jmri.util.JmriJFrame; 008import jmri.util.swing.DrawSquares; 009 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013/** 014 * Extended JmriJFrame that allows to add an InitEventListener for display of 015 * a tabbed frame in the CPE Add Item {@link jmri.jmrit.display.palette.ItemPalette} pane. 016 * <p> 017 * <a href="doc-files/DisplayFrame-ClassDiagram.png"><img src="doc-files/DisplayFrame-ClassDiagram.png" alt="UML Class diagram" height="50%" width="50%"></a> 018 * 019 * @author Egbert Broerse Copyright (c) 2017, 2021 020 **/ 021/* 022@startuml jmri/jmrit/display/doc-files/DisplayFrame-ClassDiagram.png 023 024class jmri.util.JmriJFrame 025class jmri.util.swing.ImagePanel { 026-BufferedImage back 027+setImage() 028+paintComponent() 029} 030class jmri.jmrit.DisplayFrame #88dddd { 031-previewBgIndex 032#SetInitListener() 033#setPreviewBg(i) 034#getPreviewBg() 035} 036class jmri.jmrit.display.IconEditor 037 038object AddItem_TabbedPane 039AddItem_TabbedPane : Tab[1] = TurnoutTab 040AddItem_TabbedPane : Tab[n] = IndicatorTab 041object TurnoutItemPanel 042TurnoutItemPanel : type = "Turnout" 043object SignalMastItemPanel 044SignalMastItemPanel : type = "SignalMast" 045object xItemPanel 046xItemPanel : type = "x" 047object viewOnCombo 048viewOnCombo : -int choice 049viewOnCombo : +EventListener InitListener 050object preview 051preview : -image = 1 052preview : +EventListener comboListener 053 054AddItem_TabbedPane --> TurnoutItemPanel : show() 055AddItem_TabbedPane --> SignalMastItemPanel : show() 056AddItem_TabbedPane --> xItemPanel : show() 057jmri.util.JmriJFrame --|> jmri.jmrit.DisplayFrame 058jmri.jmrit.DisplayFrame *-- jmri.jmrit.display.IconEditor 059SignalMastItemPanel *-- viewOnCombo 060TurnoutItemPanel *-- viewOnCombo 061xItemPanel *-- viewOnCombo 062AddItem_TabbedPane ..> viewOnCombo: TabShown(i) 063viewOnCombo ..> preview: SetImage[n] 064jmri.jmrit.display.IconEditor *-- viewOnCombo 065jmri.jmrit.DisplayFrame *-- AddItem_TabbedPane 066jmri.util.swing.ImagePanel -- preview 067 068@enduml 069*/ 070public class DisplayFrame extends JmriJFrame { 071 072 static Color _grayColor = new Color(235, 235, 235); 073 static Color _darkGrayColor = new Color(150, 150, 150); 074 static final Color[] colorChoice = new Color[]{Color.white, _grayColor, _darkGrayColor}; // panel bg color picked up directly 075 076 // Array of BufferedImage backgrounds loaded as background image in Preview, shared across tabs 077 private BufferedImage[] _backgrounds; 078 private Editor _editor; // current panel editor using this frame 079 private Color _panelBackground; // current background 080 private int previewBgIndex = 0; // Shared index setting for preview pane background color combo choice. 081 082 083 /** 084 * Create a JmriJFrame with standard settings, optional save/restore of size 085 * and position. 086 * 087 * @param saveSize set true to save the last known size 088 * @param savePosition set true to save the last known location 089 */ 090 public DisplayFrame(boolean saveSize, boolean savePosition) { 091 super(saveSize, savePosition); 092 } 093 094 /** 095 * Create a JmriJFrame with with given name plus standard settings, including 096 * optional save/restore of size and position. 097 * 098 * @param name title of the Frame 099 * @param saveSize set true to save the last knowm size 100 * @param savePosition set true to save the last known location 101 */ 102 public DisplayFrame(String name, boolean saveSize, boolean savePosition) { 103 super(name, saveSize, savePosition); 104 } 105 106 /** 107 * Create a JmriJFrame for ItemPalette or for edit popups of a given editor panel. 108 * Such child classes need to provide backgrounds for their panes and panels. 109 * 110 * @param name title of the Frame 111 * @param editor editor of panel items 112 */ 113 public DisplayFrame(String name, Editor editor) { 114 super(name, false, false); 115 _editor = editor; 116 makeBackgrounds(); 117 } 118 119 /** 120 * Create a JmriJFrame with standard settings, including saving/restoring of 121 * size and position. 122 */ 123 public DisplayFrame() { 124 this(true, true); 125 } 126 127 /** 128 * Create a JmriJFrame with with given name plus standard settings, including 129 * saving/restoring of size and position. 130 * 131 * @param name title of the JFrame 132 */ 133 public DisplayFrame(String name) { 134 this(name, true, true); 135 } 136 137 /** 138 * This may be used as a callback to notify children of this class 139 * when the preview color has changed. 140 * Children of this class should override if there are several other 141 * members with separate preview panels. e.g. ItemPalette 142 * But prevent a loop when calling super in that process (bug in 4.21.3; fixed in 4.21.4) 143 * 144 * @param index index of selection in _backgrounds array 145 */ 146 public void setPreviewBg(int index) { 147 previewBgIndex = index; 148 } 149 150 public int getPreviewBg() { 151 return previewBgIndex; 152 } 153 154 public BufferedImage getPreviewBackground() { 155 return _backgrounds[previewBgIndex]; 156 } 157 158 /** 159 * 160 * @return the color of the background of editor display panel 161 */ 162 public Color getCurrentColor() { 163 // should be _editor.getTargetPanel().getBackground() 164 return _panelBackground; 165 } 166 167 public BufferedImage getBackground(int index) { 168 return _backgrounds[index]; 169 } 170 171 /** 172 * Called when the background of the display panel is changed. 173 * @param ed the editor of the display panel 174 */ 175 public void updateBackground(Editor ed) { 176 if (ed == null) { 177 log.error("updateBackground called for a null editor!"); 178 return; 179 } 180 _editor = ed; 181 Color color = ed.getTargetPanel().getBackground(); 182 if (!color.equals(_panelBackground)) { 183 _backgrounds[0] = DrawSquares.getImage(500, 400, 10, color, color); 184 _panelBackground = color; 185 if (previewBgIndex == 0) { 186 setPreviewBg(0); // notify children 187 } 188 } 189 } 190 191 public Editor getEditor() { 192 return _editor; 193 } 194 195 /** 196 * Make an array of background BufferedImages for the PreviewPanels 197 */ 198 private void makeBackgrounds() { 199 _panelBackground = _editor.getTargetPanel().getBackground(); // start using Panel background color 200 if (_backgrounds == null) { // reduces load but will not redraw for new size 201 _backgrounds = new BufferedImage[5]; 202 for (int i = 1; i <= 3; i++) { 203 _backgrounds[i] = DrawSquares.getImage(500, 400, 10, colorChoice[i - 1], colorChoice[i - 1]); 204 // [i-1] because choice 0 is not in colorChoice[] 205 } 206 _backgrounds[4] = DrawSquares.getImage(500, 400, 10, Color.white, _grayColor); 207 } 208 // always update background from Panel Editor 209 _backgrounds[0] = DrawSquares.getImage(500, 400, 10, _panelBackground, _panelBackground); 210 log.debug("makeBackgrounds backgrounds[0] = {}", _backgrounds[0]); 211 } 212 213 /** 214 * Resizes this frame to accommodate the size of the tab panel when tab is changed. 215 * Otherwise it may force the tab panel to use scrollbars or be far oversized. 216 * As a trade off to keep right mouse arrow in same place for ItemPalette accept frame is wider in few cases. 217 * 218 * @param container Container to be resized 219 * @param deltaDim Size difference of container with old contents 220 * @param newDim Size of the new contents 221 */ 222 public void reSize(java.awt.Container container, Dimension deltaDim, Dimension newDim) { 223 Dimension dim = new Dimension(deltaDim.width + newDim.width, deltaDim.height + newDim.height); 224 container.setPreferredSize(dim); 225 container.invalidate(); 226 if (log.isDebugEnabled()) 227 log.debug(" deltaDim= ({}, {}) NewDim= ({}, {}) setPreferredSize to ({}, {})", 228 deltaDim.width, deltaDim.height, newDim.width, newDim.height, dim.width, dim.height); 229 pack(); 230 if (log.isDebugEnabled()) { 231 dim = container.getSize(); 232 log.debug(" Resized to ({}, {})", dim.width, dim.height); 233 } 234 } 235 236 private final static Logger log = LoggerFactory.getLogger(DisplayFrame.class); 237 238}