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