001package jmri.jmrit.withrottle; 002 003import java.awt.BorderLayout; 004import java.awt.Color; 005import java.awt.event.ActionEvent; 006import java.beans.PropertyChangeListener; 007import java.util.List; 008import javax.swing.*; 009import javax.swing.event.TableModelEvent; 010import javax.swing.event.TableModelListener; 011import javax.swing.table.AbstractTableModel; 012import javax.swing.table.TableColumn; 013import javax.swing.table.TableColumnModel; 014import jmri.*; 015import jmri.util.JmriJFrame; 016import org.slf4j.Logger; 017import org.slf4j.LoggerFactory; 018 019/** 020 * @author Brett Hoffman Copyright (C) 2010 021 */ 022public class ControllerFilterFrame extends JmriJFrame implements TableModelListener { 023 024 private static final String[] COLUMN_NAMES = {Bundle.getMessage("ColumnSystemName"), 025 Bundle.getMessage("ColumnUserName"), 026 Bundle.getMessage("Include")}; 027 028 public ControllerFilterFrame() { 029 super(Bundle.getMessage("TitleControlsFilter"), true, true); 030 } 031 032 @Override 033 public void initComponents() { 034 JTabbedPane tabbedPane = new JTabbedPane(); 035 if (InstanceManager.getNullableDefault(jmri.TurnoutManager.class) != null) { 036 037 tabbedPane.addTab(Bundle.getMessage("Turnouts"), null, addTurnoutPanel(), Bundle.getMessage("ToolTipTurnoutTab")); 038 } 039 040 if (InstanceManager.getNullableDefault(jmri.RouteManager.class) != null) { 041 042 tabbedPane.addTab(Bundle.getMessage("LabelRoute"), null, addRoutePanel(), Bundle.getMessage("ToolTipRouteTab")); 043 } 044 045 add(tabbedPane); 046 047 pack(); 048 049 addHelpMenu("package.jmri.jmrit.withrottle.UserInterface", true); 050 } 051 052 private JPanel addTurnoutPanel() { 053 JPanel tPanel = new JPanel(new BorderLayout()); 054 JLabel label = new JLabel(Bundle.getMessage("LabelTurnoutTab"), SwingConstants.CENTER); 055 tPanel.add(label, BorderLayout.NORTH); 056 tPanel.add(addCancelSavePanel(), BorderLayout.WEST); 057 058 final TurnoutFilterModel filterModel = new TurnoutFilterModel(); 059 JTable table = new JTable(filterModel); 060 buildTable(table); 061 062 JScrollPane scrollPane = new JScrollPane(table); 063 tPanel.add(scrollPane, BorderLayout.CENTER); 064 065 tPanel.add(getIncludeButtonsPanel(filterModel), BorderLayout.SOUTH); 066 067 return tPanel; 068 } 069 070 private JPanel addRoutePanel() { 071 JPanel tPanel = new JPanel(new BorderLayout()); 072 JLabel label = new JLabel(Bundle.getMessage("LabelRouteTab"), SwingConstants.CENTER); 073 tPanel.add(label, BorderLayout.NORTH); 074 tPanel.add(addCancelSavePanel(), BorderLayout.WEST); 075 076 final RouteFilterModel filterModel = new RouteFilterModel(); 077 JTable table = new JTable(filterModel); 078 buildTable(table); 079 080 JScrollPane scrollPane = new JScrollPane(table); 081 tPanel.add(scrollPane, BorderLayout.CENTER); 082 083 tPanel.add(getIncludeButtonsPanel(filterModel), BorderLayout.SOUTH); 084 085 return tPanel; 086 } 087 088 private void buildTable(JTable table) { 089 table.getModel().addTableModelListener(this); 090 091 table.setRowSelectionAllowed(false); 092 table.setPreferredScrollableViewportSize(new java.awt.Dimension(580, 240)); 093 094 //table.getTableHeader().setBackground(Color.lightGray); 095 table.setShowGrid(false); 096 table.setShowHorizontalLines(true); 097 table.setGridColor(Color.gray); 098 table.setRowHeight(30); 099 100 TableColumnModel columnModel = table.getColumnModel(); 101 102 TableColumn include = columnModel.getColumn(AbstractFilterModel.INCLUDECOL); 103 include.setResizable(false); 104 include.setMinWidth(60); 105 include.setMaxWidth(70); 106 107 TableColumn sName = columnModel.getColumn(AbstractFilterModel.SNAMECOL); 108 sName.setResizable(true); 109 sName.setMinWidth(80); 110 sName.setPreferredWidth(80); 111 sName.setMaxWidth(340); 112 113 TableColumn uName = columnModel.getColumn(AbstractFilterModel.UNAMECOL); 114 uName.setResizable(true); 115 uName.setMinWidth(180); 116 uName.setPreferredWidth(300); 117 uName.setMaxWidth(440); 118 } 119 120 private JPanel getIncludeButtonsPanel(final AbstractFilterModel fm) { 121 JPanel pane = new JPanel(); 122 pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); 123 pane.add(Box.createHorizontalGlue()); 124 125 JButton selectAllButton = new JButton(Bundle.getMessage("ButtonSelectAll")); 126 selectAllButton.addActionListener((ActionEvent event) -> { 127 fm.setIncludeColToValue(true); 128 }); 129 pane.add(selectAllButton); 130 131 JButton deselectAllButton = new JButton(Bundle.getMessage("ButtonDeselectAll")); 132 deselectAllButton.addActionListener((ActionEvent event) -> { 133 fm.setIncludeColToValue(false); 134 }); 135 pane.add(deselectAllButton); 136 137 JButton selectUserNamedButton = new JButton(Bundle.getMessage("ButtonSelectByUserName")); 138 selectUserNamedButton.addActionListener((ActionEvent event) -> { 139 fm.setIncludeToUserNamed(); 140 }); 141 pane.add(selectUserNamedButton); 142 143 return pane; 144 } 145 146 private JPanel addCancelSavePanel() { 147 JPanel p = new JPanel(); 148 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 149 p.add(Box.createVerticalGlue()); 150 151 JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel")); 152 cancelButton.setAlignmentX(CENTER_ALIGNMENT); 153 cancelButton.setToolTipText(Bundle.getMessage("ToolTipCancel")); 154 cancelButton.addActionListener((ActionEvent event) -> { 155 dispose(); 156 }); 157 p.add(cancelButton); 158 159 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 160 saveButton.setAlignmentX(CENTER_ALIGNMENT); 161 saveButton.setToolTipText(Bundle.getMessage("ToolTipSave")); 162 saveButton.addActionListener((ActionEvent event) -> { 163 storeValues(); 164 dispose(); 165 }); 166 p.add(saveButton); 167 168 return p; 169 } 170 171 @Override 172 protected void storeValues() { 173 new jmri.configurexml.StoreXmlUserAction().actionPerformed(null); 174 } 175 176 @Override 177 public void tableChanged(TableModelEvent e) { 178 if (log.isDebugEnabled()) { 179 log.debug("Set mod flag true for: {}", getTitle()); 180 } 181 this.setModifiedFlag(true); 182 } 183 184 public abstract class AbstractFilterModel extends AbstractTableModel implements PropertyChangeListener { 185 186 List<String> sysNameList = null; 187 boolean isDirty; 188 189 @Override 190 public Class<?> getColumnClass(int c) { 191 if (c == INCLUDECOL) { 192 return Boolean.class; 193 } else { 194 return String.class; 195 } 196 } 197 198 @Override 199 public void propertyChange(java.beans.PropertyChangeEvent e) { 200 if (e.getPropertyName().equals("length")) { 201 fireTableDataChanged(); 202 } 203 } 204 205 public void dispose() { 206 InstanceManager.turnoutManagerInstance().removePropertyChangeListener(this); 207 InstanceManager.getDefault(jmri.RouteManager.class).removePropertyChangeListener(this); 208 } 209 210 @Override 211 public String getColumnName(int c) { 212 return COLUMN_NAMES[c]; 213 } 214 215 @Override 216 public int getColumnCount() { 217 return 3; 218 } 219 220 @Override 221 public int getRowCount() { 222 return sysNameList.size(); 223 } 224 225 @Override 226 public boolean isCellEditable(int r, int c) { 227 return (c == INCLUDECOL); 228 } 229 230 abstract void setIncludeColToValue(boolean value); 231 232 abstract void setIncludeToUserNamed(); 233 234 public static final int SNAMECOL = 0; 235 public static final int UNAMECOL = 1; 236 public static final int INCLUDECOL = 2; 237 } 238 239 class TurnoutFilterModel extends AbstractFilterModel { 240 241 TurnoutManager mgr = InstanceManager.turnoutManagerInstance(); 242 243 TurnoutFilterModel() { 244 sysNameList = new java.util.ArrayList<>(mgr.getNamedBeanSet().size()); 245 mgr.getNamedBeanSet().forEach(bean -> { 246 sysNameList.add(bean.getSystemName()); 247 }); 248 mgr.addPropertyChangeListener(this); 249 } 250 251 @Override 252 public Object getValueAt(int r, int c) { 253 254 // some error checking 255 if (r >= sysNameList.size()) { 256 log.debug("row is greater than turnout list size"); 257 return null; 258 } 259 Turnout t = mgr.getBySystemName(sysNameList.get(r)); 260 switch (c) { 261 case INCLUDECOL: 262 if (t != null) { 263 Object o = t.getProperty("WifiControllable"); 264 if (o != null) { 265 return Boolean.valueOf(o.toString()); 266 } 267 } 268 return true; 269 case SNAMECOL: 270 return sysNameList.get(r); 271 case UNAMECOL: 272 return t != null ? t.getUserName() : null; 273 default: 274 return null; 275 } 276 } 277 278 @Override 279 public void setValueAt(Object type, int r, int c) { 280 Turnout t = mgr.getBySystemName(sysNameList.get(r)); 281 if (t != null) { 282 switch (c) { 283 case INCLUDECOL: 284 t.setProperty("WifiControllable", type); 285 if (!isDirty) { 286 this.fireTableChanged(new TableModelEvent(this)); 287 isDirty = true; 288 } 289 break; 290 default: 291 log.warn("Unhandled col: {}", c); 292 break; 293 } 294 } 295 } 296 297 @Override 298 public void setIncludeColToValue(boolean value) { 299 for (String sysName : sysNameList) { 300 Turnout t = mgr.getBySystemName(sysName); 301 if (t != null) { 302 t.setProperty("WifiControllable", value); 303 } 304 } 305 fireTableDataChanged(); 306 } 307 308 @Override 309 public void setIncludeToUserNamed() { 310 for (String sysName : sysNameList) { 311 Turnout t = mgr.getBySystemName(sysName); 312 if (t != null) { 313 String uname = t.getUserName(); 314 if ((uname != null) && (uname.length() > 0)) { 315 t.setProperty("WifiControllable", true); 316 } else { 317 t.setProperty("WifiControllable", false); 318 } 319 } 320 } 321 fireTableDataChanged(); 322 } 323 } 324 325 class RouteFilterModel extends AbstractFilterModel { 326 327 RouteManager mgr = InstanceManager.getDefault(jmri.RouteManager.class); 328 329 RouteFilterModel() { 330 sysNameList = new java.util.ArrayList<>(mgr.getNamedBeanSet().size()); 331 mgr.getNamedBeanSet().forEach(bean -> { 332 sysNameList.add(bean.getSystemName()); 333 }); 334 mgr.addPropertyChangeListener(this); 335 } 336 337 @Override 338 public Object getValueAt(int r, int c) { 339 340 // some error checking 341 if (r >= sysNameList.size()) { 342 log.debug("row is greater than turnout list size"); 343 return null; 344 } 345 Route rt = mgr.getBySystemName(sysNameList.get(r)); 346 switch (c) { 347 case INCLUDECOL: 348 if (rt == null) { 349 return null; 350 } 351 Object o = rt.getProperty("WifiControllable"); 352 if (o != null) { 353 return Boolean.valueOf(o.toString()); 354 } 355 return true; 356 case SNAMECOL: 357 return sysNameList.get(r); 358 case UNAMECOL: 359 if (rt == null) { 360 return null; 361 } 362 return rt.getUserName(); 363 default: 364 return null; 365 } 366 } 367 368 @Override 369 public void setValueAt(Object type, int r, int c) { 370 371 switch (c) { 372 case INCLUDECOL: 373 Route rt = mgr.getBySystemName(sysNameList.get(r)); 374 if (rt != null) { 375 rt.setProperty("WifiControllable", type); 376 if (!isDirty) { 377 this.fireTableChanged(new TableModelEvent(this)); 378 isDirty = true; 379 } 380 } 381 break; 382 default: 383 log.warn("Unhandled col: {}", c); 384 break; 385 } 386 } 387 388 @Override 389 public void setIncludeColToValue(boolean value) { 390 for (String sysName : sysNameList) { 391 Route rt = mgr.getBySystemName(sysName); 392 if (rt != null) { 393 rt.setProperty("WifiControllable", value); 394 } 395 } 396 fireTableDataChanged(); 397 } 398 399 @Override 400 public void setIncludeToUserNamed() { 401 for (String sysName : sysNameList) { 402 NamedBean bean = mgr.getBySystemName(sysName); 403 if (bean != null) { 404 String uname = bean.getUserName(); 405 if ((uname != null) && (uname.length() > 0)) { 406 bean.setProperty("WifiControllable", true); 407 } else { 408 bean.setProperty("WifiControllable", false); 409 } 410 } else { 411 log.error("Failed to get bean from getBySystemName {}", sysName); 412 } 413 } 414 fireTableDataChanged(); 415 } 416 } 417 418 private final static Logger log = LoggerFactory.getLogger(ControllerFilterFrame.class); 419 420}