001package jmri.jmrit.display.layoutEditor.blockRoutingTable;
002
003import java.beans.PropertyChangeListener;
004import jmri.jmrit.display.layoutEditor.LayoutBlock;
005import jmri.jmrit.display.layoutEditor.LayoutBlockManager;
006
007/**
008 * Table data model for display the through path of a layoutblock
009 * <p>
010 * Any desired ordering, etc, is handled outside this class.
011 *
012 * @author Kevin Dickerson Copyright (C) 2011
013 */
014public class LayoutBlockThroughPathsTableModel extends javax.swing.table.AbstractTableModel implements PropertyChangeListener {
015
016    public static final int SOURCECOL = 0;
017    static final int DESTINATIONCOL = 1;
018    static final int ACTIVECOL = 2;
019
020    static final int NUMCOL = 2 + 1;
021
022    boolean editable = false;
023
024    public LayoutBlockThroughPathsTableModel(boolean editable, LayoutBlock lBlock) {
025        this.editable = editable;
026        this.lBlock = lBlock;
027        lBlock.addPropertyChangeListener(this);
028    }
029
030    @Override
031    public int getRowCount() {
032        return lBlock.getNumberOfThroughPaths();
033    }
034
035    @Override
036    public int getColumnCount() {
037        return NUMCOL;
038    }
039
040    @Override
041    public String getColumnName(int col) {
042        switch (col) {
043            case SOURCECOL:
044                return Bundle.getMessage("Source");
045            case DESTINATIONCOL:
046                return Bundle.getMessage("Destination");
047            case ACTIVECOL:
048                return Bundle.getMessage("SensorStateActive");
049
050            default:
051                return "<UNKNOWN>";
052        }
053    }
054
055    @Override
056    public Class<?> getColumnClass(int col) {
057        return String.class;
058    }
059
060    /**
061     * Editable state must be set in ctor.
062     */
063    @Override
064    public boolean isCellEditable(int row, int col) {
065        return false;
066    }
067
068    @Override
069    public void propertyChange(java.beans.PropertyChangeEvent e) {
070        if (e.getPropertyName().equals("length")) {
071            fireTableDataChanged();
072        } else if (e.getPropertyName().equals("through-path-removed")) {
073            fireTableDataChanged();
074        } else if (e.getPropertyName().equals("through-path-added")) {
075            fireTableDataChanged();
076        } else if (matchPropertyName(e)) {
077            // a value changed.  Find it, to avoid complete redraw
078            int row;
079            row = (Integer) e.getNewValue();
080            // since we can add columns, the entire row is marked as updated
081            //int row = sysNameList.indexOf(name);
082            fireTableRowsUpdated(row, row);
083        }
084    }
085
086    protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
087        return (e.getPropertyName().contains("path"));
088    }
089
090    /**
091     * Provides the empty String if attribute doesn't exist.
092     */
093    @Override
094    public Object getValueAt(int row, int col) {
095        // get roster entry for row
096        if (lBlock == null) {
097            log.debug("layout Block is null!");
098            return "Error";
099        }
100        switch (col) {
101            case SOURCECOL:
102                return lBlock.getThroughPathSource(row).getDisplayName();
103            case ACTIVECOL:
104                Boolean mutual = lBlock.isThroughPathActive(row);
105                if (mutual) {
106                    return Bundle.getMessage("ButtonYes");
107                }
108                return Bundle.getMessage("ButtonNo");
109            case DESTINATIONCOL:
110                return lBlock.getThroughPathDestination(row).getDisplayName();
111            default:
112                return "<UNKNOWN>";
113        }
114    }
115
116    @Override
117    public void setValueAt(Object value, int row, int col) {
118    }
119
120    public int getPreferredWidth(int column) {
121        int retval = 20; // always take some width
122        retval = Math.max(retval, new javax.swing.JLabel(getColumnName(column)).getPreferredSize().width + 15);  // leave room for sorter arrow
123        for (int row = 0; row < getRowCount(); row++) {
124            if (getColumnClass(column).equals(String.class)) {
125                retval = Math.max(retval, new javax.swing.JLabel(getValueAt(row, column).toString()).getPreferredSize().width);
126            } else if (getColumnClass(column).equals(Integer.class)) {
127                retval = Math.max(retval, new javax.swing.JLabel(getValueAt(row, column).toString()).getPreferredSize().width);
128            }
129        }
130        return retval + 5;
131    }
132
133    // drop listeners
134    public void dispose() {
135    }
136
137    public jmri.Manager<LayoutBlock> getManager() {
138        return jmri.InstanceManager.getDefault(LayoutBlockManager.class);
139    }
140
141    private LayoutBlock lBlock = null;
142
143    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutBlockThroughPathsTableModel.class);
144}