📄 inlineeditbox.java
字号:
/* * File: InlineEditBox.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * 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 * (at your option) 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 mpi.eudico.client.annotator.gui;import mpi.eudico.client.annotator.Constants;import mpi.eudico.client.annotator.ElanLocale;import mpi.eudico.client.annotator.ElanLocaleListener;import mpi.eudico.client.annotator.commands.Command;import mpi.eudico.client.annotator.commands.ELANCommandFactory;import mpi.eudico.client.annotator.viewer.SubtitleViewer;import mpi.eudico.client.im.ImUtil;import mpi.eudico.server.corpora.clom.Annotation;import mpi.eudico.server.corpora.clom.Transcription;import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;import mpi.util.CVEntry;import mpi.util.ControlledVocabulary;import mpi.util.LogUtil;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.Font;import java.awt.Point;import java.awt.Rectangle;import java.awt.Toolkit;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.FocusAdapter;import java.awt.event.FocusEvent;import java.awt.event.FocusListener;import java.awt.event.InputEvent;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.util.Locale;import java.util.logging.Logger;import javax.swing.DefaultComboBoxModel;import javax.swing.DefaultListModel;import javax.swing.JComboBox;import javax.swing.JComponent;import javax.swing.JDialog;import javax.swing.JList;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.JTextArea;import javax.swing.KeyStroke;import javax.swing.ListSelectionModel;import javax.swing.SwingUtilities;import javax.swing.event.ChangeEvent;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import javax.swing.event.MenuEvent;import javax.swing.event.MenuListener;/** * A class that provides and configures user interface components for editing * annotation values. Elan Viewer components that offer the possibility of * editing annotation values can use this class to get a suitable editor * component. Depending on the language (locale) of the annotation it will * activate special input method components. * * @author MPI * @version jun 2004 additions related to the use of controlled vocabularies * @version sep 2005 when an annotation's Locale is the system default and the * the edit box's is also the system default, the language isn't set anymore. * Tis way it is possible to use other system specific im's / keyboards on * MacOS as well. */public class InlineEditBox extends JPanel implements ActionListener, MouseListener, MenuListener, KeyListener, ElanLocaleListener { /** action command constant */ private static final String EDIT_MENU_DET = "Detach Editor"; /** action command constant */ private static final String EDIT_MENU_ATT = "Attach Editor"; /** action command constant */ private static final String EDIT_MENU_CMT = "Commit Changes"; /** action command constant */ private static final String EDIT_MENU_CNL = "Cancel Changes"; /** A logger to replace System.out calls. */ private static final Logger LOG = Logger.getLogger(InlineEditBox.class.getName()); /** the textarea in use when the editor is used in attached mode */ final private JTextArea textArea = new JTextArea("", 2, 1); /** the scrollpane for the attached-mode textarea */ final private JScrollPane textAreaScrollPane = new JScrollPane(textArea); /** the textarea in use when the editor is used in detached mode */ final private JTextArea exttextArea = new JTextArea("", 2, 1); /** the scrollpane for the detached-mode textarea */ final private JScrollPane exttextAreaScrollPane = new JScrollPane(exttextArea); /** * a focus listener that lets the attached-mode textarea request the * keyboard focus */ final private FocusListener intFocusListener = new FocusAdapter() { public void focusGained(FocusEvent e) { if (!isUsingControlledVocabulary) { textArea.requestFocus(); textArea.getCaret().setVisible(true); } else { if (cvEntryComp != null) { cvEntryComp.grabFocus(); } } } public void focusLost(FocusEvent e) { if (!isEditing) { transferFocusUpCycle(); } } }; /** * a focus listener that lets the detached-mode textarea request the * keyboard focus */ final private FocusListener extFocusListener = new FocusAdapter() { public void focusGained(FocusEvent e) { if (!isUsingControlledVocabulary) { exttextArea.requestFocus(); exttextArea.getCaret().setVisible(true); } else { if (cvEntryComp != null) { cvEntryComp.grabFocus(); } } } public void focusLost(FocusEvent e) { //transferFocusUpCycle(); } }; private JPopupMenu popupMenu = new JPopupMenu("Select Language"); private JDialog externalDialog = null; private Rectangle dialogBounds; private Locale[] allLocales; private int numberOfLocales; private String oldText; private boolean attached = true; private Annotation annotation; private Point position; private JTable table = null; private int editingColumn = -1; private Locale annotationLocale; private boolean attachable; private boolean isUsingControlledVocabulary = false; private SubtitleViewer subtitleViewer; // fields for Locale changes private JMenu editMenu; private JMenu editorMenu; private JMenu selectLanguageMenu; private JMenuItem attachMI; private JMenuItem commitMI; private JMenuItem cancelMI; private JMenuItem detachPUMI; private JMenuItem commitPUMI; private JMenuItem cancelPUMI; private JMenuItem selectAllPUMI; private JMenuItem cutMI; private JMenuItem copyMI; private JMenuItem pasteMI; private JMenuItem cutPUMI; private JMenuItem copyPUMI; private JMenuItem pastePUMI; private JMenuItem selectAllMI; private JMenuBar menuBar; /** a JList in a scrollpane */ private CVEntryComponent cvEntryComp; private int minCVWidth = 100; private int minCVHeight = 120; /** * this field can be either a JPanel (this), a JScrollPane, a JTextArea , a * JComboBox or any other component that can be added to the layout of a * viewer (component) */ private JComponent editorComponent; //temp private Font uniFont = Constants.DEFAULTFONT; private boolean isEditing = false; /** * If InlineEditBox is invoked by a Table, it'll call on exiting the * editingStopped/Cancelled methods of the Table. * * @param table the JTable that will use the editor component as a * tablecelleditor */ public InlineEditBox(JTable table) { this.table = table; init(); } /** * When this editor is not created by a viewer, it will always be created * as a "detached" dialog. * * @param attachable whether or not this editor can be attached to a * viewer component. */ public InlineEditBox(boolean attachable) { init(); this.attachable = attachable; } /** * Special case for a SubtitleViewer. <br> * The viewer receives a notification when editing has been stopped. * Pending: this should replaced by a more general type, an interface that * a viewer can implement that needs notification of inline editing * events (stopped, attached, detached...). * * @param subtitleViewer the subtitleviewer */ public InlineEditBox(SubtitleViewer subtitleViewer) { init(); this.subtitleViewer = subtitleViewer; } /** * Creates a new InlineEditBox instance */ public InlineEditBox() { init(); attached = false; } /** * DOCUMENT ME! */ public void init() { attachable = true; setLayout(new BorderLayout()); try { allLocales = ImUtil.getLanguages(); numberOfLocales = (allLocales == null) ? 0 : allLocales.length; } catch (java.lang.NoSuchMethodError nsme) { // The SPI extensions have not been present at startup. //String msg = "Setup incomplete: you won't be able to set languages for editing."; String msg = ElanLocale.getString("InlineEditBox.Message.SPI") + "\n" + ElanLocale.getString("InlineEditBox.Message.SPI2"); JOptionPane.showMessageDialog(null, msg, null, JOptionPane.ERROR_MESSAGE); } catch (Exception exc) { LOG.warning("InlineEditBox::init::ParentIMBug::FIXME"); LOG.warning(LogUtil.formatStackTrace(exc)); } textArea.addMouseListener(this); textArea.setLineWrap(false); textAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); add(textAreaScrollPane, BorderLayout.CENTER); textArea.getCaret().setVisible(true); textArea.addKeyListener(this); textArea.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { if (!annotationLocale.equals(Locale.getDefault()) && !annotationLocale.equals(textArea.getLocale())) { ImUtil.setLanguage(textArea, annotationLocale); textArea.setFont(uniFont); } } public void focusLost(FocusEvent e) { if (!isEditing) { transferFocusUpCycle(); } } }); exttextArea.setLineWrap(true); exttextArea.setWrapStyleWord(true); exttextArea.addKeyListener(this); exttextArea.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { if (!annotationLocale.equals(Locale.getDefault()) && !annotationLocale.equals(exttextArea.getLocale())) { ImUtil.setLanguage(exttextArea, annotationLocale); exttextArea.setFont(uniFont.deriveFont(20.0f)); } } public void focusLost(FocusEvent e) { if (!isEditing) { transferFocusUpCycle(); } } }); createPopupMenu(); exttextAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); exttextAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); textAreaScrollPane.addFocusListener(intFocusListener); addFocusListener(intFocusListener); } /** * Creates a modal JDialog when editing is done in detached mode. */ public void createExternalDialog() { try { externalDialog = new JDialog(ELANCommandFactory.getRootFrame( (Transcription) annotation.getTier().getParent()), ElanLocale.getString("InlineEditBox.Title"), true); } catch (Exception ex) { LOG.warning(LogUtil.formatStackTrace(ex)); } //exttextAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); //exttextAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); //externalDialog.getContentPane().add(exttextAreaScrollPane); if (menuBar == null) { createJMenuBar(); } externalDialog.setJMenuBar(menuBar); externalDialog.addFocusListener(extFocusListener); externalDialog.setSize(300, 300); } /** * Creates a popup menu. */ public void createPopupMenu() { detachPUMI = new JMenuItem(ElanLocale.getString("InlineEditBox.Detach")); detachPUMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ActionEvent.SHIFT_MASK)); detachPUMI.setActionCommand(EDIT_MENU_DET); detachPUMI.addActionListener(this); popupMenu.add(detachPUMI); commitPUMI = new JMenuItem(ElanLocale.getString("InlineEditBox.Commit")); commitPUMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); commitPUMI.setActionCommand(EDIT_MENU_CMT); commitPUMI.addActionListener(this); popupMenu.add(commitPUMI); cancelPUMI = new JMenuItem(ElanLocale.getString("InlineEditBox.Cancel")); cancelPUMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); cancelPUMI.setActionCommand(EDIT_MENU_CNL); cancelPUMI.addActionListener(this); popupMenu.add(cancelPUMI); popupMenu.addSeparator(); cutPUMI = new JMenuItem(ElanLocale.getString("InlineEditBox.Edit.Cut")); cutPUMI.setActionCommand("cut"); cutPUMI.addActionListener(this); popupMenu.add(cutPUMI); copyPUMI = new JMenuItem(ElanLocale.getString("InlineEditBox.Edit.Copy")); copyPUMI.setActionCommand("copy"); copyPUMI.addActionListener(this); popupMenu.add(copyPUMI); pastePUMI = new JMenuItem(ElanLocale.getString( "InlineEditBox.Edit.Paste")); pastePUMI.setActionCommand("paste"); pastePUMI.addActionListener(this); popupMenu.add(pastePUMI); selectAllPUMI = new JMenuItem(ElanLocale.getString( "InlineEditBox.Edit.SelectAll")); selectAllPUMI.setActionCommand("selectAll"); selectAllPUMI.addActionListener(this); popupMenu.add(selectAllPUMI); popupMenu.addSeparator(); JMenuItem newItem; for (int i = 0; i < numberOfLocales; i++) { if ((i == 0) && (allLocales[i] == Locale.getDefault())) { newItem = new JMenuItem(allLocales[i].getDisplayName() + " (System default)"); newItem.setActionCommand(allLocales[i].getDisplayName()); } else { newItem = new JMenuItem(allLocales[i].getDisplayName()); } popupMenu.add(newItem); newItem.addActionListener(this); } } private JMenuBar createJMenuBar() { menuBar = new JMenuBar(); editorMenu = new JMenu(ElanLocale.getString("InlineEditBox.Menu.Editor")); editMenu = new JMenu(ElanLocale.getString("Menu.Edit")); editMenu.addMenuListener(this); selectLanguageMenu = new JMenu(ElanLocale.getString( "InlineEditBox.Menu.Select")); if (attachable == true) { attachMI = new JMenuItem(ElanLocale.getString(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -