001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.preferences.display;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.awt.Component;
007    import java.util.ArrayList;
008    import java.util.Arrays;
009    import java.util.List;
010    import java.util.Locale;
011    
012    import javax.swing.Box;
013    import javax.swing.DefaultComboBoxModel;
014    import javax.swing.DefaultListCellRenderer;
015    import javax.swing.JLabel;
016    import javax.swing.JList;
017    import javax.swing.JPanel;
018    import javax.swing.ListCellRenderer;
019    
020    import org.openstreetmap.josm.Main;
021    import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
022    import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
023    import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
024    import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
025    import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
026    import org.openstreetmap.josm.gui.widgets.JosmComboBox;
027    import org.openstreetmap.josm.tools.GBC;
028    import org.openstreetmap.josm.tools.I18n;
029    
030    public class LanguagePreference implements SubPreferenceSetting {
031        public static class Factory implements PreferenceSettingFactory {
032            public PreferenceSetting createPreferenceSetting() {
033                return new LanguagePreference();
034            }
035        }
036    
037        /** the combo box with the available locales */
038        private JosmComboBox langCombo;
039        /** the model for the combo box */
040        private LanguageComboBoxModel model;
041    
042        public void addGui(final PreferenceTabbedPane gui) {
043            model = new LanguageComboBoxModel();
044            // Selecting the language BEFORE the JComboBox listens to model changes speed up initialization by ~35ms (see #7386)
045            // See http://stackoverflow.com/questions/3194958/fast-replacement-for-jcombobox-basiccomboboxui 
046            model.selectLanguage(Main.pref.get("language"));
047            langCombo = new JosmComboBox(model);
048            langCombo.setRenderer(new LanguageCellRenderer(langCombo.getRenderer()));
049    
050            LafPreference lafPreference = gui.getSetting(LafPreference.class);
051            final JPanel panel = lafPreference.panel;
052            panel.add(new JLabel(tr("Language")), GBC.std().insets(20, 0, 0, 0));
053            panel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
054            panel.add(langCombo, GBC.eol().fill(GBC.HORIZONTAL));
055            panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
056        }
057    
058        public boolean ok() {
059            if(langCombo.getSelectedItem() == null)
060                return Main.pref.put("language", null);
061            else
062                return Main.pref.put("language",
063                        ((Locale)langCombo.getSelectedItem()).toString());
064        }
065    
066        private static class LanguageComboBoxModel extends DefaultComboBoxModel {
067            private final List<Locale> data = new ArrayList<Locale>();
068    
069            public LanguageComboBoxModel(){
070                data.add(0,null);
071                data.addAll(Arrays.asList(I18n.getAvailableTranslations()));
072            }
073    
074            public void selectLanguage(String language) {
075                setSelectedItem(null);
076                if (language != null) {
077                    for (Locale locale: data) {
078                        if (locale == null) {
079                            continue;
080                        }
081                        if (locale.toString().equals(language)) {
082                            setSelectedItem(locale);
083                            return;
084                        }
085                    }
086                }
087            }
088    
089            @Override
090            public Object getElementAt(int index) {
091                return data.get(index);
092            }
093    
094            @Override
095            public int getSize() {
096                return data.size();
097            }
098        }
099    
100        static private class LanguageCellRenderer extends DefaultListCellRenderer {
101            private ListCellRenderer dispatch;
102            public LanguageCellRenderer(ListCellRenderer dispatch) {
103                this.dispatch = dispatch;
104            }
105            @Override
106            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
107                    boolean cellHasFocus) {
108                Locale l = (Locale) value;
109                return dispatch.getListCellRendererComponent(list,
110                        l == null ? tr("Default (Auto determined)") : l.getDisplayName(l),
111                                index, isSelected, cellHasFocus);
112            }
113        }
114    
115        @Override
116        public boolean isExpert() {
117            return false;
118        }
119    
120        @Override
121        public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) {
122            return gui.getDisplayPreference();
123        }
124    }