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