001package jmri.jmrix.can.cbus.swing;
002
003import java.awt.Color;
004import java.text.DateFormat;
005import java.util.Date;
006import java.util.Locale;
007import java.util.regex.Pattern;
008
009import javax.swing.BorderFactory;
010import javax.swing.JComponent;
011import javax.swing.JTable;
012import javax.swing.JTextField;
013import javax.swing.text.BadLocationException;
014
015import jmri.jmrix.can.cbus.CbusEventDataElements.EvState;
016import jmri.jmrix.can.cbus.node.CbusNodeConstants.BackupType;
017
018/**
019 * Common CBUS swing functions.
020 * @author Steve Young Copyright (C) 2020
021 */
022public class CbusCommonSwing {
023    
024    public static final Color VERY_LIGHT_RED = new Color(255,176,173);
025    public static final Color VERY_LIGHT_GREEN = new Color(165,255,164);
026    public static final Color WHITE_GREEN = new Color(0xf5,0xf5,0xf5);
027    public static final Color GOLD = new Color(255,204,51);
028    
029    /**
030     * Set cell background with alternating rows.
031     * @param isSelected true if selected.
032     * @param f cell component.
033     * @param table cell table.
034     * @param row cell row.
035     */
036    public static void setCellBackground( boolean isSelected, JComponent f, JTable table, int row){
037        f.setBackground(isSelected ? table.getSelectionBackground() : 
038            (( row % 2 == 0 ) ? table.getBackground() : WHITE_GREEN ) );
039
040        f.setForeground(isSelected ? table.getSelectionForeground(): table.getForeground());
041
042    }
043    
044    public static void setCellFocus(boolean hasFocus, JComponent f, JTable table) {
045        f.setBorder(hasFocus ? BorderFactory.createMatteBorder(1, 1, 1, 1, Color.blue) : 
046            BorderFactory.createEmptyBorder(1, 1, 1, 1) );
047    }
048    
049    public static void hideNumbersLessThan(int min, String string, JTextField f){
050        try {
051            if (Integer.parseInt(string)<min) {
052                f.setText("");
053            }
054        } catch (NumberFormatException ex) {}
055    }
056    
057    public static void setCellFromCbusEventEnum(Object object, JTextField f){
058        if ( object instanceof EvState ) {
059            EvState state = (EvState) object;
060            switch (state) {
061                case ON:
062                    setTextBackGround(f,Bundle.getMessage("CbusEventOn"),VERY_LIGHT_GREEN);
063                    break;
064                case OFF:
065                    setTextBackGround(f,Bundle.getMessage("CbusEventOff"),VERY_LIGHT_RED);
066                    break;
067                case REQUEST:
068                    setTextBackGround(f,Bundle.getMessage("CbusEventRequest"),GOLD);
069                    break;
070                case UNKNOWN:
071                    f.setText("");
072                    break;
073                default:
074                    break;
075            }
076        }
077    }
078    
079    public static void setCellFromBackupEnum(Object object, JTextField f){
080        if ( object instanceof BackupType ) {
081            BackupType type = (BackupType) object;
082            switch (type) {
083                case INCOMPLETE:
084                    setTextBackGround(f,Bundle.getMessage("BackupIncomplete"),VERY_LIGHT_RED);
085                    break;
086                case COMPLETE:
087                    setTextBackGround(f,Bundle.getMessage("BackupComplete"),VERY_LIGHT_GREEN);
088                    break;
089                case COMPLETEDWITHERROR:
090                    setTextBackGround(f,Bundle.getMessage("BackupCompleteError"),VERY_LIGHT_RED);
091                    break;
092                case NOTONNETWORK:
093                    setTextBackGround(f,Bundle.getMessage("BackupNotOnNetwork"),VERY_LIGHT_RED);
094                    break;
095                case OUTSTANDING:
096                    setTextBackGround(f,Bundle.getMessage("BackupOutstanding"),GOLD);
097                    break;
098                case SLIM:
099                    setTextBackGround(f,Bundle.getMessage("NodeInSlim"),GOLD);
100                    break;
101                default:
102                    break;
103            }
104        }
105    }
106    
107    private static void setTextBackGround(JTextField f, String text, Color bg) {
108        f.setBackground( bg );
109        f.setText(text);
110    }
111    
112    public static void setCellFromDate(Object object, JTextField f, DateFormat dformat){
113        if (object instanceof Date) {
114            f.setText(dformat.format((Date) object));
115        } 
116    }
117    
118    public static void setCellTextHighlighter(String textForSearch, String string, JTextField f){
119        if(Pattern.compile(Pattern.quote(textForSearch), Pattern.CASE_INSENSITIVE).matcher(string).find()){
120            string = string.toLowerCase(Locale.getDefault());
121            textForSearch = textForSearch.toLowerCase(Locale.getDefault());
122            int indexOf = string.indexOf(textForSearch);
123            try {
124                f.getHighlighter().addHighlight(
125                    indexOf,
126                    indexOf+textForSearch.length(),
127                    new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.CYAN)
128                );
129            } catch (BadLocationException e) {}
130        }
131    }
132    
133    /**
134     * Configure a table to have our standard rows and columns.
135     * <p>
136     * This is optional, in that other table formats can use this table model.
137     * But we put it here to help keep it consistent.
138     * @param table table to configure
139     */
140    public static void configureTable(JTable table) {
141        // allow reordering of the columns
142        table.getTableHeader().setReorderingAllowed(true);
143
144        table.createDefaultColumnsFromModel();
145        
146        // prevent the TableColumnModel from being recreated and loosing custom cell renderers
147        table.setAutoCreateColumnsFromModel(false); 
148        
149        // shut off autoResizeMode to get horizontal scroll to work (JavaSwing p 541)
150        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
151        
152        table.setRowSelectionAllowed(true);
153        table.setColumnSelectionAllowed(false);
154        table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
155        
156        table.setRowHeight(new JTextField("Y").getPreferredSize().height+6);
157        
158        // give table a name for JmriJTablePersistenceManager
159        table.setName(table.getModel().getClass().getName());
160        
161        // resize columns to initial size
162        for (int i = 0; i < table.getColumnCount(); i++) {
163            int width = Math.min(260,new JTextField(table.getColumnName(i)).getPreferredSize().width*2);
164            table.getColumnModel().getColumn(i).setPreferredWidth(width);
165        }
166        table.sizeColumnsToFit(-1);
167        
168    }
169    
170}