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