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.trainbuilder.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 null, null, fontSize, .5 * 72, .5 * 72, .5 * 72, .5 * 72, _isPreview, "", isLandscape, true, null, 140 null)) { 141 142 numberCharPerLine = writer.getCharactersPerLine(); 143 144 // create header 145 write(writer, createHeader()); 146 147 printRoster(writer); 148 149 } catch (IOException we) { 150 log.error("Error printing ConsistRosterEntry: {}", we.getLocalizedMessage()); 151 } catch (HardcopyWriter.PrintCanceledException ex) { 152 log.debug("Print canceled"); 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.enginesTableModel.SORTBY_TRAIN || 169 sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.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.enginesTableModel.SORTBY_OWNER) { 179 header.append(padAttribute(Bundle.getMessage("Owner"), Control.max_len_string_attibute)); 180 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_MOVES) { 181 header.append(padAttribute(Bundle.getMessage("Moves"), 5)); 182 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_VALUE) { 183 header.append(padAttribute(Setup.getValueLabel(), Control.max_len_string_attibute)); 184 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_LAST) { 185 header.append(padAttribute(Bundle.getMessage("LastMoved"), lastLength)); 186 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_RFID) { 187 header.append(padAttribute(Setup.getRfidLabel(), Control.max_len_string_attibute)); 188 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_DCC_ADDRESS) { 189 header.append(padAttribute(Bundle.getMessage("DccAddress"), 5)); 190 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_BUILT) { 191 header.append(padAttribute(Bundle.getMessage("Built"), Control.max_len_string_built_name)); 192 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.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.enginesTableModel.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.enginesTableModel.SORTBY_TRAIN || 237 sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.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.enginesTableModel.SORTBY_OWNER) { 246 owner = padAttribute(engine.getOwnerName(), Control.max_len_string_attibute); 247 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_MOVES) { 248 moves = padAttribute(Integer.toString(engine.getMoves()), 5); 249 } else if (sortByComboBox 250 .getSelectedIndex() == _etf.enginesTableModel.SORTBY_DCC_ADDRESS) { 251 dccAddress = padAttribute(engine.getDccAddress(), 5); 252 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_LAST) { 253 last = padAttribute(engine.getSortDate(), lastLength); 254 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_VALUE) { 255 value = padAttribute(engine.getValue(), Control.max_len_string_attibute); 256 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_RFID) { 257 rfid = padAttribute(engine.getRfid(), Control.max_len_string_attibute); 258 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_BUILT) { 259 built = padAttribute(engine.getBuilt(), Control.max_len_string_built_name); 260 } else if (sortByComboBox 261 .getSelectedIndex() == _etf.enginesTableModel.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}