001package jmri.jmrix.lenz.swing.stackmon;
002
003import javax.swing.JTable;
004import javax.swing.table.TableCellEditor;
005import javax.swing.table.TableColumnModel;
006import jmri.jmrix.lenz.XNetMessage;
007import jmri.jmrix.lenz.XNetTrafficController;
008import jmri.util.table.ButtonEditor;
009import jmri.util.table.ButtonRenderer;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Table data model for display of Lenz Command Station Stack information.
015 *
016 * @author Paul Bender Copyright (c) 2008
017 */
018public class StackMonDataModel extends javax.swing.table.AbstractTableModel {
019
020    static private final int ADDRCOLUMN = 0;     // Locomotive address
021    static private final int TYPECOLUMN = 1;     // Type of Database Entry
022    static private final int DELCOLUMN = 3;      // Remove Button
023
024    static private final int NUMCOLUMN = 4;
025
026    // the stack frame containing this object
027    StackMonFrame _stackFrame;
028
029    // internal data structures used to store stack info
030    java.util.ArrayList<Integer> _addressList;       // Store the addresses
031    java.util.Hashtable<Integer, String> _typeList;  // Store the entry type
032
033    protected XNetTrafficController tc;
034
035    /**
036     * Constructor for a new instance.
037     * 
038     * @param row (unused)
039     * @param column (unused)
040     * @param memo Provides access to rest of XNet system connection objects
041     */
042    StackMonDataModel(int row, int column, jmri.jmrix.lenz.XNetSystemConnectionMemo memo) {
043        tc = memo.getXNetTrafficController();
044    }
045
046    void initTable(JTable stackTable, StackMonFrame stackFrame) {
047        // Install the button handlers for the Delete Buttons
048        TableColumnModel tcm = stackTable.getColumnModel();
049        ButtonRenderer buttonRenderer = new ButtonRenderer();
050        tcm.getColumn(DELCOLUMN).setCellRenderer(buttonRenderer);
051        TableCellEditor buttonEditor = new ButtonEditor(new javax.swing.JButton());
052        tcm.getColumn(DELCOLUMN).setCellEditor(buttonEditor);
053        _stackFrame = stackFrame;
054    }
055
056    @Override
057    public int getRowCount() {
058        try {
059            return (_addressList.size());
060        } catch (NullPointerException e) {
061            return (0);
062        }
063    }
064
065    @Override
066    public int getColumnCount() {
067        return NUMCOLUMN;
068    }
069
070    @Override
071    public String getColumnName(int col) {
072        switch (col) {
073            case ADDRCOLUMN:
074                return Bundle.getMessage("AddressCol");
075            case TYPECOLUMN:
076                return Bundle.getMessage("EntryTypeCol");
077            default:
078                return ""; // no column title
079        }
080    }
081
082    @Override
083    public Class<?> getColumnClass(int col) {
084        switch (col) {
085            case ADDRCOLUMN:
086                return (Integer.class);
087            case DELCOLUMN:
088                return (javax.swing.JButton.class);
089            default:
090                return (String.class);
091        }
092    }
093
094    @Override
095    public boolean isCellEditable(int row, int col) {
096        log.debug("isCellEditable called for row: row: {} column: {}", row, col);
097        return col == DELCOLUMN;
098    }
099
100    @Override
101    public Object getValueAt(int row, int col) {
102        log.debug("getValueAt called for row: {} column: {}", row, col);
103        // some error checking
104        if (row >= _addressList.size()) {
105            log.debug("row is greater thant address list size");
106            return ("Error");
107        }
108        switch (col) {
109            case ADDRCOLUMN:
110                return (_addressList.get(row));
111            case TYPECOLUMN:
112                return (_typeList.get(_addressList.get(row)));
113            case DELCOLUMN:
114                return Bundle.getMessage("ButtonDelete");
115            default:
116                return ("");
117        }
118    }
119
120    @Override
121    public void setValueAt(Object value, int row, int col) {
122        log.debug("setValueAt called for row: {} column: {}", row, col);
123        if (col == DELCOLUMN) {
124            log.debug("Delete Called for row {}", row);
125            fireTableRowsDeleted(row, row);
126            // delete address from table
127            XNetMessage msg = XNetMessage.getDeleteAddressOnStackMsg(_addressList.get(row));
128            tc.sendXNetMessage(msg, _stackFrame);
129            _typeList.remove(_addressList.get(row));
130            _addressList.remove(row);
131            fireTableDataChanged();
132        } else {
133            log.error("Unknown Operation");
134        }
135    }
136
137    /**
138     * Update the internal data structures for a specified address.
139     * @param address which address to update.
140     * @param type address type.
141     */
142    public void updateData(Integer address, String type) {
143        if (_addressList == null) {
144            // initilize the address list
145            _addressList = new java.util.ArrayList<>();
146            _typeList = new java.util.Hashtable<>();
147        }
148        if (!_addressList.contains(address)) {
149            _addressList.add(address);
150            _typeList.put(address, type);
151        } else {
152            _typeList.put(address, type);
153        }
154        fireTableDataChanged();
155    }
156
157    /**
158     * Update the internal data structures for a specified address.
159     */
160    public void clearData() {
161        _addressList = new java.util.ArrayList<>();
162        _typeList = new java.util.Hashtable<>();
163        fireTableDataChanged();
164    }
165
166    private static final Logger log = LoggerFactory.getLogger(StackMonDataModel.class);
167
168}