001package jmri.jmrit.beantable.block;
002
003import javax.swing.AbstractListModel;
004import javax.swing.ComboBoxModel;
005import javax.swing.JComboBox;
006
007import jmri.Block;
008
009/**
010 * JComboBox to display / select block curvature.
011 * @see jmri.Block
012 * 
013 * @author Bob Jacobsen Copyright (C) 2003, 2008
014 * @author Egbert Broerse Copyright (C) 2017
015 * @author Steve Young Copyright (C) 2021
016 */
017public class BlockCurvatureJComboBox extends JComboBox<String> {
018    
019    private static final String NONE_TEXT = Bundle.getMessage("BlockNone"); // NOI18N
020    private static final String GRADUAL_TEXT = Bundle.getMessage("BlockGradual"); // NOI18N
021    private static final String TIGHT_TEXT = Bundle.getMessage("BlockTight"); // NOI18N
022    private static final String SEVERE_TEXT = Bundle.getMessage("BlockSevere"); // NOI18N
023    private static final String[] CURVE_OPTIONS = {NONE_TEXT, GRADUAL_TEXT, TIGHT_TEXT, SEVERE_TEXT};
024    
025    /**
026     * Create a new JComboBox to display / select block curvature.
027     * <p>
028     * Options are presented in localised String form and can be 
029     * set / retrieved in Block Constant format.
030     * <p>
031     * Block.NONE, Block.GRADUAL, Block.TIGHT, Block.SEVERE
032     * <p>
033     * Defaults to No curvature.
034     */
035    public BlockCurvatureJComboBox(){
036        super(new CurvatureComboBoxModel());
037        setSelectedItem(NONE_TEXT);
038    }
039    
040    /**
041     * Create a new JComboBox to display / select block curvature.
042     * <p>
043     * Block.NONE, Block.GRADUAL, Block.TIGHT, Block.SEVERE
044     * <p>
045     * Defaults to No curvature if invalid number in curvature field.
046     * @param curvature Block constant for Curvature.
047     */
048    public BlockCurvatureJComboBox(int curvature){
049        super(new CurvatureComboBoxModel());
050        setCurvature(curvature);
051    }
052    
053    /**
054     * Set UI properties for a JTable cell.
055     */
056    public void setJTableCellClientProperties(){
057        putClientProperty("JComponent.sizeVariant", "small"); // NOI18N
058        putClientProperty("JComboBox.buttonType", "square"); // NOI18N
059    }
060    
061    /**
062     * Set the Block Curvature by Block Constant format.
063     * If unrecognised constant, does not error or change selected value.
064     * @param blockCurve e.g. "Block.TIGHT" or "Block.NONE"
065     */
066    public final void setCurvature(int blockCurve){
067        setSelectedItem(getStringFromCurvature(blockCurve));
068    }
069    
070    /**
071     * Get the String of Block Curvature from Block Constant format.
072     * .e.g. Bundle.getMessage("BlockTight")
073     * @param blockCurve Block Constant, e.g. Block.GRADUAL
074     * @return localised String, or Bundle.getMessage("BlockNone") if unmatched.
075     */
076    public static String getStringFromCurvature(int blockCurve){
077        switch (blockCurve) {
078            case Block.GRADUAL:
079                return GRADUAL_TEXT;
080            case Block.TIGHT:
081                return TIGHT_TEXT;
082            case Block.SEVERE:
083                return SEVERE_TEXT;
084            default:
085                return NONE_TEXT;
086        }
087    }
088    
089    /**
090     * Get the Block Curvature in Block Constant format.
091     * e.g. "Block.TIGHT" or "Block.NONE"
092     * @return selected Block Curvature constant.
093     */
094    public int getCurvature(){
095        return getCurvatureFromString((String)getSelectedItem());
096    }
097    
098    /**
099     * Get the Block Curvature in Block Constant format.e.g.
100     * "Block.TIGHT" or "Block.NONE"
101     * 
102     * @param s localised String, e.g. Bundle.getMessage("BlockSevere")
103     * @return Block Curvature constant, Block.NONE if String unrecognised.
104     */
105    public static int getCurvatureFromString(String s){
106        if (GRADUAL_TEXT.equals(s)){
107            return Block.GRADUAL;
108        } else if (TIGHT_TEXT.equals(s)){
109            return Block.TIGHT;
110        } else if (SEVERE_TEXT.equals(s)){
111            return Block.SEVERE;
112        } else {
113            return Block.NONE;
114        }
115    }
116
117    /**
118     * Get the Curvature Constant from a JComboBox passed as an Object.
119     * For use in setValueAt() in Table Models.
120     * @param obj the object which should be a JComboBox.
121     * @return Block curvature Constant if JComboBox found and selected item 
122     *         text matches, else Block.NONE
123     */    
124    public static int getCurvatureFromObject(Object obj){
125        if (obj instanceof BlockCurvatureJComboBox){
126            BlockCurvatureJComboBox jcb = (BlockCurvatureJComboBox) obj;
127            return getCurvatureFromString((String) jcb.getSelectedItem());
128        }
129        return Block.NONE;
130    }
131    
132    private static class CurvatureComboBoxModel extends AbstractListModel<String> implements ComboBoxModel<String> {
133        
134        private String selection = null;
135
136        @Override
137        public String getElementAt(int index) {
138            return CURVE_OPTIONS[index];
139        }
140
141        @Override
142        public int getSize() {
143            return CURVE_OPTIONS.length;
144        }
145
146        @Override
147        public void setSelectedItem(Object anItem) {
148            selection = (String) anItem; // to select and register an
149        } // item from the pull-down list
150
151        // Methods implemented from the interface ComboBoxModel
152        @Override
153        public String getSelectedItem() {
154            return selection; // to add the selection to the combo box
155        }
156    }
157    
158}