001package jmri.jmrit.beantable.turnout; 002 003import java.awt.Component; 004 005import java.util.HashMap; 006 007import javax.swing.JTable; 008import javax.swing.table.*; 009 010import jmri.InstanceManager; 011import jmri.NamedBean; 012import jmri.Sensor; 013import jmri.SensorManager; 014import jmri.Turnout; 015import jmri.swing.NamedBeanComboBox; 016 017/** 018 * JTable to display a TurnoutTableDataModel. 019 * Code originally within TurnoutTableAction. 020 * 021 * @author Bob Jacobsen Copyright (C) 2003, 2004, 2007 022 * @author Egbert Broerse Copyright (C) 2017 023 * @author Steve Young Copyright (C) 2021, 2024 024 */ 025public class TurnoutTableJTable extends jmri.jmrit.beantable.BeanTableJTable<Turnout> { 026 027 final HashMap<Turnout, TableCellRenderer> rendererMapSensor1 = new HashMap<>(); 028 final HashMap<Turnout, TableCellEditor> editorMapSensor1 = new HashMap<>(); 029 030 final HashMap<Turnout, TableCellRenderer> rendererMapSensor2 = new HashMap<>(); 031 final HashMap<Turnout, TableCellEditor> editorMapSensor2 = new HashMap<>(); 032 033 public TurnoutTableJTable(TurnoutTableDataModel mdl){ 034 super(mdl); 035 } 036 037 @Override 038 public TableCellRenderer getCellRenderer(int row, int column) { 039 // Convert the displayed index to the model index, rather than the displayed index 040 int modelColumn = convertColumnIndexToModel(column); 041 if (modelColumn == TurnoutTableDataModel.SENSOR1COL || modelColumn == TurnoutTableDataModel.SENSOR2COL) { 042 return getRenderer(convertRowIndexToModel(row), modelColumn); 043 } else { 044 return super.getCellRenderer(row, column); 045 } 046 } 047 048 @Override 049 public TableCellEditor getCellEditor(final int row, final int column) { 050 //Convert the displayed index to the model index, rather than the displayed index 051 int modelColumn = this.convertColumnIndexToModel(column); 052 if (modelColumn == TurnoutTableDataModel.SENSOR1COL || modelColumn == TurnoutTableDataModel.SENSOR2COL) { 053 return getEditor(convertRowIndexToModel(row), modelColumn); 054 } else { 055 return super.getCellEditor(row, column); 056 } 057 } 058 059 private TableCellRenderer getRenderer(int modelRow, int modelColumn) { 060 TableCellRenderer retval; 061 Turnout t = (Turnout) getModel().getValueAt(modelRow, TurnoutTableDataModel.SYSNAMECOL); 062 java.util.Objects.requireNonNull(t, "SYSNAMECOL column content must be nonnull"); 063 switch (modelColumn) { 064 case TurnoutTableDataModel.SENSOR1COL: 065 retval = rendererMapSensor1.get(t); 066 break; 067 case TurnoutTableDataModel.SENSOR2COL: 068 retval = rendererMapSensor2.get(t); 069 break; 070 default: 071 return null; 072 } 073 074 if (retval == null) { 075 if (modelColumn == TurnoutTableDataModel.SENSOR1COL) { 076 loadRenderEditMaps(rendererMapSensor1, editorMapSensor1, t, t.getFirstSensor()); 077 } else { 078 loadRenderEditMaps(rendererMapSensor2, editorMapSensor2, t, t.getSecondSensor()); 079 } 080 retval = rendererMapSensor1.get(t); 081 } 082 log.debug("fetched for Turnout \"{}\" renderer {}", t, retval); 083 return retval; 084 } 085 086 private TableCellEditor getEditor(int modelRow, int modelColumn) { 087 TableCellEditor retval; 088 Turnout t = (Turnout) getModel().getValueAt(modelRow, TurnoutTableDataModel.SYSNAMECOL); 089 java.util.Objects.requireNonNull(t, "SYSNAMECOL column content must be nonnull"); 090 switch (modelColumn) { 091 case TurnoutTableDataModel.SENSOR1COL: 092 retval = editorMapSensor1.get(t); 093 break; 094 case TurnoutTableDataModel.SENSOR2COL: 095 retval = editorMapSensor2.get(t); 096 break; 097 default: 098 return null; 099 } 100 if (retval == null) { 101 if (modelColumn == TurnoutTableDataModel.SENSOR1COL) { 102 loadRenderEditMaps(rendererMapSensor1, editorMapSensor1, t, t.getFirstSensor()); 103 retval = editorMapSensor1.get(t); 104 } else { //Must be two 105 loadRenderEditMaps(rendererMapSensor2, editorMapSensor2, t, t.getSecondSensor()); 106 retval = editorMapSensor2.get(t); 107 } 108 } 109 log.debug("fetched for Turnout \"{}\" editor {}", t, retval); 110 return retval; 111 } 112 113 private void loadRenderEditMaps(HashMap<Turnout, TableCellRenderer> r, HashMap<Turnout, TableCellEditor> e, 114 Turnout t, Sensor s) { 115 NamedBeanComboBox<Sensor> c = new NamedBeanComboBox<>(InstanceManager.getDefault( 116 SensorManager.class), s, NamedBean.DisplayOptions.DISPLAYNAME); 117 118 TurnoutTableSensorBoxRenderer renderer = new TurnoutTableSensorBoxRenderer(); 119 r.put(t, renderer); 120 121 TableCellEditor editor = new jmri.util.table.JComboBoxEditor(c, null); 122 e.put(t, editor); 123 log.debug("initialize for Turnout \"{}\" Sensor \"{}\"", t, s); 124 } 125 126 private static class TurnoutTableSensorBoxRenderer extends jmri.util.table.NamedBeanBoxRenderer<Sensor> { 127 128 TurnoutTableSensorBoxRenderer() { 129 super(InstanceManager.getDefault(SensorManager.class)); 130 setAllowNull(true); 131 } 132 133 @Override 134 public Component getTableCellRendererComponent(JTable table, Object value, 135 boolean isSelected, boolean hasFocus, int row, int column) { 136 137 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 138 139 int tableCol = table.convertColumnIndexToModel(column); 140 int tableRow = table.convertRowIndexToModel(row); 141 142 Turnout t = (Turnout)table.getModel().getValueAt(tableRow, TurnoutTableDataModel.SYSNAMECOL); 143 if ( t == null ) { 144 return this; 145 } 146 if (value instanceof Sensor) { 147 if (( tableCol == TurnoutTableDataModel.SENSOR1COL ) && 148 (t.getFeedbackMode() != Turnout.ONESENSOR && t.getFeedbackMode() != Turnout.TWOSENSOR )) { 149 setErrorBorder(); 150 } else if ( tableCol == TurnoutTableDataModel.SENSOR2COL && t.getFeedbackMode() != Turnout.TWOSENSOR ) { 151 setErrorBorder(); 152 } else { 153 setNormalBorder(); 154 } 155 } else { 156 if (( tableCol == TurnoutTableDataModel.SENSOR1COL ) && 157 (t.getFeedbackMode() == Turnout.ONESENSOR || t.getFeedbackMode() == Turnout.TWOSENSOR )) { 158 setErrorBorder(); 159 } else if ( tableCol == TurnoutTableDataModel.SENSOR2COL && t.getFeedbackMode() == Turnout.TWOSENSOR ) { 160 setErrorBorder(); 161 } else { 162 setNormalBorder(); 163 } 164 } 165 return this; 166 } 167 } 168 169 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TurnoutTableJTable.class); 170 171}