001package jmri.jmrix.openlcb.swing.tie;
002
003import java.awt.Font;
004import java.io.IOException;
005import java.util.ResourceBundle;
006
007import javax.swing.table.AbstractTableModel;
008import jmri.util.davidflanagan.OriginalHardcopyWriter;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012
013/**
014 * Table Model for access to tie info
015 *
016 * @author Bob Jacobsen 2008
017  * @since 2.3.7
018 */
019public class TieTableModel extends AbstractTableModel {
020
021    static ResourceBundle rb = ResourceBundle.getBundle("jmri.jmrix.openlcb.swing.tie.TieBundle");
022
023    public static final int USERNAME_COLUMN = 0;
024    public static final int ID_COLUMN = 1;
025    final String[] columnName = new String[]{"User Name", "ID"};
026
027    @Override
028    public String getColumnName(int c) {
029        return columnName[c];
030    }
031
032    @Override
033    public Class<?> getColumnClass(int c) {
034        return String.class;
035    }
036
037    @Override
038    public boolean isCellEditable(int r, int c) {
039        return false;
040    }
041
042    @Override
043    public int getColumnCount() {
044        return columnName.length;
045    }
046
047    @Override
048    public int getRowCount() {
049        return dummy.length;
050    }
051
052    @Override
053    public Object getValueAt(int r, int c) {
054        return dummy[r][c];  // for testing
055    }
056
057    @Override
058    public void setValueAt(Object type, int r, int c) {
059        // nothing is stored here
060    }
061
062    final String[][] dummy = {{"Set Lower Staging Track 1", "11094"}, // row then column
063    {"Set Lower Staging Track 2", "11095"},
064    {"Set Lower Staging Track 3", "11096"},
065    {"Set Lower Staging Track 4", "11097"},
066    {"Set Lower Staging Track 5", "11098"}
067    };
068
069    /**
070     * Method to print or print preview the assignment table. Printed in
071     * proportionately sized columns across the page with headings and vertical
072     * lines between each column. Data is word wrapped within a column. Can only
073     * handle 4 columns of data as strings. Adapted from routines in
074     * BeanTableDataModel.java by Bob Jacobsen and Dennis Miller
075     * @param w hard copy writer connection
076     * @param colWidth array of column widths
077     */
078    public void printTable(OriginalHardcopyWriter w, int[] colWidth) {
079        // determine the column sizes - proportionately sized, with space between for lines
080        int[] columnSize = new int[4];
081        int charPerLine = w.getCharactersPerLine();
082        int tableLineWidth = 0;  // table line width in characters
083        int totalColWidth = 0;
084        for (int j = 0; j < 4; j++) {
085            totalColWidth += colWidth[j];
086        }
087        float ratio = ((float) charPerLine) / ((float) totalColWidth);
088        for (int j = 0; j < 4; j++) {
089            columnSize[j] = (int) Math.round(colWidth[j] * ratio - 1.);
090            tableLineWidth += (columnSize[j] + 1);
091        }
092
093        // Draw horizontal dividing line
094        w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
095                tableLineWidth);
096
097        // print the column header labels
098        String[] columnStrings = new String[4];
099        // Put each column header in the array
100        for (int i = 0; i < 4; i++) {
101            columnStrings[i] = this.getColumnName(i);
102        }
103        w.setFontStyle(Font.BOLD);
104        printColumns(w, columnStrings, columnSize);
105        w.setFontStyle(Font.PLAIN);
106        // draw horizontal line
107        w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
108                tableLineWidth);
109
110        // now print each row of data
111        String[] spaces = new String[4];
112        // create base strings the width of each of the columns
113        for (int k = 0; k < 4; k++) {
114            spaces[k] = "";
115            for (int i = 0; i < columnSize[k]; i++) {
116                spaces[k] = spaces[k] + " ";
117            }
118        }
119        for (int i = 0; i < this.getRowCount(); i++) {
120            for (int j = 0; j < 4; j++) {
121                //check for special, null contents
122                if (this.getValueAt(i, j) == null) {
123                    columnStrings[j] = spaces[j];
124                } else {
125                    columnStrings[j] = (String) this.getValueAt(i, j);
126                }
127            }
128            printColumns(w, columnStrings, columnSize);
129            // draw horizontal line
130            w.write(w.getCurrentLineNumber(), 0, w.getCurrentLineNumber(),
131                    tableLineWidth);
132        }
133        w.close();
134    }
135
136    protected void printColumns(OriginalHardcopyWriter w, String[] columnStrings, int[] columnSize) {
137        StringBuilder columnString = new StringBuilder();
138        StringBuilder lineString = new StringBuilder();
139        String[] spaces = new String[4];
140        // create base strings the width of each of the columns
141        for (int k = 0; k < 4; k++) {
142            spaces[k] = "";
143            for (int i = 0; i < columnSize[k]; i++) {
144                spaces[k] = spaces[k] + " ";
145            }
146        }
147        // loop through each column
148        boolean complete = false;
149        while (!complete) {
150            complete = true;
151            for (int i = 0; i < 4; i++) {
152                // if the column string is too wide cut it at word boundary (valid delimiters are space, - and _)
153                // use the initial part of the text,pad it with spaces and place the remainder back in the array
154                // for further processing on next line
155                // if column string isn't too wide, pad it to column width with spaces if needed
156                if (columnStrings[i].length() > columnSize[i]) {
157                    // this column string will not fit on one line
158                    boolean noWord = true;
159                    for (int k = columnSize[i]; k >= 1; k--) {
160                        if (columnStrings[i].startsWith(" ", k - 1)
161                                || columnStrings[i].startsWith("-", k - 1)
162                                || columnStrings[i].startsWith("_", k - 1)) {
163                            columnString = new StringBuilder(columnStrings[i].substring(0, k));
164                            columnString.append(spaces[i].substring(columnStrings[i].substring(0, k).length()));
165
166                            columnStrings[i] = columnStrings[i].substring(k);
167                            noWord = false;
168                            complete = false;
169                            break;
170                        }
171                    }
172                    if (noWord) {
173                        columnString = new StringBuilder(columnStrings[i].substring(0, columnSize[i]));
174                        columnStrings[i] = columnStrings[i].substring(columnSize[i]);
175                        complete = false;
176                    }
177                } else {
178                    // this column string will fit on one line
179                    columnString = new StringBuilder(columnStrings[i]);
180                    columnString.append(spaces[i].substring(columnStrings[i].length()));
181                    columnStrings[i] = "";
182                }
183                lineString.append(columnString);
184                lineString.append(" ");
185            }
186            try {
187                w.write(lineString.toString());
188                //write vertical dividing lines
189                int iLine = w.getCurrentLineNumber();
190                for (int i = 0, k = 0; i < w.getCharactersPerLine(); k++) {
191                    w.write(iLine, i, iLine + 1, i);
192                    if (k < 4) {
193                        i = i + columnSize[k] + 1;
194                    } else {
195                        i = w.getCharactersPerLine();
196                    }
197                }
198                w.write("\n");
199                lineString = new StringBuilder();
200            } catch (IOException e) {
201                log.warn("error during printing", e);
202            }
203        }
204    }
205
206    private final static Logger log = LoggerFactory.getLogger(TieTableModel.class);
207
208}