001package jmri.jmrit.throttle;
002
003import java.awt.*;
004
005import javax.swing.*;
006import javax.swing.border.BevelBorder;
007import javax.swing.table.TableCellRenderer;
008
009import jmri.Consist;
010import jmri.DccLocoAddress;
011import jmri.InstanceManager;
012import jmri.Throttle;
013import jmri.jmrit.roster.RosterIconFactory;
014import jmri.util.FileUtil;
015
016/**
017 * A TableCellRender to graphicaly display an active throttles in a summary table
018 * (see ThrottlesListPanel)
019 * 
020 * @author Lionel Jeanson - 2011
021 * 
022 */
023
024public class ThrottlesTableCellRenderer implements TableCellRenderer {
025
026    private static final ImageIcon FWD_ICN = new ImageIcon(FileUtil.findURL("resources/icons/throttles/dirFwdOn.png"));
027    private static final ImageIcon BCK_ICN = new ImageIcon(FileUtil.findURL("resources/icons/throttles/dirBckOn.png"));
028    private static final ImageIcon ESTOP_ICN = new ImageIcon(FileUtil.findURL("resources/icons/throttles/estop24.png"));
029    private static final RosterIconFactory ICN_FACT = new RosterIconFactory(32);
030    final static int LINE_HEIGHT = 42;
031
032    @Override
033    public Component getTableCellRendererComponent(JTable jtable, Object value, boolean bln, boolean bln1, int i, int i1) {
034        JPanel retPanel = new JPanel();
035        retPanel.setLayout(new BorderLayout());
036
037        if (value == null) {
038            return retPanel;
039        }
040
041        ThrottleFrame tf = (ThrottleFrame) value;
042        // loco icon
043        if ((tf.getAddressPanel().getConsistAddress() != null) && (tf.getAddressPanel().getThrottle() != null)) {
044            // consists
045            JPanel consistPanel = new JPanel();
046            consistPanel.setLayout(new FlowLayout());
047            consistPanel.setOpaque(false);
048            Consist consist =  InstanceManager.getDefault(jmri.ConsistManager.class).getConsist(tf.getAddressPanel().getConsistAddress());
049            String consistName = "";
050            for (DccLocoAddress loco : consist.getConsistList()) {
051                String reName = consist.getRosterId(loco);
052                JLabel label;
053                if (reName != null) {
054                    consistName = " ["+reName+"]" + consistName ;
055                    label = new JLabel();
056                    ImageIcon icon;
057                    Boolean dir = consist.getLocoDirection(loco);
058                    if (dir) {
059                        icon = ICN_FACT.getIcon(reName);
060                    } else {
061                        icon = ICN_FACT.getReversedIcon(reName);
062                    }
063                    if (icon != null) {
064                        icon.setImageObserver(jtable);
065                        label.setIcon(icon);
066                    } else {
067                        label.setName(reName);
068                    }
069                } else {
070                     label = new JLabel("["+loco.toString()+"]");
071                     consistName = " ["+loco.toString()+"]" + consistName ;
072                }
073                consistPanel.add(label,0); //always add last at first, the consist is facing right
074            }
075            consistPanel.add(new JLabel(consistName));
076            retPanel.add(consistPanel, BorderLayout.CENTER);
077        } else { // regular locomotive
078            ImageIcon icon = null;
079            String text;
080            if (tf.getRosterEntry() != null) {
081                icon = ICN_FACT.getIcon(tf.getAddressPanel().getRosterEntry());
082                text = tf.getAddressPanel().getRosterEntry().getId();
083            } else if ((tf.getAddressPanel().getCurrentAddress() != null) && (tf.getAddressPanel().getThrottle() != null)) {
084                switch (tf.getAddressPanel().getCurrentAddress().getNumber()) {
085                    case 0:
086                        text = Bundle.getMessage("ThrottleDCControl") + " - " + tf.getAddressPanel().getCurrentAddress();
087                        break;
088                    case 3:
089                        text = Bundle.getMessage("ThrottleDCCControl") + " - " + tf.getAddressPanel().getCurrentAddress();
090                        break;
091                    default:
092                        text = Bundle.getMessage("ThrottleAddress") + " " + tf.getAddressPanel().getCurrentAddress();
093                        break;
094                }
095            } else {
096                text = Bundle.getMessage("ThrottleNotAssigned");
097            }
098            if (icon != null) {
099                icon.setImageObserver(jtable);
100            }
101            JLabel locoID = new JLabel();
102            locoID.setHorizontalAlignment(JLabel.CENTER);
103            locoID.setVerticalAlignment(JLabel.CENTER);
104            locoID.setIcon(icon);
105            locoID.setText(text);        
106            retPanel.add(locoID, BorderLayout.CENTER);
107        }
108        
109        if (tf.getAddressPanel().getThrottle() != null) {
110            final ThrottlesPreferences preferences = InstanceManager.getDefault(ThrottlesPreferences.class);
111            JPanel ctrlPanel = new JPanel();
112            ctrlPanel.setLayout(new BorderLayout());
113            Throttle thr = tf.getAddressPanel().getThrottle();
114            // direction
115            JLabel dir = new JLabel();
116            if (preferences.isUsingExThrottle() && preferences.isUsingFunctionIcon()) {
117                if (thr.getIsForward()) {
118                    dir.setIcon(FWD_ICN);
119                } else {
120                    dir.setIcon(BCK_ICN);
121                }
122            } else {
123                if (thr.getIsForward()) {
124                    dir.setText(Bundle.getMessage("ButtonForward"));
125                } else {
126                    dir.setText(Bundle.getMessage("ButtonReverse"));
127                }
128            }
129            dir.setVerticalAlignment(JLabel.CENTER);
130            ctrlPanel.add(dir, BorderLayout.WEST);
131            // speed
132            if (preferences.isUsingExThrottle() && preferences.isUsingFunctionIcon()) {
133                if (thr.getSpeedSetting() == -1) {
134                    JLabel estop = new JLabel();
135                    estop.setPreferredSize(new Dimension(64, LINE_HEIGHT - 8));
136                    estop.setHorizontalAlignment(JLabel.CENTER);
137                    estop.setIcon(ESTOP_ICN);
138                    ctrlPanel.add(estop, BorderLayout.CENTER);
139                } else {
140                    JProgressBar speedBar = new javax.swing.JProgressBar();
141                    speedBar.setPreferredSize(new Dimension(64, LINE_HEIGHT - 8));
142                    speedBar.setMinimum(0);
143                    speedBar.setMaximum(100);
144                    speedBar.setValue((int) (thr.getSpeedSetting() * 100f));
145                    ctrlPanel.add(speedBar, BorderLayout.CENTER);
146                }
147            } else {
148                JLabel speedLabel = new JLabel("");
149                if (thr.getSpeedSetting() == -1) {
150                    speedLabel.setText(" " + Bundle.getMessage("ButtonEStop") + " ");
151                } else {
152                    speedLabel.setText(" " + (int) (thr.getSpeedSetting() * 100f) + "% ");
153                }
154                ctrlPanel.add(speedLabel, BorderLayout.CENTER);
155            }
156            ctrlPanel.setOpaque(false);
157            retPanel.add(ctrlPanel, BorderLayout.EAST);
158        }
159        // visibility -> selected
160        if (tf.isVisible()) {
161            Color selBackground = javax.swing.UIManager.getDefaults().getColor("List.selectionBackground");
162            if (selBackground == null) {
163                selBackground = Color.ORANGE;
164            }
165            Color selForeground = javax.swing.UIManager.getDefaults().getColor("List.selectionForeground");
166            if (selForeground == null) {
167                selForeground = Color.BLACK;
168            }
169            retPanel.setBackground(selBackground);
170            setForegroundAllComp( retPanel, selForeground );
171            retPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
172        } else {
173            retPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
174        }
175        return retPanel;
176    }
177    
178    private void setForegroundAllComp(JComponent cmp, Color color) {
179        if (cmp != null) {
180            cmp.setForeground(color);
181            for (Component c : cmp.getComponents()) {
182                if (c instanceof JComponent) {
183                    setForegroundAllComp( (JComponent) c, color);
184                }
185            }
186        }
187    }
188}