/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.encoding; import com.mucommander.text.Translator; import com.mucommander.ui.dialog.DialogOwner; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.WeakHashMap; /** * This menu lets the user choose a character encoding among a list of {@link EncodingPreferences#getPreferredEncodings() * preferred encodings}. * The menu contains a checkbox menu item for each of the preferred encodings, and a special item that invokes a dialog * that allows the list of preferred encodings to be customized. * * @see EncodingPreferences * @author Maxence Bernard */ public class EncodingMenu extends JMenu { /** Contains all registered encoding listeners, stored as weak references */ protected final WeakHashMap<EncodingListener, ?> listeners = new WeakHashMap<EncodingListener, Object>(); /** the dialog/frame that owns this component */ protected DialogOwner dialogOwner; /** The encoding that is currently selected, may be null */ protected String selectedEncoding; /** * Creates a new <code>EncodingMenu</code> with no encoding selected. * * @param dialogOwner the frame that owns this menu */ public EncodingMenu(DialogOwner dialogOwner) { this(dialogOwner, null); } /** * Creates a new <code>EncodingMenu</code> with the specified encoding initially selected (may be <code>null</code>). * If the encoding is not one of the preferred encodings, it is added as the first encoding in the menu. * * @param dialogOwner the frame that owns this menu * @param selectedEncoding the encoding initially selected, <code>null</code> for none */ public EncodingMenu(final DialogOwner dialogOwner, String selectedEncoding) { super(Translator.get("encoding")); this.dialogOwner = dialogOwner; this.selectedEncoding = selectedEncoding; populateMenu(); } /** * Adds a checkbox menu item for each of the preferred encodings, and a special item that invokes a dialog * that allows the list of preferred encodings to be customized. */ protected void populateMenu() { java.util.List<String> encodings = EncodingPreferences.getPreferredEncodings(); // Add the current encoding if it is not in the list of preferred encodings if(selectedEncoding!=null && !encodings.contains(selectedEncoding)) encodings.add(0, selectedEncoding); // Add preferred encodings to the menu int nbEncodings = encodings.size(); JCheckBoxMenuItem item; ButtonGroup group = new ButtonGroup(); for(String enc: encodings) { item = new JCheckBoxMenuItem(enc); // Select the current encoding, if there is one if(selectedEncoding!=null && selectedEncoding.equals(enc)) item.setSelected(true); // Listen to checkbox actions item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String oldEncoding = selectedEncoding; selectedEncoding = ((JCheckBoxMenuItem)e.getSource()).getText(); if(!oldEncoding.equals(selectedEncoding)) { // Notify listeners of the new encoding fireEncodingListener(oldEncoding, EncodingMenu.this.selectedEncoding); } } }); group.add(item); add(item); } add(new JSeparator()); // 'Customize' menu item JMenuItem customizeItem = new JMenuItem(Translator.get("customize")+"..."); customizeItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Window owner = dialogOwner.getOwner(); if(owner instanceof Frame) new PreferredEncodingsDialog((Frame)owner).showDialog(); else new PreferredEncodingsDialog((Dialog)owner).showDialog(); removeAll(); populateMenu(); } }); add(customizeItem); } /** * Returns the encoding that is currently selected, <code>null</code> if none is selected. * * @return the encoding that is currently selected, <code>null</code> if none is selected. */ public String getSelectedEncoding() { return selectedEncoding; } ////////////////////// // Listener methods // ////////////////////// public void addEncodingListener(EncodingListener listener) { synchronized(listeners) { listeners.put(listener, null); } } public void removeEncodingListener(EncodingListener listener) { synchronized(listeners) { listeners.remove(listener); } } protected void fireEncodingListener(String oldEncoding, String newEncoding) { synchronized(listeners) { for (EncodingListener listener : listeners.keySet()) listener.encodingChanged(this, oldEncoding, newEncoding); } } }