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