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