001package jmri.jmrit.operations; 002 003import java.awt.*; 004import java.util.List; 005 006import javax.swing.*; 007import javax.swing.table.DefaultTableCellRenderer; 008 009import jmri.jmrit.operations.rollingstock.RollingStock; 010import jmri.jmrit.operations.trains.trainbuilder.TrainCommon; 011import jmri.util.swing.XTableColumnModel; 012 013/** 014 * Common table model methods for operations. 015 * 016 * @author Daniel Boudreau Copyright (C) 2023, 2025, 2026 017 */ 018public abstract class OperationsTableModel extends javax.swing.table.AbstractTableModel { 019 020 protected JTable _table; 021 022 public void initTable(JTable table) { 023 _table = table; 024 table.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer()); 025 table.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor()); 026 table.setDefaultRenderer(Object.class, new MyTableCellRenderer()); 027 table.setDefaultRenderer(Integer.class, new MyTableCellRenderer()); 028 } 029 030 protected Color getForegroundColor(int row) { 031 return _table.getForeground(); 032 } 033 034 protected Font getFont(int row) { 035 return _table.getFont(); 036 } 037 038 /** 039 * Search list for rolling stock by road number 040 * 041 * @param roadNumber The string road number to search for. 042 * @param rsList The list to search 043 * @return -1 if not found, table row number if found 044 */ 045 public int findRollingStockByRoadNumber(String roadNumber, List<?> rsList) { 046 if (rsList != null) { 047 if (!roadNumber.equals(_roadNumber)) { 048 return getIndex(0, roadNumber, rsList); 049 } 050 int index = getIndex(_index, roadNumber, rsList); 051 if (index > 0) { 052 return index; 053 } 054 return getIndex(0, roadNumber, rsList); 055 } 056 return -1; 057 } 058 059 protected String _roadNumber = ""; 060 protected int _index = 0; 061 062 protected int getIndex(int start, String roadNumber, List<?> rsList) { 063 for (int index = start; index < rsList.size(); index++) { 064 RollingStock rs = (RollingStock) rsList.get(index); 065 if (rs != null) { 066 _roadNumber = roadNumber; 067 _index = index + 1; 068 String[] number = rs.getNumber().split(TrainCommon.HYPHEN); 069 // check for wild card '*' 070 if (roadNumber.startsWith("*") && roadNumber.endsWith("*") && roadNumber.length() > 1) { 071 String rN = roadNumber.substring(1, roadNumber.length() - 1); 072 if (rs.getNumber().contains(rN)) { 073 return index; 074 } 075 } else if (roadNumber.startsWith("*")) { 076 String rN = roadNumber.substring(1); 077 if (rs.getNumber().endsWith(rN) || number[0].endsWith(rN)) { 078 return index; 079 } 080 } else if (roadNumber.endsWith("*")) { 081 String rN = roadNumber.substring(0, roadNumber.length() - 1); 082 if (rs.getNumber().startsWith(rN)) { 083 return index; 084 } 085 } else if (roadNumber.contains("*")) { 086 String rn = roadNumber.replace("*", ":"); 087 String[] rN = rn.split(":"); 088 if (rs.getNumber().startsWith(rN[0]) && number[0].endsWith(rN[rN.length - 1])) { 089 return index; 090 } 091 } else if (rs.getNumber().equals(roadNumber) || number[0].equals(roadNumber)) { 092 return index; 093 } 094 } 095 } 096 _roadNumber = ""; 097 return -1; 098 } 099 100 public boolean showAll = true; // when true show all rolling stock 101 public String locationName = null; // only show rolling stock at this location 102 public String trackName = null; // only show rolling stock using this track 103 104 protected void filterList(List<?> list) { 105 if (showAll) { 106 return; 107 } 108 for (int i = 0; i < list.size(); i++) { 109 RollingStock rs = (RollingStock) list.get(i); 110 if (rs.getLocation() == null) { 111 list.remove(i--); 112 continue; 113 } 114 // filter out cars that don't have a location name that matches 115 if (locationName != null) { 116 if (!rs.getLocationName().equals(locationName)) { 117 list.remove(i--); 118 continue; 119 } 120 if (trackName != null) { 121 if (!rs.getTrackName().equals(trackName)) { 122 list.remove(i--); 123 } 124 } 125 } 126 } 127 } 128 129 protected void setToolTip(String text, int col) { 130 XTableColumnModel tcm = (XTableColumnModel) _table.getColumnModel(); 131 JComponent jC = (JComponent) tcm.getColumnByModelIndex(col).getCellRenderer(); 132 if (jC != null) { 133 jC.setToolTipText(text); 134 } 135 } 136 137 public class MyTableCellRenderer extends DefaultTableCellRenderer { 138 @Override 139 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 140 int row, int column) { 141 Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 142 int modelRow = table.convertRowIndexToModel(row); 143 component.setFont(OperationsTableModel.this.getFont(modelRow)); 144 if (!isSelected) { 145 component.setForeground(getForegroundColor(modelRow)); 146 } 147 return component; 148 } 149 } 150}