/** * Frame for adding and editing the train roster for operations. * * @author Bob Jacobsen Copyright (C) 2001 * @author Daniel Boudreau Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 * @version $Revision$ */ public class TrainsTableFrame extends OperationsFrame implements java.beans.PropertyChangeListener { /** */ private static final long serialVersionUID = 4237149773850338265L; public static final String MOVE = Bundle.getMessage("Move"); public static final String TERMINATE = Bundle.getMessage("Terminate"); public static final String RESET = Bundle.getMessage("Reset"); public static final String CONDUCTOR = Bundle.getMessage("Conductor"); CarManagerXml carManagerXml = CarManagerXml.instance(); // load cars EngineManagerXml engineManagerXml = EngineManagerXml.instance(); // load engines TrainManager trainManager = TrainManager.instance(); TrainManagerXml trainManagerXml = TrainManagerXml.instance(); LocationManager locationManager = LocationManager.instance(); TrainsTableModel trainsModel; TableSorter sorter; JTable trainsTable; JScrollPane trainsPane; // labels JLabel numTrains = new JLabel(); JLabel textTrains = new JLabel(Bundle.getMessage("Trains").toLowerCase()); JLabel textSep1 = new JLabel(" "); // radio buttons JRadioButton showTime = new JRadioButton(Bundle.getMessage("Time")); JRadioButton showId = new JRadioButton(Bundle.getMessage("Id")); JRadioButton moveRB = new JRadioButton(MOVE); JRadioButton terminateRB = new JRadioButton(TERMINATE); JRadioButton resetRB = new JRadioButton(RESET); JRadioButton conductorRB = new JRadioButton(CONDUCTOR); // major buttons JButton addButton = new JButton(Bundle.getMessage("Add")); JButton buildButton = new JButton(Bundle.getMessage("Build")); JButton printButton = new JButton(Bundle.getMessage("Print")); JButton openFileButton = new JButton(Bundle.getMessage("OpenFile")); JButton runFileButton = new JButton(Bundle.getMessage("RunFile")); JButton switchListsButton = new JButton(Bundle.getMessage("SwitchLists")); JButton terminateButton = new JButton(Bundle.getMessage("Terminate")); JButton saveButton = new JButton(Bundle.getMessage("SaveBuilds")); // check boxes JCheckBox buildMsgBox = new JCheckBox(Bundle.getMessage("BuildMessages")); JCheckBox buildReportBox = new JCheckBox(Bundle.getMessage("BuildReport")); JCheckBox printPreviewBox = new JCheckBox(Bundle.getMessage("Preview")); JCheckBox openFileBox = new JCheckBox(Bundle.getMessage("OpenFile")); JCheckBox runFileBox = new JCheckBox(Bundle.getMessage("RunFile")); JCheckBox showAllBox = new JCheckBox(Bundle.getMessage("ShowAllTrains")); public TrainsTableFrame() { super(); updateTitle(); // create ShutDownTasks createShutDownTask(); // always check for dirty operations files setModifiedFlag(true); // general GUI configuration getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); // Set up the jtable in a Scroll Pane.. trainsModel = new TrainsTableModel(); sorter = new TableSorter(trainsModel); trainsTable = new JTable(sorter); sorter.setTableHeader(trainsTable.getTableHeader()); trainsPane = new JScrollPane(trainsTable); trainsModel.initTable(trainsTable, this); // Set up the control panel // row 1 JPanel cp1 = new JPanel(); cp1.setLayout(new BoxLayout(cp1, BoxLayout.X_AXIS)); JPanel show = new JPanel(); show.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ShowClickToSort"))); show.add(showTime); show.add(showId); JPanel options = new JPanel(); options.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options"))); options.add(showAllBox); options.add(buildMsgBox); options.add(buildReportBox); options.add(printPreviewBox); options.add(openFileBox); options.add(runFileBox); JPanel action = new JPanel(); action.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Action"))); action.add(moveRB); action.add(conductorRB); action.add(terminateRB); action.add(resetRB); cp1.add(show); cp1.add(options); cp1.add(action); // tool tips, see setPrintButtonText() for more tool tips addButton.setToolTipText(Bundle.getMessage("AddTrain")); buildButton.setToolTipText(Bundle.getMessage("BuildSelectedTip")); switchListsButton.setToolTipText(Bundle.getMessage("PreviewPrintSwitchLists")); terminateButton.setToolTipText(Bundle.getMessage("TerminateSelectedTip")); saveButton.setToolTipText(Bundle.getMessage("SaveBuildsTip")); openFileButton.setToolTipText(Bundle.getMessage("OpenFileButtonTip")); runFileButton.setToolTipText(Bundle.getMessage("RunFileButtonTip")); buildMsgBox.setToolTipText(Bundle.getMessage("BuildMessagesTip")); printPreviewBox.setToolTipText(Bundle.getMessage("PreviewTip")); openFileBox.setToolTipText(Bundle.getMessage("OpenFileTip")); runFileBox.setToolTipText(Bundle.getMessage("RunFileTip")); showAllBox.setToolTipText(Bundle.getMessage("ShowAllTrainsTip")); moveRB.setToolTipText(Bundle.getMessage("MoveTip")); terminateRB.setToolTipText(Bundle.getMessage("TerminateTip")); resetRB.setToolTipText(Bundle.getMessage("ResetTip")); // row 2 JPanel addTrain = new JPanel(); addTrain.setBorder(BorderFactory.createTitledBorder("")); addTrain.add(numTrains); addTrain.add(textTrains); addTrain.add(textSep1); addTrain.add(addButton); numTrains.setText(Integer.toString(trainManager.getNumEntries())); JPanel select = new JPanel(); select.setBorder(BorderFactory.createTitledBorder("")); select.add(buildButton); select.add(printButton); select.add(openFileButton); select.add(runFileButton); select.add(switchListsButton); select.add(terminateButton); JPanel save = new JPanel(); save.setBorder(BorderFactory.createTitledBorder("")); save.add(saveButton); JPanel cp2 = new JPanel(); cp2.setLayout(new BoxLayout(cp2, BoxLayout.X_AXIS)); cp2.add(addTrain); cp2.add(select); cp2.add(save); // place controls in scroll pane JPanel controlPanel = new JPanel(); controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); controlPanel.add(cp1); controlPanel.add(cp2); JScrollPane controlPane = new JScrollPane(controlPanel); getContentPane().add(trainsPane); getContentPane().add(controlPane); // setup buttons addButtonAction(addButton); addButtonAction(buildButton); addButtonAction(printButton); addButtonAction(openFileButton); addButtonAction(runFileButton); addButtonAction(switchListsButton); addButtonAction(terminateButton); addButtonAction(saveButton); ButtonGroup showGroup = new ButtonGroup(); showGroup.add(showTime); showGroup.add(showId); showTime.setSelected(true); ButtonGroup actionGroup = new ButtonGroup(); actionGroup.add(moveRB); actionGroup.add(conductorRB); actionGroup.add(terminateRB); actionGroup.add(resetRB); addRadioButtonAction(showTime); addRadioButtonAction(showId); addRadioButtonAction(moveRB); addRadioButtonAction(terminateRB); addRadioButtonAction(resetRB); addRadioButtonAction(conductorRB); buildMsgBox.setSelected(trainManager.isBuildMessagesEnabled()); buildReportBox.setSelected(trainManager.isBuildReportEnabled()); printPreviewBox.setSelected(trainManager.isPrintPreviewEnabled()); openFileBox.setSelected(trainManager.isOpenFileEnabled()); runFileBox.setSelected(trainManager.isRunFileEnabled()); showAllBox.setSelected(trainsModel.isShowAll()); // show open files only if create csv is enabled updateRunAndOpenButtons(); addCheckBoxAction(buildMsgBox); addCheckBoxAction(buildReportBox); addCheckBoxAction(printPreviewBox); addCheckBoxAction(showAllBox); addCheckBoxAction(openFileBox); addCheckBoxAction(runFileBox); // Set the button text to Print or Preview setPrintButtonText(); // Set the train action button text to Move or Terminate setTrainActionButton(); // build menu JMenuBar menuBar = new JMenuBar(); JMenu toolMenu = new JMenu(Bundle.getMessage("Tools")); toolMenu.add(new OptionAction(Bundle.getMessage("TitleOptions"))); toolMenu.add(new PrintOptionAction()); toolMenu.add(new BuildReportOptionAction()); toolMenu.add(new TrainsByCarTypeAction(Bundle.getMessage("TitleModifyTrains"))); toolMenu.add(new TrainByCarTypeAction(Bundle.getMessage("MenuItemShowCarTypes"), null)); toolMenu.add(new ChangeDepartureTimesAction(Bundle.getMessage("TitleChangeDepartureTime"))); toolMenu.add(new TrainsTableSetColorAction()); toolMenu.add(new TrainsScheduleAction(Bundle.getMessage("TitleTimeTableTrains"))); toolMenu.add(new TrainCopyAction(Bundle.getMessage("TitleTrainCopy"))); toolMenu.add(new TrainsScriptAction(Bundle.getMessage("MenuItemScripts"), this)); toolMenu.add( new PrintSavedTrainManifestAction(Bundle.getMessage("MenuItemPrintSavedManifest"), false)); toolMenu.add( new PrintSavedTrainManifestAction(Bundle.getMessage("MenuItemPreviewSavedManifest"), true)); toolMenu.add(new SetupExcelProgramFrameAction(Bundle.getMessage("MenuItemSetupExcelProgram"))); toolMenu.add(new ExportTrainRosterAction()); toolMenu.add( new PrintTrainsAction(Bundle.getMessage("MenuItemPrint"), new Frame(), false, this)); toolMenu.add( new PrintTrainsAction(Bundle.getMessage("MenuItemPreview"), new Frame(), true, this)); menuBar.add(toolMenu); menuBar.add(new jmri.jmrit.operations.OperationsMenu()); setJMenuBar(menuBar); // add help menu to window addHelpMenu("package.jmri.jmrit.operations.Operations_Trains", true); // NOI18N initMinimumSize(); addHorizontalScrollBarKludgeFix(controlPane, controlPanel); // listen for timetable changes trainManager.addPropertyChangeListener(this); Setup.addPropertyChangeListener(this); // listen for location switch list changes addPropertyChangeLocations(); // auto save new AutoSave(); } public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { log.debug("radio button activated"); if (ae.getSource() == showId) { trainsModel.setSort(trainsModel.SORTBYID); } if (ae.getSource() == showTime) { trainsModel.setSort(trainsModel.SORTBYTIME); } if (ae.getSource() == moveRB) { trainManager.setTrainsFrameTrainAction(MOVE); } if (ae.getSource() == terminateRB) { trainManager.setTrainsFrameTrainAction(TERMINATE); } if (ae.getSource() == resetRB) { trainManager.setTrainsFrameTrainAction(RESET); } if (ae.getSource() == conductorRB) { trainManager.setTrainsFrameTrainAction(CONDUCTOR); } } TrainSwitchListEditFrame tslef; // add, build, print, switch lists, terminate, and save buttons public void buttonActionPerformed(java.awt.event.ActionEvent ae) { // log.debug("train button activated"); if (ae.getSource() == addButton) { new TrainEditFrame(null); } if (ae.getSource() == buildButton) { // uses a thread which allows table updates during build trainManager.buildSelectedTrains(getSortByList()); } if (ae.getSource() == printButton) { trainManager.printSelectedTrains(getSortByList()); } if (ae.getSource() == openFileButton) { // open the csv files List<Train> trains = getSortByList(); for (Train train : trains) { if (train.isBuildEnabled()) { if (!train.isBuilt() && trainManager.isBuildMessagesEnabled()) { JOptionPane.showMessageDialog( this, MessageFormat.format( Bundle.getMessage("NeedToBuildBeforeOpenFile"), new Object[] { train.getName(), (trainManager.isPrintPreviewEnabled() ? Bundle.getMessage("preview") : Bundle.getMessage("print")) }), MessageFormat.format( Bundle.getMessage("CanNotPrintManifest"), new Object[] { trainManager.isPrintPreviewEnabled() ? Bundle.getMessage("preview") : Bundle.getMessage("print") }), JOptionPane.ERROR_MESSAGE); } else if (train.isBuilt()) { train.openFile(); } } } } if (ae.getSource() == runFileButton) { // Processes the CSV Manifest files using an external custom program. if (!TrainCustomManifest.manifestCreatorFileExists()) { log.warn( "Manifest creator file not found!, directory name: " + TrainCustomManifest.getDirectoryName() + ", file name: " + TrainCustomManifest.getFileName()); // NOI18N JOptionPane.showMessageDialog( this, MessageFormat.format( Bundle.getMessage("LoadDirectoryNameFileName"), new Object[] { TrainCustomManifest.getDirectoryName(), TrainCustomManifest.getFileName() }), Bundle.getMessage("ManifestCreatorNotFound"), JOptionPane.ERROR_MESSAGE); return; } List<Train> trains = getSortByList(); for (Train train : trains) { if (train.isBuildEnabled()) { if (!train.isBuilt() && trainManager.isBuildMessagesEnabled()) { JOptionPane.showMessageDialog( this, MessageFormat.format( Bundle.getMessage("NeedToBuildBeforeRunFile"), new Object[] { train.getName(), (trainManager.isPrintPreviewEnabled() ? Bundle.getMessage("preview") : Bundle.getMessage("print")) }), MessageFormat.format( Bundle.getMessage("CanNotPrintManifest"), new Object[] { trainManager.isPrintPreviewEnabled() ? Bundle.getMessage("preview") : Bundle.getMessage("print") }), JOptionPane.ERROR_MESSAGE); } else if (train.isBuilt()) { // Make sure our csv manifest file exists for this Train. File csvFile = train.createCSVManifestFile(); // Add it to our collection to be processed. TrainCustomManifest.addCVSFile(csvFile); } } } // Now run the user specified custom Manifest processor program TrainCustomManifest.process(); } if (ae.getSource() == switchListsButton) { if (tslef != null) { tslef.dispose(); } tslef = new TrainSwitchListEditFrame(); tslef.initComponents(); } if (ae.getSource() == terminateButton) { trainManager.terminateSelectedTrains(getSortByList()); } if (ae.getSource() == saveButton) { storeValues(); } } int _status = TableSorter.ASCENDING; protected String getSortBy() { // set the defaults String sortBy = TrainsTableModel.TIMECOLUMNNAME; _status = TableSorter.ASCENDING; // now look to see if a sort is active for (int i = 0; i < sorter.getColumnCount(); i++) { String name = sorter.getColumnName(i); int status = sorter.getSortingStatus(i); // log.debug("Column " + name + " status " + status); if (status != TableSorter.NOT_SORTED && !name.equals("")) { sortBy = name; _status = status; break; } } return sortBy; } public List<Train> getSortByList() { List<Train> sysList; String sortBy = getSortBy(); if (sortBy.equals(TrainsTableModel.IDCOLUMNNAME)) { sysList = trainManager.getTrainsByIdList(); } else if (sortBy.equals(TrainsTableModel.TIMECOLUMNNAME)) { sysList = trainManager.getTrainsByTimeList(); } else if (sortBy.equals(TrainsTableModel.DEPARTSCOLUMNNAME)) { sysList = trainManager.getTrainsByDepartureList(); } else if (sortBy.equals(TrainsTableModel.TERMINATESCOLUMNNAME)) { sysList = trainManager.getTrainsByTerminatesList(); } else if (sortBy.equals(TrainsTableModel.ROUTECOLUMNNAME)) { sysList = trainManager.getTrainsByRouteList(); } else if (sortBy.equals(TrainsTableModel.STATUSCOLUMNNAME)) { sysList = trainManager.getTrainsByStatusList(); } else if (sortBy.equals(TrainsTableModel.DESCRIPTIONCOLUMNNAME)) { sysList = trainManager.getTrainsByDescriptionList(); } else { sysList = trainManager.getTrainsByNameList(); } return sysList; } // Modifies button text and tool tips private void setPrintButtonText() { if (printPreviewBox.isSelected()) { printButton.setText(Bundle.getMessage("Preview")); printButton.setToolTipText(Bundle.getMessage("PreviewSelectedTip")); buildReportBox.setToolTipText(Bundle.getMessage("BuildReportPreviewTip")); } else { printButton.setText(Bundle.getMessage("Print")); printButton.setToolTipText(Bundle.getMessage("PrintSelectedTip")); buildReportBox.setToolTipText(Bundle.getMessage("BuildReportPrintTip")); } } private void setTrainActionButton() { moveRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.MOVE)); terminateRB.setSelected( trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.TERMINATE)); resetRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.RESET)); conductorRB.setSelected( trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.CONDUCTOR)); } public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { if (ae.getSource() == buildMsgBox) { trainManager.setBuildMessagesEnabled(buildMsgBox.isSelected()); } if (ae.getSource() == buildReportBox) { trainManager.setBuildReportEnabled(buildReportBox.isSelected()); } if (ae.getSource() == printPreviewBox) { trainManager.setPrintPreviewEnabled(printPreviewBox.isSelected()); setPrintButtonText(); // set the button text for Print or Preview } if (ae.getSource() == openFileBox) { trainManager.setOpenFileEnabled(openFileBox.isSelected()); runFileBox.setSelected(false); trainManager.setRunFileEnabled(false); } if (ae.getSource() == runFileBox) { trainManager.setRunFileEnabled(runFileBox.isSelected()); openFileBox.setSelected(false); trainManager.setOpenFileEnabled(false); } if (ae.getSource() == showAllBox) { trainsModel.setShowAll(showAllBox.isSelected()); } } private void updateTitle() { String title = Bundle.getMessage("TitleTrainsTable"); TrainSchedule sch = TrainScheduleManager.instance().getScheduleById(trainManager.getTrainScheduleActiveId()); if (sch != null) { title = title + " (" + sch.getName() + ")"; } setTitle(title); } private void updateSwitchListButton() { log.debug("update switch list button"); List<Location> locations = locationManager.getList(); for (Location location : locations) { if (location != null && location.isSwitchListEnabled() && location.getStatus().equals(Location.MODIFIED)) { switchListsButton.setBackground(Color.RED); return; } } switchListsButton.setBackground(Color.GREEN); } // show open files only if create csv is enabled private void updateRunAndOpenButtons() { openFileBox.setVisible(Setup.isGenerateCsvManifestEnabled()); openFileButton.setVisible(Setup.isGenerateCsvManifestEnabled()); runFileBox.setVisible(Setup.isGenerateCsvManifestEnabled()); runFileButton.setVisible(Setup.isGenerateCsvManifestEnabled()); } private synchronized void addPropertyChangeLocations() { List<Location> locations = locationManager.getList(); for (Location location : locations) { location.addPropertyChangeListener(this); } } private synchronized void removePropertyChangeLocations() { List<Location> locations = locationManager.getList(); for (Location location : locations) { location.removePropertyChangeListener(this); } } public void dispose() { /* * all JMRI window position and size are now saved in user preference file * trainManager.setTrainsFrameTableColumnWidths(getCurrentTableColumnWidths()); // save column widths * trainManager.setTrainsFrame(null); */ trainsModel.dispose(); trainManager.runShutDownScripts(); trainManager.removePropertyChangeListener(this); Setup.removePropertyChangeListener(this); removePropertyChangeLocations(); super.dispose(); } protected void handleModified() { if (Setup.isAutoSaveEnabled()) { storeValues(); return; } if (OperationsXml.areFilesDirty()) { int result = javax.swing.JOptionPane.showOptionDialog( this, Bundle.getMessage("PromptQuitWindowNotWritten"), Bundle.getMessage("PromptSaveQuit"), javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.WARNING_MESSAGE, null, // icon new String[] { ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnYesSave"), // NOI18N ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnNoClose") }, // NOI18N ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnYesSave")); if (result == javax.swing.JOptionPane.NO_OPTION) { return; } // user wants to save storeValues(); } } protected void storeValues() { super.storeValues(); saveTableDetails(trainsTable); } public void propertyChange(java.beans.PropertyChangeEvent e) { if (Control.showProperty) { log.debug( "Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e.getNewValue()); } if (e.getPropertyName().equals(TrainManager.ACTIVE_TRAIN_SCHEDULE_ID)) { updateTitle(); } if (e.getPropertyName().equals(Location.STATUS_CHANGED_PROPERTY) || e.getPropertyName().equals(Location.SWITCHLIST_CHANGED_PROPERTY)) { updateSwitchListButton(); } if (e.getPropertyName().equals(Setup.MANIFEST_CSV_PROPERTY_CHANGE)) { updateRunAndOpenButtons(); } if (e.getPropertyName().equals(TrainManager.LISTLENGTH_CHANGED_PROPERTY)) { numTrains.setText(Integer.toString(trainManager.getNumEntries())); } } static Logger log = LoggerFactory.getLogger(TrainsTableFrame.class.getName()); }
/** * Frame for adding and editing train schedules (Timetable) for operations. * * @author Bob Jacobsen Copyright (C) 2001 * @author Daniel Boudreau Copyright (C) 2010, 2012 * @version $Revision$ */ public class TrainsScheduleTableFrame extends OperationsFrame implements PropertyChangeListener { // public static SwingShutDownTask trainDirtyTask; public static final String NAME = Bundle.getMessage("Name"); // Sort by choices public static final String TIME = Bundle.getMessage("Time"); TrainManager trainManager = TrainManager.instance(); TrainScheduleManager trainScheduleManager = TrainScheduleManager.instance(); LocationManager locationManager = LocationManager.instance(); TrainsScheduleTableModel trainsScheduleModel = new TrainsScheduleTableModel(); javax.swing.JTable trainsScheduleTable = new javax.swing.JTable(trainsScheduleModel); JScrollPane trainsPane; // labels JLabel textSort = new JLabel(Bundle.getMessage("SortBy")); // radio buttons JRadioButton sortByName = new JRadioButton(NAME); JRadioButton sortByTime = new JRadioButton(TIME); JRadioButton noneButton = new JRadioButton(Bundle.getMessage("None")); // radio button groups ButtonGroup schGroup = new ButtonGroup(); // major buttons JButton selectButton = new JButton(Bundle.getMessage("Select")); JButton clearButton = new JButton(Bundle.getMessage("Clear")); JButton applyButton = new JButton(Bundle.getMessage("Apply")); JButton buildButton = new JButton(Bundle.getMessage("Build")); JButton printButton = new JButton(Bundle.getMessage("Print")); JButton switchListsButton = new JButton(); JButton terminateButton = new JButton(Bundle.getMessage("Terminate")); JButton activateButton = new JButton(Bundle.getMessage("Activate")); JButton saveButton = new JButton(Bundle.getMessage("Save")); // check boxes // panel JPanel schedule = new JPanel(); // text area JTextArea commentTextArea = new JTextArea(2, 70); JScrollPane commentScroller = new JScrollPane( commentTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); public TrainsScheduleTableFrame() { // general GUI configuration getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); // Set up the jtable in a Scroll Pane.. trainsPane = new JScrollPane(trainsScheduleTable); trainsPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); trainsPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); trainsScheduleModel.initTable(trainsScheduleTable, this); // row comment JPanel pC = new JPanel(); pC.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); pC.setLayout(new GridBagLayout()); addItem(pC, commentScroller, 1, 0); // adjust text area width based on window size adjustTextAreaColumnWidth(commentScroller, commentTextArea); // Set up the control panel // row 1 JPanel cp1 = new JPanel(); cp1.setLayout(new BoxLayout(cp1, BoxLayout.X_AXIS)); // row 1 JPanel sortBy = new JPanel(); sortBy.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("SortBy"))); sortBy.add(sortByTime); sortBy.add(sortByName); // row 2 schedule.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Active"))); updateControlPanel(); cp1.add(sortBy); cp1.add(schedule); JPanel pButtons = new JPanel(); pButtons.setLayout(new BoxLayout(pButtons, BoxLayout.X_AXIS)); JPanel cp3 = new JPanel(); cp3.setBorder(BorderFactory.createTitledBorder("")); cp3.add(clearButton); cp3.add(selectButton); JPanel cp4 = new JPanel(); cp4.setBorder(BorderFactory.createTitledBorder("")); cp4.add(applyButton); cp4.add(buildButton); cp4.add(printButton); cp4.add(switchListsButton); cp4.add(terminateButton); JPanel cp5 = new JPanel(); cp5.setBorder(BorderFactory.createTitledBorder("")); cp5.add(activateButton); cp5.add(saveButton); pButtons.add(cp3); pButtons.add(cp4); pButtons.add(cp5); // tool tips selectButton.setToolTipText(Bundle.getMessage("SelectAllButtonTip")); clearButton.setToolTipText(Bundle.getMessage("ClearAllButtonTip")); applyButton.setToolTipText(Bundle.getMessage("ApplyButtonTip")); buildButton.setToolTipText(Bundle.getMessage("BuildSelectedTip")); activateButton.setToolTipText(Bundle.getMessage("ActivateButtonTip")); terminateButton.setToolTipText(Bundle.getMessage("TerminateSelectedTip")); setPrintButtonText(); setSwitchListButtonText(); // place controls in scroll pane JPanel controlPanel = new JPanel(); controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); controlPanel.add(pC); controlPanel.add(cp1); controlPanel.add(pButtons); JScrollPane controlPane = new JScrollPane(controlPanel); // make sure control panel is the right size controlPane.setMinimumSize(new Dimension(500, 480)); controlPane.setMaximumSize(new Dimension(2000, 500)); controlPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); getContentPane().add(trainsPane); getContentPane().add(controlPane); // setup buttons addButtonAction(clearButton); addButtonAction(selectButton); addButtonAction(applyButton); addButtonAction(buildButton); addButtonAction(printButton); addButtonAction(switchListsButton); addButtonAction(terminateButton); addButtonAction(activateButton); addButtonAction(saveButton); ButtonGroup sortGroup = new ButtonGroup(); sortGroup.add(sortByTime); sortGroup.add(sortByName); sortByTime.setSelected(true); addRadioButtonAction(sortByTime); addRadioButtonAction(sortByName); addRadioButtonAction(noneButton); // build menu JMenuBar menuBar = new JMenuBar(); JMenu toolMenu = new JMenu(Bundle.getMessage("Tools")); toolMenu.add(new TrainsScheduleEditAction()); menuBar.add(toolMenu); setJMenuBar(menuBar); // add help menu to window addHelpMenu("package.jmri.jmrit.operations.Operations_Timetable", true); // NOI18N setTitle(Bundle.getMessage("TitleTimeTableTrains")); initMinimumSize(new Dimension(Control.panelWidth700, Control.panelHeight500)); addHorizontalScrollBarKludgeFix(controlPane, controlPanel); Setup.addPropertyChangeListener(this); trainManager.addPropertyChangeListener(this); trainScheduleManager.addPropertyChangeListener(this); addPropertyChangeLocations(); addPropertyChangeTrainSchedules(); } public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { log.debug("radio button activated"); if (ae.getSource() == sortByName) { trainsScheduleModel.setSort(trainsScheduleModel.SORTBYNAME); } else if (ae.getSource() == sortByTime) { trainsScheduleModel.setSort(trainsScheduleModel.SORTBYTIME); } else if (ae.getSource() == noneButton) { enableButtons(false); commentTextArea.setText(""); // no text for the noneButton // must be one of the schedule radio buttons } else { enableButtons(true); // update comment field TrainSchedule ts = trainScheduleManager.getScheduleById(getSelectedScheduleId()); commentTextArea.setText(ts.getComment()); } } // add, build, print, switch lists, terminate, and save buttons public void buttonActionPerformed(java.awt.event.ActionEvent ae) { log.debug("button activated"); if (ae.getSource() == clearButton) { updateCheckboxes(false); } if (ae.getSource() == selectButton) { updateCheckboxes(true); } if (ae.getSource() == applyButton) { applySchedule(); } if (ae.getSource() == buildButton) { switchListsButton.setEnabled(false); // uses a thread which allows table updates during build trainManager.buildSelectedTrains(getSortByList()); } if (ae.getSource() == printButton) { trainManager.printSelectedTrains(getSortByList()); } if (ae.getSource() == switchListsButton) { trainScheduleManager.buildSwitchLists(); } if (ae.getSource() == terminateButton) { trainManager.terminateSelectedTrains(getSortByList()); } if (ae.getSource() == activateButton) { trainManager.setTrainSecheduleActiveId(getSelectedScheduleId()); activateButton.setEnabled(false); } if (ae.getSource() == saveButton) { storeValues(); if (Setup.isCloseWindowOnSaveEnabled()) { dispose(); } } } /* * Update radio button names in the same order as the table */ private void updateControlPanel() { schedule.removeAll(); noneButton.setName(""); // Name holds schedule id for the selected radio button noneButton.setSelected(true); commentTextArea.setText(""); // no text for the noneButton enableButtons(false); schedule.add(noneButton); schGroup.add(noneButton); for (int i = trainsScheduleModel.getFixedColumn(); i < trainsScheduleModel.getColumnCount(); i++) { log.debug("Column name: {}", trainsScheduleTable.getColumnName(i)); TrainSchedule ts = trainScheduleManager.getScheduleByName(trainsScheduleTable.getColumnName(i)); if (ts != null) { JRadioButton b = new JRadioButton(); b.setText(ts.getName()); b.setName(ts.getId()); schedule.add(b); schGroup.add(b); addRadioButtonAction(b); if (b.getName().equals(trainManager.getTrainScheduleActiveId())) { b.setSelected(true); enableButtons(true); // update comment field commentTextArea.setText(ts.getComment()); } } } schedule.revalidate(); } private void updateCheckboxes(boolean selected) { TrainSchedule ts = trainScheduleManager.getScheduleById(getSelectedScheduleId()); if (ts != null) { for (Train train : trainManager.getTrainsByIdList()) { if (selected) { ts.addTrainId(train.getId()); } else { ts.removeTrainId(train.getId()); } } } } private void applySchedule() { TrainSchedule ts = trainScheduleManager.getScheduleById(getSelectedScheduleId()); if (ts != null) { for (Train train : trainManager.getTrainsByIdList()) { train.setBuildEnabled(ts.containsTrainId(train.getId())); } } } private String getSelectedScheduleId() { AbstractButton b; Enumeration<AbstractButton> en = schGroup.getElements(); while (en.hasMoreElements()) { b = en.nextElement(); if (b.isSelected()) { log.debug("schedule radio button " + b.getText()); return b.getName(); } } return null; } private void enableButtons(boolean enable) { selectButton.setEnabled(enable); clearButton.setEnabled(enable); applyButton.setEnabled(enable); buildButton.setEnabled(enable); printButton.setEnabled(enable); switchListsButton.setEnabled(enable); terminateButton.setEnabled(enable); log.debug( "Selected id: {}, Active id: {}", getSelectedScheduleId(), trainManager.getTrainScheduleActiveId()); activateButton.setEnabled( getSelectedScheduleId() != null && !getSelectedScheduleId().equals(trainManager.getTrainScheduleActiveId())); commentTextArea.setEnabled(enable); } private List<Train> getSortByList() { if (sortByTime.isSelected()) { return trainManager.getTrainsByTimeList(); } else { return trainManager.getTrainsByNameList(); } } private void setSwitchListButtonText() { if (!Setup.isSwitchListRealTime()) { switchListsButton.setText(Bundle.getMessage("Update")); } else if (trainManager.isPrintPreviewEnabled()) { switchListsButton.setText(Bundle.getMessage("PreviewSwitchLists")); } else { switchListsButton.setText(Bundle.getMessage("PrintSwitchLists")); } } // Modifies button text and tool tips private void setPrintButtonText() { if (trainManager.isPrintPreviewEnabled()) { printButton.setText(Bundle.getMessage("Preview")); printButton.setToolTipText(Bundle.getMessage("PreviewSelectedTip")); } else { printButton.setText(Bundle.getMessage("Print")); printButton.setToolTipText(Bundle.getMessage("PrintSelectedTip")); } } // private void buildSwitchList() { // TrainSwitchLists trainSwitchLists = new TrainSwitchLists(); // for (Location location : locationManager.getLocationsByNameList()) { // if (location.isSwitchListEnabled()) { // trainSwitchLists.buildSwitchList(location); // // // print or print changes // if (Setup.isSwitchListRealTime() && // !location.getStatus().equals(Location.PRINTED)) { // trainSwitchLists.printSwitchList(location, // trainManager.isPrintPreviewEnabled()); // } // } // } // // set trains switch lists printed // trainManager.setTrainsSwitchListStatus(Train.PRINTED); // } private void updateSwitchListButton() { log.debug("update switch list button"); List<Location> locations = locationManager.getList(); for (Location location : locations) { if (location != null && location.isSwitchListEnabled() && location.getStatus().equals(Location.MODIFIED)) { switchListsButton.setBackground(Color.RED); return; } } switchListsButton.setBackground(Color.GREEN); } protected void storeValues() { // Save comment TrainSchedule ts = trainScheduleManager.getScheduleById(getSelectedScheduleId()); if (ts != null) { ts.setComment(commentTextArea.getText()); } // updateControlPanel(); saveTableDetails(trainsScheduleTable); OperationsXml.save(); } public void dispose() { Setup.removePropertyChangeListener(this); trainManager.removePropertyChangeListener(this); trainScheduleManager.removePropertyChangeListener(this); removePropertyChangeTrainSchedules(); removePropertyChangeLocations(); trainsScheduleModel.dispose(); super.dispose(); } private void addPropertyChangeLocations() { for (Location location : locationManager.getList()) { location.addPropertyChangeListener(this); } } private void removePropertyChangeLocations() { for (Location location : locationManager.getList()) { location.removePropertyChangeListener(this); } } private void addPropertyChangeTrainSchedules() { List<TrainSchedule> trainSchedules = trainScheduleManager.getSchedulesByIdList(); for (TrainSchedule ts : trainSchedules) { ts.addPropertyChangeListener(this); } } private void removePropertyChangeTrainSchedules() { List<TrainSchedule> trainSchedules = trainScheduleManager.getSchedulesByIdList(); for (TrainSchedule ts : trainSchedules) { ts.removePropertyChangeListener(this); } } public void propertyChange(PropertyChangeEvent e) { if (Control.showProperty) log.debug( "Property change {} old: {} new: {}", e.getPropertyName(), e.getOldValue(), e.getNewValue()); if (e.getPropertyName().equals(TrainScheduleManager.LISTLENGTH_CHANGED_PROPERTY) || e.getPropertyName().equals(TrainSchedule.NAME_CHANGED_PROPERTY)) { updateControlPanel(); } if (e.getPropertyName().equals(TrainManager.PRINTPREVIEW_CHANGED_PROPERTY)) { setPrintButtonText(); setSwitchListButtonText(); } if (e.getPropertyName().equals(TrainManager.TRAINS_BUILT_CHANGED_PROPERTY)) { switchListsButton.setEnabled(true); } if (e.getPropertyName().equals(Setup.REAL_TIME_PROPERTY_CHANGE)) { setSwitchListButtonText(); } if (e.getPropertyName().equals(Location.STATUS_CHANGED_PROPERTY) || e.getPropertyName().equals(Location.SWITCHLIST_CHANGED_PROPERTY)) { updateSwitchListButton(); } } private static final Logger log = LoggerFactory.getLogger(TrainsScheduleTableFrame.class.getName()); }
/** * Builds a switch list for a location on the railroad * * @author Daniel Boudreau (C) Copyright 2008, 2011, 2012, 2013, 2015 * @version $Revision: 21846 $ */ public class TrainSwitchLists extends TrainCommon { TrainManager trainManager = TrainManager.instance(); private static final char FORM_FEED = '\f'; private static final boolean IS_PRINT_HEADER = true; String messageFormatText = ""; // the text being formated in case there's an exception /** * Builds a switch list for a location showing the work by train arrival time. If not running in * real time, new train work is appended to the end of the file. User has the ability to modify * the text of the messages which can cause an IllegalArgumentException. Some messages have more * arguments than the default message allowing the user to customize the message to their liking. * * <p>There also an option to list all of the car work by track name. This option is only * available in real time and is shown after the switch list by train. * * @param location The Location needing a switch list */ @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE", justification = "CarManager only provides Car Objects") // NOI18N public void buildSwitchList(Location location) { // Append switch list data if not operating in real time boolean newTrainsOnly = !Setup.isSwitchListRealTime(); boolean append = false; // add text to end of file when true boolean checkFormFeed = true; // used to determine if FF needed between trains if (newTrainsOnly) { if (!location.getStatus().equals(Location.MODIFIED) && !Setup.isSwitchListAllTrainsEnabled()) { return; // nothing to add } append = location.getSwitchListState() == Location.SW_APPEND; if (location.getSwitchListState() != Location.SW_APPEND) { location.setSwitchListState(Location.SW_APPEND); } location.setStatus(Location.UPDATED); } log.debug("Append: {} for location ({})", append, location.getName()); // create switch list file File file = TrainManagerXml.instance().createSwitchListFile(location.getName()); PrintWriter fileOut = null; try { fileOut = new PrintWriter( new BufferedWriter( new OutputStreamWriter(new FileOutputStream(file, append), "UTF-8")), true); // NOI18N } catch (IOException e) { log.error("Can not open switchlist file: {}", file.getName()); return; } try { // build header if (!append) { newLine(fileOut, Setup.getRailroadName()); newLine(fileOut); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringSwitchListFor(), new Object[] {splitString(location.getName())})); if (!location.getSwitchListComment().equals(Location.NONE)) { newLine(fileOut, location.getSwitchListComment()); } } String valid = MessageFormat.format( messageFormatText = TrainManifestText.getStringValid(), new Object[] {getDate(true)}); if (Setup.isPrintTimetableNameEnabled()) { TrainSchedule sch = TrainScheduleManager.instance() .getScheduleById(trainManager.getTrainScheduleActiveId()); if (sch != null) { valid = valid + " (" + sch.getName() + ")"; } } // get a list of trains sorted by arrival time List<Train> trains = trainManager.getTrainsArrivingThisLocationList(location); for (Train train : trains) { if (!train.isBuilt()) { continue; // train wasn't built so skip } if (newTrainsOnly && train.getSwitchListStatus().equals(Train.PRINTED)) { continue; // already printed this train } Route route = train.getRoute(); if (route == null) { continue; // no route for this train } // determine if train works this location boolean works = isThereWorkAtLocation(train, location); if (!works && !Setup.isSwitchListAllTrainsEnabled()) { log.debug("No work for train ({}) at location ({})", train.getName(), location.getName()); continue; } // we're now going to add to the switch list if (checkFormFeed) { if (append && !Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { fileOut.write(FORM_FEED); } if (Setup.isPrintValidEnabled()) { newLine(fileOut, valid); } } else if (!Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { fileOut.write(FORM_FEED); } checkFormFeed = false; // done with FF for this train // some cars booleans and the number of times this location get's serviced pickupCars = false; // when true there was a car pick up dropCars = false; // when true there was a car set out int stops = 1; boolean trainDone = false; // get engine and car lists List<Engine> engineList = engineManager.getByTrainBlockingList(train); List<Car> carList = carManager.getByTrainDestinationList(train); List<RouteLocation> routeList = route.getLocationsBySequenceList(); RouteLocation rlPrevious = null; // does the train stop once or more at this location? for (RouteLocation rl : routeList) { if (!splitString(rl.getName()).equals(splitString(location.getName()))) { rlPrevious = rl; continue; } String expectedArrivalTime = train.getExpectedArrivalTime(rl); if (expectedArrivalTime.equals(Train.ALREADY_SERVICED)) { trainDone = true; } // first time at this location? if (stops == 1) { newLine(fileOut); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {train.getName(), train.getDescription()})); if (train.isTrainEnRoute()) { if (!trainDone) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartedExpected(), new Object[] { splitString(train.getTrainDepartsName()), expectedArrivalTime, rl.getTrainDirectionString() })); } } else if (!train.isLocalSwitcher()) { if (rl == train.getRoute().getDepartsRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartsAt(), new Object[] { splitString(train.getTrainDepartsName()), rl.getTrainDirectionString(), train.getFormatedDepartureTime() })); } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartsAtExpectedArrival(), new Object[] { splitString(train.getTrainDepartsName()), train.getFormatedDepartureTime(), expectedArrivalTime, rl.getTrainDirectionString() })); } } } else { // multiple visits to this location // Print visit number only if previous location wasn't the same if (rlPrevious == null || !splitString(rl.getName()).equals(splitString(rlPrevious.getName()))) { if (Setup.getSwitchListPageFormat().equals(Setup.PAGE_PER_VISIT)) { fileOut.write(FORM_FEED); } newLine(fileOut); if (train.isTrainEnRoute()) { if (expectedArrivalTime.equals(Train.ALREADY_SERVICED)) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberDone(), new Object[] {stops, train.getName(), train.getDescription()})); } else if (rl != train.getRoute().getTerminatesRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberDeparted(), new Object[] { stops, train.getName(), expectedArrivalTime, rl.getTrainDirectionString(), train.getDescription() })); } else { // message: Visit number {0} for train ({1}) expect to arrive in {2}, terminates // {3} newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberTerminatesDeparted(), new Object[] { stops, train.getName(), expectedArrivalTime, splitString(rl.getName()), train.getDescription() })); } } else { // train hasn't departed if (rl != train.getRoute().getTerminatesRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumber(), new Object[] { stops, train.getName(), expectedArrivalTime, rl.getTrainDirectionString(), train.getDescription() })); } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberTerminates(), new Object[] { stops, train.getName(), expectedArrivalTime, splitString(rl.getName()), train.getDescription() })); } } } else { stops--; // don't bump stop count, same location // Does the train reverse direction? if (rl.getTrainDirection() != rlPrevious.getTrainDirection() && !TrainSwitchListText.getStringTrainDirectionChange().equals("")) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringTrainDirectionChange(), new Object[] { train.getName(), rl.getTrainDirectionString(), train.getDescription(), train.getTrainTerminatesName() })); } } } rlPrevious = rl; // save current location in case there's back to back location with the same name // add route comment if (Setup.isSwitchListRouteLocationCommentEnabled() && !rl.getComment().trim().equals("")) { newLine(fileOut, rl.getComment()); } // now print out the work for this location if (Setup.getManifestFormat().equals(Setup.STANDARD_FORMAT)) { pickupEngines(fileOut, engineList, rl, !IS_MANIFEST); // if switcher show loco drop at end of list if (train.isLocalSwitcher()) { blockCarsByTrack( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); dropEngines(fileOut, engineList, rl, !IS_MANIFEST); } else { dropEngines(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrack( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } } else if (Setup.getManifestFormat().equals(Setup.TWO_COLUMN_FORMAT)) { blockLocosTwoColumn(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrackTwoColumn( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } else { blockLocosTwoColumn(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrackNameTwoColumn( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } if (Setup.isPrintHeadersEnabled() || !Setup.getManifestFormat().equals(Setup.STANDARD_FORMAT)) { printHorizontalLine(fileOut, !IS_MANIFEST); } stops++; // done with work, now print summary for this location if we're done if (rl != train.getRoute().getTerminatesRouteLocation()) { RouteLocation nextRl = train.getRoute().getNextRouteLocation(rl); if (splitString(rl.getName()).equals(splitString(nextRl.getName()))) { continue; // the current location name is the "same" as the next } // print departure text if not a switcher if (!train.isLocalSwitcher()) { String trainDeparts = ""; if (Setup.isPrintLoadsAndEmptiesEnabled()) { int emptyCars = train.getNumberEmptyCarsInTrain(rl); // Message format: Train departs Boston Westbound with 4 loads, 8 empties, 450 feet, // 3000 tons trainDeparts = MessageFormat.format( TrainSwitchListText.getStringTrainDepartsLoads(), new Object[] { TrainCommon.splitString(rl.getName()), rl.getTrainDirectionString(), train.getNumberCarsInTrain(rl) - emptyCars, emptyCars, train.getTrainLength(rl), Setup.getLengthUnit().toLowerCase(), train.getTrainWeight(rl), train.getTrainTerminatesName(), train.getName() }); } else { // Message format: Train departs Boston Westbound with 12 cars, 450 feet, 3000 tons trainDeparts = MessageFormat.format( TrainSwitchListText.getStringTrainDepartsCars(), new Object[] { TrainCommon.splitString(rl.getName()), rl.getTrainDirectionString(), train.getNumberCarsInTrain(rl), train.getTrainLength(rl), Setup.getLengthUnit().toLowerCase(), train.getTrainWeight(rl), train.getTrainTerminatesName(), train.getName() }); } newLine(fileOut, trainDeparts); } } } if (trainDone && !pickupCars && !dropCars) { // Default message: Train ({0}) has serviced this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringTrainDone(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } else { if (stops > 1 && !pickupCars) { // Default message: No car pick ups for train ({0}) at this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringNoCarPickUps(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } if (stops > 1 && !dropCars) { // Default message: No car set outs for train ({0}) at this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringNoCarDrops(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } } } // now report car movement by tracks at location if (Setup.isTrackSummaryEnabled() && Setup.isSwitchListRealTime()) { clearUtilityCarTypes(); // list utility cars by quantity if (Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { newLine(fileOut); newLine(fileOut); } else { fileOut.write(FORM_FEED); } newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringSwitchListByTrack(), new Object[] {splitString(location.getName())})); // we only need the cars delivered to or at this location List<RollingStock> rsList = carManager.getByTrainList(); List<Car> carList = new ArrayList<Car>(); for (RollingStock rs : rsList) { if ((rs.getLocation() != null && splitString(rs.getLocation().getName()) .equals(splitString(location.getName()))) || (rs.getDestination() != null && splitString(rs.getDestination().getName()) .equals(splitString(location.getName())))) carList.add((Car) rs); } List<String> trackNames = new ArrayList< String>(); // locations and tracks can have "similar" names, only list track names // once for (Location loc : locationManager.getLocationsByNameList()) { if (!splitString(loc.getName()).equals(splitString(location.getName()))) continue; for (Track track : loc.getTrackByNameList(null)) { String trackName = splitString(track.getName()); if (trackNames.contains(trackName)) continue; trackNames.add(trackName); String trainName = ""; // for printing train message once newLine(fileOut); newLine(fileOut, trackName); // print out just the track name // now show the cars pickup and holds for this track for (Car car : carList) { if (!splitString(car.getTrackName()).equals(trackName)) { continue; } // is the car scheduled for pickup? if (car.getRouteLocation() != null) { if (splitString(car.getRouteLocation().getLocation().getName()) .equals(splitString(location.getName()))) { // cars are sorted by train name, print train message once if (!trainName.equals(car.getTrainName())) { trainName = car.getTrainName(); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {car.getTrainName(), car.getTrain().getDescription()})); printPickupCarHeader(fileOut, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); } if (car.isUtility()) { pickupUtilityCars(fileOut, carList, car, !IS_MANIFEST); } else { pickUpCar(fileOut, car, !IS_MANIFEST); } } // car holds } else if (car.isUtility()) { String s = pickupUtilityCars(carList, car, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); if (s != null) { newLine( fileOut, TrainSwitchListText.getStringHoldCar().split("\\{")[0] + s.trim()); // NOI18N } } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringHoldCar(), new Object[] { padAndTruncateString( car.getRoadName(), CarRoads.instance().getMaxNameLength()), padAndTruncateString( TrainCommon.splitString(car.getNumber()), Control.max_len_string_print_road_number), padAndTruncateString( car.getTypeName().split("-")[0], CarTypes.instance().getMaxNameLength()), padAndTruncateString( car.getLength() + LENGTHABV, Control.max_len_string_length_name), padAndTruncateString( car.getLoadName(), CarLoads.instance().getMaxNameLength()), padAndTruncateString(trackName, locationManager.getMaxTrackNameLength()), padAndTruncateString( car.getColor(), CarColors.instance().getMaxNameLength()) })); } } // now do set outs at this location for (Car car : carList) { if (!splitString(car.getDestinationTrackName()).equals(trackName)) { continue; } if (car.getRouteDestination() != null && splitString(car.getRouteDestination().getLocation().getName()) .equals(splitString(location.getName()))) { // cars are sorted by train name, print train message once if (!trainName.equals(car.getTrainName())) { trainName = car.getTrainName(); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {car.getTrainName(), car.getTrain().getDescription()})); printDropCarHeader(fileOut, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); } if (car.isUtility()) { setoutUtilityCars(fileOut, carList, car, !IS_MANIFEST); } else { dropCar(fileOut, car, !IS_MANIFEST); } } } } } } } catch (IllegalArgumentException e) { newLine( fileOut, MessageFormat.format( Bundle.getMessage("ErrorIllegalArgument"), new Object[] {Bundle.getMessage("TitleSwitchListText"), e.getLocalizedMessage()})); newLine(fileOut, messageFormatText); e.printStackTrace(); } // Are there any cars that need to be found? addCarsLocationUnknown(fileOut, !IS_MANIFEST); fileOut.flush(); fileOut.close(); } public void printSwitchList(Location location, boolean isPreview) { File buildFile = TrainManagerXml.instance().getSwitchListFile(location.getName()); if (!buildFile.exists()) { log.warn("Switch list file missing for location ({})", location.getName()); return; } if (isPreview && Setup.isManifestEditorEnabled()) { TrainPrintUtilities.openDesktopEditor(buildFile); } else { TrainPrintUtilities.printReport( buildFile, location.getName(), isPreview, Setup.getFontName(), false, FileUtil.getExternalFilename(Setup.getManifestLogoURL()), location.getDefaultPrinterName(), Setup.getSwitchListOrientation(), Setup.getManifestFontSize()); } if (!isPreview) { location.setStatus(Location.PRINTED); location.setSwitchListState(Location.SW_PRINTED); } } protected void newLine(PrintWriter file, String string) { newLine(file, string, !IS_MANIFEST); } private static final Logger log = LoggerFactory.getLogger(TrainSwitchLists.class.getName()); }