⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 languageoptionpanel.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
字号:
/*
 * 05/25/2004
 *
 * LanguageOptionPanel.java - Option panel letting the user choose the
 *                            language they are most comfortable with.
 * Copyright (C) 2004 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * This program 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 2
 * of the License, or any later version.
 *
 * This program 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.fife.rtext;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.ResourceBundle;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

import org.fife.RListSelectionModel;
import org.fife.io.UnicodeReader;
import org.fife.ui.OptionsDialogPanel;
import org.fife.ui.RButton;
import org.fife.ui.RScrollPane;
import org.fife.ui.UIUtilities;
import org.fife.ui.app.GUIApplication;


/**
 * Option panel letting the user choose the language he or she is most
 * comfortable with.
 *
 * @author Robert Futrell
 * @version 0.5
 */
class LanguageOptionPanel extends OptionsDialogPanel
								implements ListSelectionListener {

	private DefaultListModel listModel;
	private JList languageList;	// Contains all available languages.
	private HashMap languageMap;
	private GUIApplication app;

	private static final String LANGUAGE_PROPERTY	= "language";

	private static final String ROOT_ELEMENT		= "RText-languages";
	private static final String LANGUAGE			= "language";
	private static final String NAME				= "name";
	private static final String ID				= "id";

	private static final int EMPTY_ICON_WIDTH		= 37;
	private static final int EMPTY_ICON_HEIGHT		= 20;

	private static final String FILE_NAME			= "localizations.xml";


/*****************************************************************************/


	/**
	 * Constructor.
	 *
	 * @param app The owner of the options dialog in which this panel
	 *              appears.
	 * @param msg The resource bundle to use.
	 */
	public LanguageOptionPanel(final GUIApplication app,
							final ResourceBundle msg) {

		super(msg.getString("OptLaName"));
		this.app = app;

		setBorder(UIUtilities.getEmpty5Border());
		setLayout(new BorderLayout());

		JPanel languagePanel = new JPanel();
		languagePanel.setBorder(BorderFactory.createCompoundBorder(
							new OptionPanelBorder(
									msg.getString("OptLaLabel")),
									UIUtilities.getEmpty5Border()));
		languagePanel.setLayout(new BorderLayout());
		JPanel temp = new JPanel(new BorderLayout());
		temp.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
		JLabel label = new JLabel(msg.getString("OptLaDesc"));
		temp.add(label, BorderLayout.WEST);
		languagePanel.add(temp, BorderLayout.NORTH);

		listModel = new DefaultListModel();
		languageList = new JList(listModel);
		languageList.setCellRenderer(new CellRenderer());
		languageMap = new HashMap(1);
		try {
			File file = new File(app.getInstallLocation(), FILE_NAME);
			getLocalizations(file);
		} catch (Exception e) {
			app.displayException(e);
		}

		languageList.setSelectionModel(new RListSelectionModel());
		languageList.addListSelectionListener(this);
		RScrollPane scrollPane = new RScrollPane(languageList);
		languagePanel.add(scrollPane);

		add(languagePanel);

	}


/*****************************************************************************/


	/**
	 * Checks whether or not all input the user specified on this panel is
	 * valid.  This should be overridden to check, for example, whether
	 * text fields have valid values, etc.  This method will be called
	 * whenever the user clicks "OK" or "Apply" on the options dialog to
	 * ensure all input is valid.  If it isn't, the component with invalid
	 * data will be given focus and the user will be prompted to fix it.<br>
	 * 
	 *
	 * @return <code>null</code> if the panel has all valid inputs, or an
	 *         <code>OptionsPanelCheckResult</code> if an input was invalid.
	 *         This component is the one that had the error and will be
	 *         given focus, and the string is an error message that will be
	 *         displayed.
	 */
	public OptionsPanelCheckResult ensureValidInputs() {
		// They can't input invalid stuff on this options panel.
		return null;
	}


/*****************************************************************************/


	/**
	 * Returns the icon to use for the specified localization.
	 *
	 * @param id The localization (such as <code>en</code> or
	 *        <code>zh_CN</code>).
	 * @return The icon.
	 */
	private Icon getIconFor(String id) {
		Icon icon = null;
		URL url = getClass().getClassLoader().getResource(
						"org/fife/rtext/graphics/flags/" + id + ".png");
		if (url!=null) {
			try {
				icon = new ImageIcon(ImageIO.read(url));
			} catch (IOException ioe) {
				app.displayException(ioe);
				icon = EmptyIcon.getInstance();
			}
		}
		else {
			icon = EmptyIcon.getInstance();
		}
		return icon;
	}


/*****************************************************************************/


	/**
	 * Loads the languages to display as selectable.
	 *
	 * @param xmlFile The XML file from which to load.
	 * @throws IOException If an error occurs while parsing the file.
	 */
	private void getLocalizations(File xmlFile) throws IOException {

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		Document doc = null;
		try {
			db = dbf.newDocumentBuilder();
			//InputSource is = new InputSource(new FileReader(file));
			InputSource is = new InputSource(new UnicodeReader(
							new BufferedInputStream(
							new FileInputStream(xmlFile)), "UTF-8"));
			is.setEncoding("UTF-8");
			doc = db.parse(is);//db.parse(file);
		} catch (Exception e) {
			e.printStackTrace();
			throw new IOException("XML error:  Error parsing file");
		}

		// Traverse the XML tree.
		initializeFromXMLFile(doc);

	}


/*****************************************************************************/


	/**
	 * Returns the selected language, as a <code>Locale</code> string value.
	 *
	 * @return The selected language; i.e., <code>en</code> or
	 *         <code>es</code>.
	 */
	public final String getSelectedLanguage() {
		IconTextInfo iti = (IconTextInfo)languageList.getSelectedValue();
		String language = iti.getText();
		String code = (String)languageMap.get(language);
		if (code==null) {
			app.displayException(
				new InternalError("Couldn't find language code for " +
					"language: " + language));
			code = "en";
		}
		return code;
	}

	
/*****************************************************************************/


	/**
	 * Returns the <code>JComponent</code> at the "top" of this Options
	 * panel.  This is the component that will receive focus if the user
	 * switches to this Options panel in the Options dialog.  As an added
	 * bonus, if this component is a <code>JTextComponent</code>, its
	 * text is selected for easy changing.
	 */
	public JComponent getTopJComponent() {
		return languageList;
	}


/*****************************************************************************/


	/**
	 * Used in parsing an XML document containing a macro.  This method
	 * initializes this macro with the data contained in the passed-in node.
	 *
	 * @param node The root node of the parsed XML document.
	 * @throws IOException If an error occurs while parsing the XML.
	 */
	private void initializeFromXMLFile(Node node) throws IOException {

		if (node==null)
			throw new IOException("XML error:  node==null!");

		int type = node.getNodeType();
		switch (type) {

			// The document node is ???
			case Node.DOCUMENT_NODE:
				initializeFromXMLFile(
							((Document)node).getDocumentElement());
				break;

			// Handle element nodes.
			case Node.ELEMENT_NODE:

				String nodeName = node.getNodeName();

				// Might be the "topmost" node.
				if (nodeName.equals(ROOT_ELEMENT)) {
					NodeList childNodes = node.getChildNodes();
					// We should at least have English.
					if (childNodes==null || childNodes.getLength()==0) {
						throw new IOException("XML error:  There must " +
							"be at least 1 language declared!");
					}
					int childCount = childNodes.getLength();
					for (int i=0; i<childCount; i++)
						initializeFromXMLFile(childNodes.item(i));
				}

				// Might be a language declaration.
				else if (nodeName.equals(LANGUAGE)) {
					// Shouldn't have any children.
					NodeList childNodes = node.getChildNodes();
					if (childNodes!=null && childNodes.getLength()>0) {
						throw new IOException("XML error:  language " +
							"tags shouldn't have children!");
					}
					NamedNodeMap attributes = node.getAttributes();
					if (attributes==null || attributes.getLength()!=2) {
						throw new IOException("XML error:  language " +
							"tags should have two attributes!");
					}
					String name = null;
					String id = null;
					for (int i=0; i<2; i++) {
						Node node2 = attributes.item(i);
						nodeName = node2.getNodeName();
						if (nodeName.equals(NAME))
							name = node2.getNodeValue();
						else if (nodeName.equals(ID))
							id = node2.getNodeValue();
						else
							throw new IOException("XML error: unknown " +
								"attribute: '" + nodeName + "'");
					}
					if (name==null || id==null) {
						throw new IOException("XML error: language " +
							"must have attributes 'name' and 'id'.");
					}
					Icon icon = getIconFor(id);
					IconTextInfo iti = new IconTextInfo(name, icon);
					listModel.addElement(iti);
					languageMap.put(name, id);
				}

				// Anything else is an error.
				else {
					throw new IOException("XML error:  Unknown element " +
						"node: " + nodeName);
				}

				break;

			// Whitespace nodes.
			case Node.TEXT_NODE:
				break;

			// An error occured?
			default:
				throw new IOException("XML error:  Unknown node type: " +
					type);

		} // End of switch (type).

	}


/*****************************************************************************/


	/**
	 * Sets the language selected in this Options panel.
	 *
	 * @param language The language to be selected, as a Locale string
	 *        constant (e.g., <code>en</code> or <code>es</code>).
	 */
	public void setSelectedLanguage(String language) {

		int count = listModel.size();
		for (int i=0; i<count; i++) {
			Object obj = listModel.get(i);
			String langName = null;
			langName = ((IconTextInfo)obj).getText();
			String langValue = (String)languageMap.get(langName);
			if (language.startsWith(langValue)) {
				languageList.setSelectedIndex(i);
				return;
			}
		}

		// If the passed-in language wasn't "recognized," default to
		// English.
		for (int i=0; i<count; i++) {
			String langName = (String)listModel.get(i);
			String langValue = (String)languageMap.get(langName);
			if (langValue.equals("en")) {
				languageList.setSelectedIndex(i);
				return;
			}
		}

	}


/*****************************************************************************/


	/**
	 * Called when the user changes the language in the language list.
	 * Do not override.
	 */
	public void valueChanged(ListSelectionEvent e) {
		hasUnsavedChanges = true;
		firePropertyChange(LANGUAGE_PROPERTY,
						-1, languageList.getSelectedIndex());
	}


/*****************************************************************************/
/************************* INNER CLASSES *************************************/
/*****************************************************************************/


	/**
	 * Cell renderer that knows how to display both an icon and text (as
	 * <code>DefaultListCellRenderer</code> only knows how to display
	 * either/or).
	 */
	class CellRenderer extends DefaultListCellRenderer {

		public Component getListCellRendererComponent(JList list,
										Object value,
										int index,
										boolean isSelected,
										boolean cellHasFocus) {
			super.getListCellRendererComponent(list, value, index,
										isSelected, cellHasFocus);
			IconTextInfo iti = (IconTextInfo)value;
			setIcon(iti.getIcon());
			setText(iti.getText());
			return this;
		}

	}


/*****************************************************************************/


	/**
	 * An empty icon.
	 */
	static class EmptyIcon implements Icon {

		private static EmptyIcon instance;

		public int getIconHeight() {
			return EMPTY_ICON_HEIGHT;
		}

		public int getIconWidth() {
			return EMPTY_ICON_WIDTH;
		}

		public static EmptyIcon getInstance() {
			if (instance==null)
				instance = new EmptyIcon();
			return instance;
		}

		public void paintIcon(Component c, Graphics g, int x, int y) {
			// Do nothing.
		}

	}


/*****************************************************************************/


	/**
	 * Wrapper class for an icon and text; used in the language list to
	 * wrap the two into a single list element.
	 */
	class IconTextInfo {

		private Icon icon;
		private String text;

		public IconTextInfo(String text, Icon icon) {
			this.text = text;
			this.icon = icon;
		}

		public Icon getIcon() {
			return icon;
		}

		public String getText() {
			return text;
		}

	}


/*****************************************************************************/

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -