001package jmri.jmrit.operations.rollingstock.engines.tools; 002 003import java.awt.*; 004import java.io.IOException; 005import java.util.List; 006 007import javax.swing.*; 008 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012import jmri.InstanceManager; 013import jmri.jmrit.operations.OperationsFrame; 014import jmri.jmrit.operations.OperationsPanel; 015import jmri.jmrit.operations.locations.LocationManager; 016import jmri.jmrit.operations.rollingstock.cars.CarRoads; 017import jmri.jmrit.operations.rollingstock.engines.*; 018import jmri.jmrit.operations.setup.Control; 019import jmri.jmrit.operations.setup.Setup; 020import jmri.jmrit.operations.trains.TrainCommon; 021import jmri.util.davidflanagan.HardcopyWriter; 022 023/** 024 * Prints engine roster. 025 * <p> 026 * This uses the older style printing, for compatibility with Java 1.1.8 in 027 * Macintosh MRJ 028 * 029 * @author Bob Jacobsen Copyright (C) 2003 030 * @author Daniel Boudreau Copyright (C) 2023 031 */ 032 033public class PrintEngineRosterFrame extends OperationsFrame { 034 035 boolean _isPreview; 036 EnginesTableFrame _etf; 037 038 private int numberCharPerLine = 90; 039 private int lastLength = 19; 040 041 EngineManager engineManager = InstanceManager.getDefault(EngineManager.class); 042 LocationManager locationManager = InstanceManager.getDefault(LocationManager.class); 043 044 JCheckBox printLocosWithLocation = new JCheckBox(Bundle.getMessage("PrintLocosWithLocation")); 045 046 JComboBox<String> sortByComboBox = new JComboBox<>(); 047 JComboBox<String> manifestOrientationComboBox = new JComboBox<>(); 048 JComboBox<Integer> fontSizeComboBox = new JComboBox<>(); 049 050 JButton okayButton = new JButton(Bundle.getMessage("ButtonOK")); 051 052 public PrintEngineRosterFrame(boolean isPreview, EnginesTableFrame etf) { 053 super(); 054 _isPreview = isPreview; 055 _etf = etf; 056 057 // create panel 058 JPanel pSortBy = new JPanel(); 059 pSortBy.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("SortBy"))); 060 pSortBy.add(sortByComboBox); 061 addComboBoxAction(sortByComboBox); 062 063 JPanel pOrientation = new JPanel(); 064 pOrientation.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOrientation"))); 065 pOrientation.add(manifestOrientationComboBox); 066 067 manifestOrientationComboBox.addItem(Setup.PORTRAIT); 068 manifestOrientationComboBox.addItem(Setup.LANDSCAPE); 069 manifestOrientationComboBox.setSelectedItem(Setup.LANDSCAPE); 070 071 JPanel pFontSize = new JPanel(); 072 pFontSize.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutFontSize"))); 073 pFontSize.add(fontSizeComboBox); 074 075 OperationsPanel.loadFontSizeComboBox(fontSizeComboBox); 076 fontSizeComboBox.setSelectedItem(Control.reportFontSize); 077 078 JPanel pPanel = new JPanel(); 079 pPanel.setLayout(new GridBagLayout()); 080 JScrollPane panePanel = new JScrollPane(pPanel); 081 panePanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("PrintOptions"))); 082 addItemLeft(pPanel, printLocosWithLocation, 0, 0); 083 084 JPanel pButtons = new JPanel(); 085 pButtons.setLayout(new GridBagLayout()); 086 pButtons.add(okayButton); 087 pButtons.setBorder(BorderFactory.createTitledBorder("")); 088 addButtonAction(okayButton); 089 090 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 091 getContentPane().add(pSortBy); 092 getContentPane().add(pOrientation); 093 getContentPane().add(pFontSize); 094 getContentPane().add(panePanel); 095 getContentPane().add(pButtons); 096 097 if (_isPreview) { 098 setTitle(Bundle.getMessage("MenuItemPreview")); 099 } else { 100 setTitle(Bundle.getMessage("MenuItemPrint")); 101 } 102 loadSortByComboBox(sortByComboBox); 103 104 initMinimumSize(new Dimension(Control.panelWidth300, Control.panelHeight300)); 105 } 106 107 @Override 108 public void initComponents() { 109 sortByComboBox.setSelectedItem(_etf.enginesModel.getSortByName()); 110 } 111 112 private void loadSortByComboBox(JComboBox<String> box) { 113 box.removeAllItems(); 114 for (int i = 115 _etf.enginesModel.SORTBY_NUMBER; i <= _etf.enginesModel.SORTBY_COMMENT; i++) { 116 box.addItem(_etf.enginesModel.getSortByName(i)); 117 } 118 box.setSelectedItem(_etf.enginesModel.getSortByName()); 119 } 120 121 @Override 122 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 123 setVisible(false); 124 printEngines(); 125 } 126 127 private void printEngines() { 128 boolean landscape = false; 129 if (manifestOrientationComboBox.getSelectedItem() != null && 130 manifestOrientationComboBox.getSelectedItem().equals(Setup.LANDSCAPE)) { 131 landscape = true; 132 } 133 134 int fontSize = (int) fontSizeComboBox.getSelectedItem(); 135 136 // obtain a HardcopyWriter to do this 137 try (HardcopyWriter writer = new HardcopyWriter(new Frame(), Bundle.getMessage("TitleEngineRoster"), 138 fontSize, .5, .5, .5, .5, _isPreview, "", landscape, true, null);) { 139 140 numberCharPerLine = writer.getCharactersPerLine(); 141 142 // create header 143 write(writer, createHeader()); 144 145 printRoster(writer); 146 147 // and force completion of the printing 148 writer.close(); 149 } catch (IOException we) { 150 log.error("Error printing ConsistRosterEntry: {}", we.getLocalizedMessage()); 151 } catch (HardcopyWriter.PrintCanceledException ex) { 152 log.debug("Print cancelled"); 153 } 154 } 155 156 private String createHeader() { 157 StringBuffer header = new StringBuffer(); 158 159 header.append(padAttribute(Bundle.getMessage("Number"), Control.max_len_string_print_road_number) + 160 padAttribute(Bundle.getMessage("Road"), 161 InstanceManager.getDefault(CarRoads.class).getMaxNameLength()) + 162 padAttribute(Bundle.getMessage("Model"), 163 InstanceManager.getDefault(EngineModels.class).getMaxNameLength()) + 164 padAttribute(Bundle.getMessage("Type"), 165 InstanceManager.getDefault(EngineTypes.class).getMaxNameLength()) + 166 padAttribute(Bundle.getMessage("Len"), Control.max_len_string_length_name)); 167 168 if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_TRAIN || 169 sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_DESTINATION) { 170 header.append(padAttribute(Bundle.getMessage("Train"), Control.max_len_string_train_name / 2)); 171 } else { 172 header.append(padAttribute(Bundle.getMessage("Consist"), 173 InstanceManager.getDefault(ConsistManager.class).getMaxNameLength())); 174 } 175 header.append(padAttribute(Bundle.getMessage("Location"), 176 locationManager.getMaxLocationAndTrackNameLength() + 3)); 177 // one of eight user selections 178 if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_OWNER) { 179 header.append(padAttribute(Bundle.getMessage("Owner"), Control.max_len_string_attibute)); 180 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_MOVES) { 181 header.append(padAttribute(Bundle.getMessage("Moves"), 5)); 182 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_VALUE) { 183 header.append(padAttribute(Setup.getValueLabel(), Control.max_len_string_attibute)); 184 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_LAST) { 185 header.append(padAttribute(Bundle.getMessage("LastMoved"), lastLength)); 186 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_RFID) { 187 header.append(padAttribute(Setup.getRfidLabel(), Control.max_len_string_attibute)); 188 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_DCC_ADDRESS) { 189 header.append(padAttribute(Bundle.getMessage("DccAddress"), 5)); 190 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_BUILT) { 191 header.append(padAttribute(Bundle.getMessage("Built"), Control.max_len_string_built_name)); 192 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_DESTINATION) { 193 header.append(Bundle.getMessage("Destination")); 194 } else { 195 header.append(padAttribute(Bundle.getMessage("Comment"), engineManager.getMaxCommentLength())); 196 } 197 return header.toString() + NEW_LINE; 198 } 199 200 private void printRoster(HardcopyWriter writer) throws IOException { 201 // Loop through the Roster, printing as needed 202 String number; 203 String road; 204 String model; 205 String type; 206 String length; 207 String train = ""; 208 String consist = ""; 209 String location = ""; 210 String moves = ""; 211 String owner = ""; 212 String built = ""; 213 String dccAddress = ""; 214 String value = ""; 215 String rfid = ""; 216 String last = ""; 217 String comment = ""; 218 219 List<Engine> engines = _etf.enginesModel.getEngineList(sortByComboBox.getSelectedIndex()); 220 for (Engine engine : engines) { 221 if (printLocosWithLocation.isSelected() && engine.getLocation() == null) { 222 continue; 223 } 224 String destination = ""; 225 // engine number, road, model, type, and length are always printed 226 number = padAttribute(engine.getNumber(), Control.max_len_string_print_road_number); 227 road = padAttribute(engine.getRoadName(), 228 InstanceManager.getDefault(CarRoads.class).getMaxNameLength()); 229 model = padAttribute(engine.getModel(), 230 InstanceManager.getDefault(EngineModels.class).getMaxNameLength()); 231 type = padAttribute(engine.getTypeName(), 232 InstanceManager.getDefault(EngineTypes.class).getMaxNameLength()); 233 length = padAttribute(engine.getLength(), Control.max_len_string_length_name); 234 235 // show train or consist name 236 if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_TRAIN || 237 sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_DESTINATION) { 238 train = padAttribute(engine.getTrainName().trim(), Control.max_len_string_train_name / 2); 239 } else { 240 consist = padAttribute(engine.getConsistName(), 241 InstanceManager.getDefault(ConsistManager.class).getMaxNameLength()); 242 } 243 244 // show one of 8 options, comment is default 245 if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_OWNER) { 246 owner = padAttribute(engine.getOwnerName(), Control.max_len_string_attibute); 247 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_MOVES) { 248 moves = padAttribute(Integer.toString(engine.getMoves()), 5); 249 } else if (sortByComboBox 250 .getSelectedIndex() == _etf.enginesModel.SORTBY_DCC_ADDRESS) { 251 dccAddress = padAttribute(engine.getDccAddress(), 5); 252 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_LAST) { 253 last = padAttribute(engine.getSortDate(), lastLength); 254 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_VALUE) { 255 value = padAttribute(engine.getValue(), Control.max_len_string_attibute); 256 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_RFID) { 257 rfid = padAttribute(engine.getRfid(), Control.max_len_string_attibute); 258 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesModel.SORTBY_BUILT) { 259 built = padAttribute(engine.getBuilt(), Control.max_len_string_built_name); 260 } else if (sortByComboBox 261 .getSelectedIndex() == _etf.enginesModel.SORTBY_DESTINATION) { 262 if (engine.getDestination() != null) { 263 destination = padAttribute( 264 engine.getDestinationName() + " - " + engine.getDestinationTrackName(), 265 locationManager.getMaxLocationAndTrackNameLength() + 266 3); 267 } 268 } else { 269 comment = padAttribute(engine.getComment(), engineManager.getMaxCommentLength()); 270 } 271 272 if (!engine.getLocationName().equals(Engine.NONE)) { 273 location = padAttribute(engine.getLocationName() + " - " + engine.getTrackName(), 274 locationManager.getMaxLocationAndTrackNameLength() + 3); 275 } else { 276 location = padAttribute("", 277 locationManager.getMaxLocationAndTrackNameLength() + 3); 278 } 279 280 String s = number + 281 road + 282 model + 283 type + 284 length + 285 consist + 286 train + 287 location + 288 moves + 289 owner + 290 value + 291 rfid + 292 dccAddress + 293 built + 294 last + 295 comment + 296 destination; 297 write(writer, s); 298 } 299 } 300 301 private void write(HardcopyWriter writer, String s) throws IOException { 302 if (s.length() > numberCharPerLine) { 303 s = s.substring(0, numberCharPerLine); 304 } 305 writer.write(s + NEW_LINE); 306 } 307 308 private String padAttribute(String attribute, int length) { 309 return TrainCommon.padAndTruncate(attribute, length) + TrainCommon.SPACE; 310 } 311 312 private final static Logger log = LoggerFactory.getLogger(PrintEngineRosterFrame.class); 313}