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 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 } catch (IOException we) { 149 log.error("Error printing ConsistRosterEntry: {}", we.getLocalizedMessage()); 150 } catch (HardcopyWriter.PrintCanceledException ex) { 151 log.debug("Print canceled"); 152 } 153 } 154 155 private String createHeader() { 156 StringBuffer header = new StringBuffer(); 157 158 header.append(padAttribute(Bundle.getMessage("Number"), Control.max_len_string_print_road_number) + 159 padAttribute(Bundle.getMessage("Road"), 160 InstanceManager.getDefault(CarRoads.class).getMaxNameLength()) + 161 padAttribute(Bundle.getMessage("Model"), 162 InstanceManager.getDefault(EngineModels.class).getMaxNameLength()) + 163 padAttribute(Bundle.getMessage("Type"), 164 InstanceManager.getDefault(EngineTypes.class).getMaxNameLength()) + 165 padAttribute(Bundle.getMessage("Len"), Control.max_len_string_length_name)); 166 167 if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_TRAIN || 168 sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_DESTINATION) { 169 header.append(padAttribute(Bundle.getMessage("Train"), Control.max_len_string_train_name / 2)); 170 } else { 171 header.append(padAttribute(Bundle.getMessage("Consist"), 172 InstanceManager.getDefault(ConsistManager.class).getMaxNameLength())); 173 } 174 header.append(padAttribute(Bundle.getMessage("Location"), 175 locationManager.getMaxLocationAndTrackNameLength() + 3)); 176 // one of eight user selections 177 if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_OWNER) { 178 header.append(padAttribute(Bundle.getMessage("Owner"), Control.max_len_string_attibute)); 179 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_MOVES) { 180 header.append(padAttribute(Bundle.getMessage("Moves"), 5)); 181 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_VALUE) { 182 header.append(padAttribute(Setup.getValueLabel(), Control.max_len_string_attibute)); 183 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_LAST) { 184 header.append(padAttribute(Bundle.getMessage("LastMoved"), lastLength)); 185 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_RFID) { 186 header.append(padAttribute(Setup.getRfidLabel(), Control.max_len_string_attibute)); 187 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_DCC_ADDRESS) { 188 header.append(padAttribute(Bundle.getMessage("DccAddress"), 5)); 189 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_BUILT) { 190 header.append(padAttribute(Bundle.getMessage("Built"), Control.max_len_string_built_name)); 191 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_DESTINATION) { 192 header.append(Bundle.getMessage("Destination")); 193 } else { 194 header.append(padAttribute(Bundle.getMessage("Comment"), engineManager.getMaxCommentLength())); 195 } 196 return header.toString() + NEW_LINE; 197 } 198 199 private void printRoster(HardcopyWriter writer) throws IOException { 200 // Loop through the Roster, printing as needed 201 String number; 202 String road; 203 String model; 204 String type; 205 String length; 206 String train = ""; 207 String consist = ""; 208 String location = ""; 209 String moves = ""; 210 String owner = ""; 211 String built = ""; 212 String dccAddress = ""; 213 String value = ""; 214 String rfid = ""; 215 String last = ""; 216 String comment = ""; 217 218 List<Engine> engines = _etf.enginesTableModel.getEngineList(sortByComboBox.getSelectedIndex()); 219 for (Engine engine : engines) { 220 if (printLocosWithLocation.isSelected() && engine.getLocation() == null) { 221 continue; 222 } 223 String destination = ""; 224 // engine number, road, model, type, and length are always printed 225 number = padAttribute(engine.getNumber(), Control.max_len_string_print_road_number); 226 road = padAttribute(engine.getRoadName(), 227 InstanceManager.getDefault(CarRoads.class).getMaxNameLength()); 228 model = padAttribute(engine.getModel(), 229 InstanceManager.getDefault(EngineModels.class).getMaxNameLength()); 230 type = padAttribute(engine.getTypeName(), 231 InstanceManager.getDefault(EngineTypes.class).getMaxNameLength()); 232 length = padAttribute(engine.getLength(), Control.max_len_string_length_name); 233 234 // show train or consist name 235 if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_TRAIN || 236 sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_DESTINATION) { 237 train = padAttribute(engine.getTrainName().trim(), Control.max_len_string_train_name / 2); 238 } else { 239 consist = padAttribute(engine.getConsistName(), 240 InstanceManager.getDefault(ConsistManager.class).getMaxNameLength()); 241 } 242 243 // show one of 8 options, comment is default 244 if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_OWNER) { 245 owner = padAttribute(engine.getOwnerName(), Control.max_len_string_attibute); 246 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_MOVES) { 247 moves = padAttribute(Integer.toString(engine.getMoves()), 5); 248 } else if (sortByComboBox 249 .getSelectedIndex() == _etf.enginesTableModel.SORTBY_DCC_ADDRESS) { 250 dccAddress = padAttribute(engine.getDccAddress(), 5); 251 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_LAST) { 252 last = padAttribute(engine.getSortDate(), lastLength); 253 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_VALUE) { 254 value = padAttribute(engine.getValue(), Control.max_len_string_attibute); 255 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_RFID) { 256 rfid = padAttribute(engine.getRfid(), Control.max_len_string_attibute); 257 } else if (sortByComboBox.getSelectedIndex() == _etf.enginesTableModel.SORTBY_BUILT) { 258 built = padAttribute(engine.getBuilt(), Control.max_len_string_built_name); 259 } else if (sortByComboBox 260 .getSelectedIndex() == _etf.enginesTableModel.SORTBY_DESTINATION) { 261 if (engine.getDestination() != null) { 262 destination = padAttribute( 263 engine.getDestinationName() + " - " + engine.getDestinationTrackName(), 264 locationManager.getMaxLocationAndTrackNameLength() + 265 3); 266 } 267 } else { 268 comment = padAttribute(engine.getComment(), engineManager.getMaxCommentLength()); 269 } 270 271 if (!engine.getLocationName().equals(Engine.NONE)) { 272 location = padAttribute(engine.getLocationName() + " - " + engine.getTrackName(), 273 locationManager.getMaxLocationAndTrackNameLength() + 3); 274 } else { 275 location = padAttribute("", 276 locationManager.getMaxLocationAndTrackNameLength() + 3); 277 } 278 279 String s = number + 280 road + 281 model + 282 type + 283 length + 284 consist + 285 train + 286 location + 287 moves + 288 owner + 289 value + 290 rfid + 291 dccAddress + 292 built + 293 last + 294 comment + 295 destination; 296 write(writer, s); 297 } 298 } 299 300 private void write(HardcopyWriter writer, String s) throws IOException { 301 if (s.length() > numberCharPerLine) { 302 s = s.substring(0, numberCharPerLine); 303 } 304 writer.write(s + NEW_LINE); 305 } 306 307 private String padAttribute(String attribute, int length) { 308 return TrainCommon.padAndTruncate(attribute, length) + TrainCommon.SPACE; 309 } 310 311 private final static Logger log = LoggerFactory.getLogger(PrintEngineRosterFrame.class); 312}