Revision: 19799
http://sourceforge.net/p/gate/code/19799
Author: markagreenwood
Date: 2016-11-25 12:55:26 +0000 (Fri, 25 Nov 2016)
Log Message:
-----------
moved the schema annotation editor code into it's plugin
Added Paths:
-----------
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.classpath
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.project
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/pom.xml
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/annedit/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/resources/
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/resources/creole.xml
Removed Paths:
-------------
gate/branches/sawdust2/gate-core/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/creole.xml
Deleted:
gate/branches/sawdust2/gate-core/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
===================================================================
---
gate/branches/sawdust2/gate-core/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
2016-11-25 12:53:48 UTC (rev 19798)
+++
gate/branches/sawdust2/gate-core/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
2016-11-25 12:55:26 UTC (rev 19799)
@@ -1,1306 +0,0 @@
-/*
- * Copyright (c) 1995-2012, The University of Sheffield. See the file
- * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
- *
- * This file is part of GATE (see http://gate.ac.uk/), and is free software,
- * licenced under the GNU Library General Public License, Version 2, June 1991
- * (in the distribution as file licence.html, and also available at
- * http://gate.ac.uk/gate/licence.html).
- *
- * AnnotationEditor.java
- *
- * Valentin Tablan, Sep 10, 2007
- *
- * $Id$
- */
-package gate.gui.annedit;
-
-import gate.Annotation;
-import gate.AnnotationSet;
-import gate.Factory;
-import gate.FeatureMap;
-import gate.Gate;
-import gate.LanguageResource;
-import gate.Resource;
-import gate.creole.AbstractVisualResource;
-import gate.creole.AnnotationSchema;
-import gate.creole.FeatureSchema;
-import gate.creole.ResourceInstantiationException;
-import gate.event.CreoleEvent;
-import gate.event.CreoleListener;
-import gate.gui.MainFrame;
-import gate.swing.JChoice;
-import gate.util.GateException;
-import gate.util.GateRuntimeException;
-import gate.util.InvalidOffsetException;
-import gate.util.LuckyException;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.ComponentOrientation;
-import java.awt.Container;
-import java.awt.Dialog;
-import java.awt.Dimension;
-import java.awt.Frame;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.HeadlessException;
-import java.awt.Insets;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.Window;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseMotionAdapter;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.Vector;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.Icon;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.JToggleButton;
-import javax.swing.KeyStroke;
-import javax.swing.SwingUtilities;
-import javax.swing.border.Border;
-import javax.swing.event.AncestorEvent;
-import javax.swing.event.AncestorListener;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.JTextComponent;
-
-/**
- * An annotation editor that enforces the annotation schemas currently loaded
in
- * the system. Once the editing of an annotation is started, it cannot be
- * completed until the annotation complies with the schema for that annotation
- * type.
- */
-@SuppressWarnings("serial")
-public class SchemaAnnotationEditor extends AbstractVisualResource implements
-
OwnedAnnotationEditor {
-
- @Override
- public void editAnnotation(Annotation ann, AnnotationSet set) {
- // the external components we listen to (the text and the list view) can
- // change outside of our control, so we need to update the values
frequently
- updateListeners();
- this.annotation = ann;
- this.annSet = set;
- // update the selection in the list view
- // this is necessary because sometimes the call to eidtAnnotaiton is
- // internally received from the search and annotate function.
- // update the editor display
- String annType = annotation == null ? null : annotation.getType();
- // update the border for the types choice
- if(annType == null) {
- // no annotation -> ok
- if(typesChoice.getBorder() != typeDefaultBorder)
- typesChoice.setBorder(typeDefaultBorder);
- } else {
- if(schemasByType.containsKey(annType)) {
- // accepted type
- if(typesChoice.getBorder() != typeDefaultBorder)
- typesChoice.setBorder(typeDefaultBorder);
- } else {
- // wrong type
- if(typesChoice.getBorder() != typeHighlightBorder)
- typesChoice.setBorder(typeHighlightBorder);
- }
- }
- // update the features editor
- SchemaFeaturesEditor newFeaturesEditor = featureEditorsByType.get(annType);
- // if new type, we need to change the features editor and selected type
- // button
- if(newFeaturesEditor != featuresEditor) {
- typesChoice.setSelectedItem(annType);
- if(featuresEditor != null) {
- featuresBox.remove(featuresEditor);
- featuresEditor.editFeatureMap(null);
- }
- featuresEditor = newFeaturesEditor;
- if(featuresEditor != null) {
- featuresBox.add(featuresEditor);
- }
- }
- if(featuresEditor != null) {
- FeatureMap features = ann.getFeatures();
- if(features == null) {
- features = Factory.newFeatureMap();
- ann.setFeatures(features);
- }
- featuresEditor.editFeatureMap(features);
- }
- // enable editing if there is an annotation, disable if not
- setEditingEnabled(annType != null);
- if(dialog != null) {
- if(annotation != null) {
- placeDialog(annotation.getStartNode().getOffset().intValue(),
- annotation.getEndNode().getOffset().intValue());
- } else {
- // this should only occur when the dialog is pinned, so offsets are
- // irrelevant
- placeDialog(0, 0);
- }
- }
- }
-
- /**
- * This editor implementation is designed to enforce schema compliance. This
- * method will return <tt>false</tt> if the current annotation type does not
- * have a schema or if the features of the current annotation do not comply
- * with the schema.
- *
- * @see gate.gui.annedit.OwnedAnnotationEditor#editingFinished()
- */
- @Override
- public boolean editingFinished() {
- if(annotation == null) return true;
- // if the dialog is hidden, we've missed the train and we can't force
- // compliance for the old annotation any more. Just give up and
- // allow further editing
- if(!dialog.isVisible()) return true;
- if(!schemasByType.containsKey(annotation.getType())) return false;
- // we need to check that:
- // 1) all required features have values
- // 2) all features known by schema that have values, comply with the schema
-
- AnnotationSchema aSchema = schemasByType.get(annotation.getType());
- if(aSchema.getFeatureSchemaSet() == null
- || aSchema.getFeatureSchemaSet().isEmpty()) {
- // known type but no schema restrictions -> OK
- return true;
- }
- FeatureMap annotationFeatures = annotation.getFeatures();
- Map<String, FeatureSchema> featureSchemaByName =
- new HashMap<String, FeatureSchema>();
- // store all the feature schemas, and check the required ones
- for(FeatureSchema aFeatureSchema : aSchema.getFeatureSchemaSet()) {
- featureSchemaByName.put(aFeatureSchema.getFeatureName(), aFeatureSchema);
- Object featureValue =
- annotationFeatures == null ? null : annotationFeatures
- .get(aFeatureSchema.getFeatureName());
- if(aFeatureSchema.isRequired() && featureValue == null) return false;
- }
- // check all the actual values for compliance
- for(Object featureName : annotationFeatures.keySet()) {
- Object featureValue = annotationFeatures.get(featureName);
- FeatureSchema fSchema = featureSchemaByName.get(featureName);
- if(fSchema != null) {
- // this is a schema feature
- if(fSchema.getFeatureValueClass().equals(Boolean.class)
- || fSchema.getFeatureValueClass().equals(Integer.class)
- || fSchema.getFeatureValueClass().equals(Short.class)
- || fSchema.getFeatureValueClass().equals(Byte.class)
- || fSchema.getFeatureValueClass().equals(Float.class)
- || fSchema.getFeatureValueClass().equals(Double.class)) {
- if(featureValue instanceof String) {
- // try to convert numbers
- try {
- if (fSchema.getFeatureValueClass().equals(Integer.class)) {
- featureValue = Integer.valueOf((String) featureValue);
- } else if (fSchema.getFeatureValueClass().equals(Short.class)) {
- featureValue = Short.valueOf((String) featureValue);
- } else if (fSchema.getFeatureValueClass().equals(Byte.class)) {
- featureValue = Byte.valueOf((String) featureValue);
- } else if (fSchema.getFeatureValueClass().equals(Double.class)) {
- featureValue = Double.valueOf((String) featureValue);
- } else if (fSchema.getFeatureValueClass().equals(Float.class)) {
- featureValue = Float.valueOf((String) featureValue);
- }
- annotationFeatures.put(featureName, featureValue);
- } catch (NumberFormatException e) {
- // could not convert
- return false;
- }
- } else if(!fSchema.getFeatureValueClass().isAssignableFrom(
- featureValue.getClass())) {
- // not a String, nor the exact correct class: invalid value type
- return false;
- }
- } else if(fSchema.getFeatureValueClass().equals(String.class)) {
- if(fSchema.getPermittedValues() != null
- && !fSchema.getPermittedValues().contains(featureValue)) {
- // invalid value
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /**
- * Does nothing, as this editor does not support cancelling and rollbacks.
- */
- @Override
- public void cancelAction() throws GateException {
- }
-
- /**
- * Returns <tt>true</tt> always as this editor is generic and can edit any
- * annotation type.
- */
- @Override
- public boolean canDisplayAnnotationType(String annotationType) {
- return true;
- }
-
- /**
- * Does nothing as this editor works in auto-commit mode (changes are
- * implemented immediately).
- */
- @Override
- public void okAction() throws GateException {
- }
-
- /**
- * Returns <tt>false</tt>, as this editor does not support cancel operations.
- */
- @Override
- public boolean supportsCancel() {
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see gate.gui.annedit.AnnotationEditor#isActive()
- */
- @Override
- public boolean isActive() {
- return dialog.isVisible();
- }
-
- /**
- * Finds the best location for the editor dialog for a given span of text
- */
- @Override
- public void placeDialog(int start, int end) {
- if(pinnedButton.isSelected()) {
- // just resize
- Point where = null;
- if(dialog.isVisible()) {
- // where = dialog.getLocationOnScreen();
- where = dialog.getLocation();
- }
- dialog.pack();
- if(where != null) {
- dialogLocation.move(where.x, where.y);
- dialog.setLocation(dialogLocation);
- }
- } else {
- // calculate position
- try {
- Rectangle startRect = owner.getTextComponent().modelToView(start);
- Rectangle endRect = owner.getTextComponent().modelToView(end);
- Point topLeft = owner.getTextComponent().getLocationOnScreen();
- int x = topLeft.x + startRect.x;
- int y = topLeft.y + endRect.y + endRect.height;
- // make sure the window doesn't start lower
- // than the end of the visible rectangle
- Rectangle visRect = owner.getTextComponent().getVisibleRect();
- int maxY = topLeft.y + visRect.y + visRect.height;
- // make sure window doesn't get off-screen
- dialog.pack();
- // responding to changed orientation
- if(currentOrientation == ComponentOrientation.RIGHT_TO_LEFT) {
- x = x - dialog.getSize().width;
- if(x < 0) x = 0;
- }
- // dialog.validate();
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- boolean revalidate = false;
- if(dialog.getSize().width > screenSize.width) {
- dialog.setSize(screenSize.width, dialog.getSize().height);
- revalidate = true;
- }
- if(dialog.getSize().height > screenSize.height) {
- dialog.setSize(dialog.getSize().width, screenSize.height);
- revalidate = true;
- }
- if(revalidate) dialog.validate();
- // calculate max X
- int maxX = screenSize.width - dialog.getSize().width;
- // calculate max Y
- if(maxY + dialog.getSize().height > screenSize.height) {
- maxY = screenSize.height - dialog.getSize().height;
- }
- // correct position
- if(y > maxY) y = maxY;
- if(x > maxX) x = maxX;
- dialogLocation.move(x, y);
- dialog.setLocation(dialogLocation);
- } catch(BadLocationException ble) {
- // this should never occur
- throw new GateRuntimeException(ble);
- }
- }
- if(!dialog.isVisible()) dialog.setVisible(true);
- }
-
- protected static final int HIDE_DELAY = 1500;
-
- protected static final int SHIFT_INCREMENT = 5;
-
- protected static final int CTRL_SHIFT_INCREMENT = 10;
-
- /**
- * The annotation currently being edited.
- */
- protected Annotation annotation;
-
- /**
- * The annotation set containing the currently edited annotation.
- */
- protected AnnotationSet annSet;
-
- /**
- * The controlling object for this editor.
- */
- private AnnotationEditorOwner owner;
-
- /**
- * The text component (obtained from the owner) that this editor listens to.
- */
- private JTextComponent textComponent;
-
- /**
- * JChoice used for selecting the annotation type.
- */
- protected JChoice<String> typesChoice;
-
- /**
- * The default border for the types choice
- */
- protected Border typeDefaultBorder;
-
- /**
- * The highlight border for the types choice
- */
- protected Border typeHighlightBorder;
-
- /**
- * The dialog used to show this annotation editor.
- */
- protected JDialog dialog;
-
- protected CreoleListener creoleListener;
-
- /**
- * Listener used to hide the editing window when the text is hidden.
- */
- protected AncestorListener textAncestorListener;
-
- /**
- * Stores the Annotation schema objects available in the system. The
- * annotation types are used as keys for the map.
- */
- protected Map<String, AnnotationSchema> schemasByType;
-
- /**
- * Caches the features editor for each annotation type.
- */
- protected Map<String, SchemaFeaturesEditor> featureEditorsByType;
-
- /**
- * The box used to host the features editor pane.
- */
- protected Box featuresBox;
-
- /**
- * Toggle button used to pin down the dialog.
- */
- protected JToggleButton pinnedButton;
-
- /**
- * The current features editor, one of the ones stored in
- * {@link #featureEditorsByType}.
- */
- protected SchemaFeaturesEditor featuresEditor = null;
-
- protected MouseEvent pressed;
-
- public SchemaAnnotationEditor() {
- initData();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see gate.creole.AbstractVisualResource#init()
- */
- @Override
- public Resource init() throws ResourceInstantiationException {
- super.init();
- initGui();
- initListeners();
- return this;
- }
-
- protected void updateListeners() {
- if(owner != null) {
- // we have a new owner
- // if the components that we listen to have changed, we need to update
the
- // listeners
- if(textComponent != getOwner().getTextComponent()) {
- // remove old listener
- if(textComponent != null) {
- textComponent.removeAncestorListener(textAncestorListener);
- }
- this.textComponent = owner.getTextComponent();
- // register new listener
- if(textComponent != null) {
- textComponent.addAncestorListener(textAncestorListener);
- }
- }
- } else {
- // no new owner -> just remove old listeners
- if(textComponent != null) {
- textComponent.removeAncestorListener(textAncestorListener);
- }
- }
- }
-
- protected void initData() {
- schemasByType = new TreeMap<String, AnnotationSchema>();
- for(LanguageResource aSchema : Gate.getCreoleRegister().getLrInstances(
- "gate.creole.AnnotationSchema")) {
- schemasByType.put(((AnnotationSchema)aSchema).getAnnotationName(),
- (AnnotationSchema)aSchema);
- }
- creoleListener = new CreoleListener() {
- @Override
- public void resourceLoaded(CreoleEvent e) {
- Resource newResource = e.getResource();
- if(newResource instanceof AnnotationSchema) {
- AnnotationSchema aSchema = (AnnotationSchema)newResource;
- schemasByType.put(aSchema.getAnnotationName(), aSchema);
- }
- }
-
- @Override
- public void resourceUnloaded(CreoleEvent e) {
- Resource newResource = e.getResource();
- if(newResource instanceof AnnotationSchema) {
- AnnotationSchema aSchema = (AnnotationSchema)newResource;
- if(schemasByType.containsValue(aSchema)) {
- schemasByType.remove(aSchema.getAnnotationName());
- }
- }
- }
-
- @Override
- public void datastoreOpened(CreoleEvent e) {
- }
-
- @Override
- public void datastoreCreated(CreoleEvent e) {
- }
-
- @Override
- public void datastoreClosed(CreoleEvent e) {
- }
-
- @Override
- public void resourceRenamed(Resource resource, String oldName,
- String newName) {
- }
- };
- Gate.getCreoleRegister().addCreoleListener(creoleListener);
- textAncestorListener = new AncestorListener() {
- /**
- * A flag used to mark the fact that the dialog is active and was hidden
- * by this listener.
- */
- private boolean dialogActive = false;
-
- @Override
- public void ancestorAdded(AncestorEvent event) {
- if(dialogActive) {
- if(annotation != null) {
- placeDialog(annotation.getStartNode().getOffset().intValue(),
- annotation.getEndNode().getOffset().intValue());
- }
- dialogActive = false;
- }
- }
-
- @Override
- public void ancestorMoved(AncestorEvent event) {
- if(dialog.isVisible() && annotation != null) {
- placeDialog(annotation.getStartNode().getOffset().intValue(),
- annotation.getEndNode().getOffset().intValue());
- }
- }
-
- @Override
- public void ancestorRemoved(AncestorEvent event) {
- if(dialog.isVisible()) {
- dialogActive = true;
- dialog.setVisible(false);
- }
- }
- };
- }
-
- @Override
- public void cleanup() {
- Gate.getCreoleRegister().removeCreoleListener(creoleListener);
- }
-
- protected void initGui() {
- // make the dialog
- Window parentWindow =
- SwingUtilities.windowForComponent(owner.getTextComponent());
- if(parentWindow != null) {
- dialog =
- parentWindow instanceof Frame ? new JDialog((Frame)parentWindow,
- "Annotation Editor Dialog", false) : new JDialog(
- (Dialog)parentWindow, "Annotation Editor Dialog", false);
- dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
- MainFrame.getGuiRoots().add(dialog);
- }
- setLayout(new BorderLayout());
- // build the toolbar
- JPanel tBar = new JPanel();
- tBar.setLayout(new GridBagLayout());
- GridBagConstraints constraints = new GridBagConstraints();
- constraints.gridx = GridBagConstraints.RELATIVE;
- constraints.gridy = 0;
- constraints.weightx = 0;
- solButton = new IconOnlyButton(null);
- solButton.setIcon(MainFrame.getIcon("bounds-sol"));
- solButton.setPressedIcon(MainFrame.getIcon("bounds-sol-pressed"));
- tBar.add(solButton, constraints);
- JLabel aLabel = new JLabel(MainFrame.getIcon("bounds-left"));
- aLabel.setBorder(null);
- tBar.add(aLabel, constraints);
- sorButton = new IconOnlyButton(null);
- sorButton.setIcon(MainFrame.getIcon("bounds-sor"));
- sorButton.setPressedIcon(MainFrame.getIcon("bounds-sor-pressed"));
- tBar.add(sorButton, constraints);
- aLabel = new JLabel(MainFrame.getIcon("bounds-span"));
- aLabel.setBorder(null);
- tBar.add(aLabel, constraints);
- eolButton = new IconOnlyButton(null);
- eolButton.setIcon(MainFrame.getIcon("bounds-eol"));
- eolButton.setPressedIcon(MainFrame.getIcon("bounds-eol-pressed"));
- tBar.add(eolButton, constraints);
- aLabel = new JLabel(MainFrame.getIcon("bounds-right"));
- aLabel.setBorder(null);
- tBar.add(aLabel, constraints);
- eorButton = new IconOnlyButton(null);
- eorButton.setIcon(MainFrame.getIcon("bounds-eor"));
- eorButton.setPressedIcon(MainFrame.getIcon("bounds-eor-pressed"));
- tBar.add(eorButton, constraints);
- tBar.add(Box.createHorizontalStrut(15), constraints);
- tBar.add(delButton = new SmallButton(null), constraints);
- constraints.weightx = 1;
- tBar.add(Box.createHorizontalGlue(), constraints);
- constraints.weightx = 0;
- pinnedButton = new JToggleButton(MainFrame.getIcon("pin"));
- pinnedButton.setSelectedIcon(MainFrame.getIcon("pin-in"));
- pinnedButton.setSelected(false);
- pinnedButton.setToolTipText("Press to pin window in place.");
- pinnedButton.setMargin(new Insets(0, 2, 0, 2));
- pinnedButton.setBorderPainted(false);
- pinnedButton.setContentAreaFilled(false);
- tBar.add(pinnedButton);
- add(tBar, BorderLayout.NORTH);
- // build the main pane
- mainPane = new JPanel();
- mainPane.setLayout(new BorderLayout());
- featureEditorsByType = new HashMap<String, SchemaFeaturesEditor>();
- // for each schema we need to create a type button and a features editor
- for(String annType : schemasByType.keySet()) {
- AnnotationSchema annSchema = schemasByType.get(annType);
- SchemaFeaturesEditor aFeaturesEditor =
- new SchemaFeaturesEditor(annSchema);
- featureEditorsByType.put(annType, aFeaturesEditor);
- }
- List<String> typeList = new ArrayList<String>(schemasByType.keySet());
- Collections.sort(typeList);
- String[] typesArray = new String[typeList.size()];
- typeList.toArray(typesArray);
- typesChoice = new JChoice<String>(typesArray);
- typesChoice.setDefaultButtonMargin(new Insets(0, 2, 0, 2));
- typesChoice.setMaximumFastChoices(20);
- typesChoice.setMaximumWidth(300);
- String aTitle = "Type ";
- Border titleBorder = BorderFactory.createTitledBorder(aTitle);
- typeDefaultBorder =
- BorderFactory.createCompoundBorder(titleBorder,
- BorderFactory.createEmptyBorder(2, 2, 2, 2));
- typeHighlightBorder =
- BorderFactory.createCompoundBorder(titleBorder,
- BorderFactory.createLineBorder(Color.RED, 2));
- typesChoice.setBorder(typeDefaultBorder);
- aLabel = new JLabel(aTitle);
- typesChoice
- .setMinimumSize(new Dimension(aLabel.getPreferredSize().width, 0));
- mainPane.add(typesChoice, BorderLayout.NORTH);
- // add the features box
- featuresBox = Box.createVerticalBox();
- aTitle = "Features ";
- featuresBox.setBorder(BorderFactory.createTitledBorder(aTitle));
- aLabel = new JLabel(aTitle);
- mainPane.add(featuresBox, BorderLayout.SOUTH);
- add(mainPane, BorderLayout.CENTER);
- // add the search and annotate GUI at the bottom of the annotator editor
- SearchAndAnnotatePanel searchPanel =
- new SearchAndAnnotatePanel(mainPane.getBackground(), this, dialog);
- add(searchPanel, BorderLayout.SOUTH);
- dialog.add(this);
- dialog.pack();
- }
-
- protected void initListeners() {
- typesChoice.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- String newType;
- if(typesChoice.getSelectedItem() == null) {
- newType = "";
- } else {
- newType = typesChoice.getSelectedItem().toString();
- }
- if(annotation != null && annSet != null
- && !annotation.getType().equals(newType)) {
- // annotation type change
- Integer oldId = annotation.getId();
- Annotation oldAnn = annotation;
- annSet.remove(oldAnn);
- try {
- annSet.add(oldId, oldAnn.getStartNode().getOffset(), oldAnn
- .getEndNode().getOffset(), newType, oldAnn.getFeatures());
- Annotation newAnn = annSet.get(oldId);
- // update the selection to the new annotation
- getOwner().selectAnnotation(new AnnotationDataImpl(annSet,
newAnn));
- editAnnotation(newAnn, annSet);
- owner.annotationChanged(newAnn, annSet, oldAnn.getType());
- } catch(InvalidOffsetException ioe) {
- // this should never happen
- throw new LuckyException(ioe);
- }
- }
- }
- });
- dialog.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- if(editingFinished()) {
- // we can close
- dialog.setVisible(false);
- if(pinnedButton.isSelected()) pinnedButton.setSelected(false);
- } else {
- // let's be really snotty
- getToolkit().beep();
- }
- }
- });
- dialog.getRootPane().addMouseListener(new MouseAdapter() {
- // allow dialog to be dragged with a mouse
- @Override
- public void mousePressed(MouseEvent me) {
- pressed = me;
- }
- });
- dialog.getRootPane().addMouseMotionListener(new MouseMotionAdapter() {
- Point location;
-
- // allow a dialog to be dragged with a mouse
- @Override
- public void mouseDragged(MouseEvent me) {
- location = dialog.getLocation(location);
- int x = location.x - pressed.getX() + me.getX();
- int y = location.y - pressed.getY() + me.getY();
- dialog.setLocation(x, y);
- pinnedButton.setSelected(true);
- }
- });
- dialog.addComponentListener(new ComponentAdapter() {
- /*
- * (non-Javadoc)
- *
- * @see java.awt.event.ComponentAdapter#componentMoved(java.awt.event.
- * ComponentEvent)
- */
- @Override
- public void componentMoved(ComponentEvent e) {
- Point newLocation = dialog.getLocation();
- if(!newLocation.equals(dialogLocation)) {
- pinnedButton.setSelected(true);
- }
- }
- });
- InputMap inputMap =
- ((JComponent)dialog.getContentPane())
- .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
- actionMap = ((JComponent)dialog.getContentPane()).getActionMap();
- // add the key-action bindings of this Component to the parent window
- solAction =
- new StartOffsetLeftAction("", MainFrame.getIcon("extend-left"),
- SOL_DESC, KeyEvent.VK_LEFT);
- solButton.setAction(solAction);
- setShortCuts(inputMap, SOL_KEY_STROKES, "solAction");
- actionMap.put("solAction", solAction);
- sorAction =
- new StartOffsetRightAction("", MainFrame.getIcon("extend-right"),
- SOR_DESC, KeyEvent.VK_RIGHT);
- sorButton.setAction(sorAction);
- setShortCuts(inputMap, SOR_KEY_STROKES, "sorAction");
- actionMap.put("sorAction", sorAction);
- delAction =
- new DeleteAnnotationAction("", MainFrame.getIcon("remove-annotation"),
- "Delete the annotation", KeyEvent.VK_DELETE);
- delButton.setAction(delAction);
- inputMap.put(KeyStroke.getKeyStroke("alt DELETE"), "delAction");
- actionMap.put("delAction", delAction);
- eolAction =
- new EndOffsetLeftAction("", MainFrame.getIcon("extend-left"), EOL_DESC,
- KeyEvent.VK_LEFT);
- eolButton.setAction(eolAction);
- setShortCuts(inputMap, EOL_KEY_STROKES, "eolAction");
- actionMap.put("eolAction", eolAction);
- eorAction =
- new EndOffsetRightAction("", MainFrame.getIcon("extend-right"),
- EOR_DESC, KeyEvent.VK_RIGHT);
- eorButton.setAction(eorAction);
- setShortCuts(inputMap, EOR_KEY_STROKES, "eorAction");
- actionMap.put("eorAction", eorAction);
- Action dismissAction = new AbstractAction() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- dialog.setVisible(false);
- }
- };
- inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "dismissAction");
- actionMap.put("dismissAction", dismissAction);
- }
-
- /**
- * Stores the currently set dialog location (which is used to identify cases
- * when the dialog was moved by hand, which causes the dialog to be pinned).
- */
- private Point dialogLocation = new Point(0, 0);
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- try {
- Gate.init();
- JFrame aFrame = new JFrame("New Annotation Editor");
- aFrame.setSize(800, 600);
- aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- JDialog annDialog =
- new JDialog(aFrame, "Annotation Editor Dialog", false);
- annDialog.setFocusableWindowState(false);
- // annDialog.setResizable(false);
- // annDialog.setUndecorated(true);
- SchemaAnnotationEditor pane = new SchemaAnnotationEditor();
- annDialog.add(pane);
- annDialog.pack();
- // JToolBar tBar = new JToolBar("Annotation Editor",
JToolBar.HORIZONTAL);
- // tBar.setLayout(new BorderLayout());
- // tBar.setMinimumSize(tBar.getPreferredSize());
- // tBar.add(pane);
- // aFrame.getContentPane().add(tBar, BorderLayout.NORTH);
- StringBuffer strBuf = new StringBuffer();
- for(int i = 0; i < 100; i++) {
- strBuf.append("The quick brown fox jumped over the lazy dog.\n");
- }
- JTextArea aTextPane = new JTextArea(strBuf.toString());
- JScrollPane scroller = new JScrollPane(aTextPane);
- aFrame.getContentPane().add(scroller, BorderLayout.CENTER);
- // Box aBox = Box.createVerticalBox();
- // aFrame.getContentPane().add(aBox);
- //
- // FeatureEditor aFeatEditor = new FeatureEditor("F-nominal-small",
- // FeatureType.nominal, "val1");
- // aFeatEditor.setValues(new String[]{"val1", "val2", "val3"});
- // aBox.add(aFeatEditor.getGui());
- //
- // aFeatEditor = new FeatureEditor("F-nominal-large",
- // FeatureType.nominal, "val1");
- // aFeatEditor.setValues(new String[]{"val1", "val2", "val3", "val4",
- // "val5",
- // "val6", "val7", "val8", "val9"});
- // aBox.add(aFeatEditor.getGui());
- //
- // aFeatEditor = new FeatureEditor("F-boolean-true",
- // FeatureType.bool, "true");
- // aBox.add(aFeatEditor.getGui());
- //
- // aFeatEditor = new FeatureEditor("F-boolean-false",
- // FeatureType.bool, "false");
- // aBox.add(aFeatEditor.getGui());
- aFrame.setVisible(true);
- System.out.println("Window up");
- annDialog.setVisible(true);
- System.out.println("Dialog up");
- } catch(HeadlessException e) {
- e.printStackTrace();
- } catch(GateException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Base class for actions on annotations.
- */
- protected abstract class AnnotationAction extends AbstractAction {
- public AnnotationAction(String text, Icon icon, String desc, int mnemonic)
{
- super(text, icon);
- putValue(SHORT_DESCRIPTION, desc);
- putValue(MNEMONIC_KEY, mnemonic);
- }
- }
-
- protected class StartOffsetLeftAction extends AnnotationAction {
- private static final long serialVersionUID = 1L;
-
- public StartOffsetLeftAction(String text, Icon icon, String desc,
- int mnemonic) {
- super(text, icon, desc, mnemonic);
- }
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- int increment = 1;
- if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
- // CTRL pressed -> use tokens for advancing
- increment = SHIFT_INCREMENT;
- if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
- increment = CTRL_SHIFT_INCREMENT;
- }
- }
- long newValue =
- annotation.getStartNode().getOffset().longValue() - increment;
- if(newValue < 0) newValue = 0;
- try {
- moveAnnotation(annSet, annotation, new Long(newValue), annotation
- .getEndNode().getOffset());
- } catch(InvalidOffsetException ioe) {
- throw new GateRuntimeException(ioe);
- }
- }
- }
-
- protected class StartOffsetRightAction extends AnnotationAction {
- private static final long serialVersionUID = 1L;
-
- public StartOffsetRightAction(String text, Icon icon, String desc,
- int mnemonic) {
- super(text, icon, desc, mnemonic);
- }
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- long endOffset = annotation.getEndNode().getOffset().longValue();
- int increment = 1;
- if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
- // CTRL pressed -> use tokens for advancing
- increment = SHIFT_INCREMENT;
- if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
- increment = CTRL_SHIFT_INCREMENT;
- }
- }
- long newValue =
- annotation.getStartNode().getOffset().longValue() + increment;
- if(newValue > endOffset) newValue = endOffset;
- try {
- moveAnnotation(annSet, annotation, new Long(newValue), annotation
- .getEndNode().getOffset());
- } catch(InvalidOffsetException ioe) {
- throw new GateRuntimeException(ioe);
- }
- }
- }
-
- protected class EndOffsetLeftAction extends AnnotationAction {
- private static final long serialVersionUID = 1L;
-
- public EndOffsetLeftAction(String text, Icon icon, String desc, int
mnemonic) {
- super(text, icon, desc, mnemonic);
- }
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- long startOffset = annotation.getStartNode().getOffset().longValue();
- int increment = 1;
- if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
- // CTRL pressed -> use tokens for advancing
- increment = SHIFT_INCREMENT;
- if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
- increment = CTRL_SHIFT_INCREMENT;
- }
- }
- long newValue =
- annotation.getEndNode().getOffset().longValue() - increment;
- if(newValue < startOffset) newValue = startOffset;
- try {
- moveAnnotation(annSet, annotation, annotation.getStartNode()
- .getOffset(), new Long(newValue));
- } catch(InvalidOffsetException ioe) {
- throw new GateRuntimeException(ioe);
- }
- }
- }
-
- protected class EndOffsetRightAction extends AnnotationAction {
- private static final long serialVersionUID = 1L;
-
- public EndOffsetRightAction(String text, Icon icon, String desc,
- int mnemonic) {
- super(text, icon, desc, mnemonic);
- }
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- long maxOffset = owner.getDocument().getContent().size().longValue() - 1;
- int increment = 1;
- if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
- // CTRL pressed -> use tokens for advancing
- increment = SHIFT_INCREMENT;
- if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
- increment = CTRL_SHIFT_INCREMENT;
- }
- }
- long newValue =
- annotation.getEndNode().getOffset().longValue() + increment;
- if(newValue > maxOffset) newValue = maxOffset;
- try {
- moveAnnotation(annSet, annotation, annotation.getStartNode()
- .getOffset(), new Long(newValue));
- } catch(InvalidOffsetException ioe) {
- throw new GateRuntimeException(ioe);
- }
- }
- }
-
- protected class DeleteAnnotationAction extends AnnotationAction {
- private static final long serialVersionUID = 1L;
-
- public DeleteAnnotationAction(String text, Icon icon, String desc,
- int mnemonic) {
- super(text, icon, desc, mnemonic);
- }
-
- @Override
- public void actionPerformed(ActionEvent evt) {
- annSet.remove(annotation);
- // clear the dialog
- editAnnotation(null, annSet);
- if(!pinnedButton.isSelected()) {
- // if not pinned, hide the dialog.
- dialog.setVisible(false);
- } else {
- setEditingEnabled(false);
- }
- }
- }
-
- /**
- * Changes the span of an existing annotation by creating a new annotation
- * with the same ID, type and features but with the new start and end
offsets.
- *
- * @param set
- * the annotation set
- * @param oldAnnotation
- * the annotation to be moved
- * @param newStartOffset
- * the new start offset
- * @param newEndOffset
- * the new end offset
- */
- protected void moveAnnotation(AnnotationSet set, Annotation oldAnnotation,
- Long newStartOffset, Long newEndOffset) throws InvalidOffsetException {
- // Moving is done by deleting the old annotation and creating a new one.
- // If this was the last one of one type it would mess up the gui which
- // "forgets" about this type and then it recreates it (with a different
- // colour and not visible.
- // In order to avoid this problem, we'll create a new temporary annotation.
- Annotation tempAnn = null;
- if(set.get(oldAnnotation.getType()).size() == 1) {
- // create a clone of the annotation that will be deleted, to act as a
- // placeholder
- Integer tempAnnId =
- set.add(oldAnnotation.getStartNode(), oldAnnotation.getStartNode(),
- oldAnnotation.getType(), oldAnnotation.getFeatures());
- tempAnn = set.get(tempAnnId);
- }
- Integer oldID = oldAnnotation.getId();
- set.remove(oldAnnotation);
- set.add(oldID, newStartOffset, newEndOffset, oldAnnotation.getType(),
- oldAnnotation.getFeatures());
- Annotation newAnn = set.get(oldID);
- // update the selection to the new annotation
- getOwner().selectAnnotation(new AnnotationDataImpl(set, newAnn));
- editAnnotation(newAnn, set);
- // remove the temporary annotation
- if(tempAnn != null) set.remove(tempAnn);
- owner.annotationChanged(newAnn, set, null);
- }
-
- /**
- * A JButton with content are not filled and border not painted (in order to
- * save screen real estate)
- */
- protected class SmallButton extends JButton {
- private static final long serialVersionUID = 1L;
-
- public SmallButton(Action a) {
- super(a);
- // setBorder(null);
- setMargin(new Insets(0, 2, 0, 2));
- // setBorderPainted(false);
- // setContentAreaFilled(false);
- }
- }
-
- protected class IconOnlyButton extends JButton {
- private static final long serialVersionUID = 1L;
-
- public IconOnlyButton(Action a) {
- super(a);
- setMargin(new Insets(0, 0, 0, 0));
- setBorder(null);
- setBorderPainted(false);
- setContentAreaFilled(false);
- }
- }
-
- protected IconOnlyButton solButton;
-
- protected IconOnlyButton sorButton;
-
- protected SmallButton delButton;
-
- protected IconOnlyButton eolButton;
-
- protected IconOnlyButton eorButton;
-
- protected JPanel mainPane;
-
- /**
- * Action bindings for the popup window.
- */
- ActionMap actionMap;
-
- private StartOffsetLeftAction solAction;
-
- private StartOffsetRightAction sorAction;
-
- private DeleteAnnotationAction delAction;
-
- private EndOffsetLeftAction eolAction;
-
- private EndOffsetRightAction eorAction;
-
- /**
- * @return the owner
- */
- @Override
- public AnnotationEditorOwner getOwner() {
- return owner;
- }
-
- /**
- * @param owner
- * the owner to set
- */
- @Override
- public void setOwner(AnnotationEditorOwner owner) {
- // if the owner is new, register existing listeners to new owner elements
- if(this.owner != owner) {
- this.owner = owner;
- updateListeners();
- }
- }
-
- @Override
- public AnnotationSet getAnnotationSetCurrentlyEdited() {
- return annSet;
- }
-
- @Override
- public Annotation getAnnotationCurrentlyEdited() {
- return annotation;
- }
-
- @Override
- public void setPinnedMode(boolean pinned) {
- pinnedButton.setSelected(pinned);
- }
-
- @Override
- public void setEditingEnabled(boolean isEditingEnabled) {
- solButton.setEnabled(isEditingEnabled);
- sorButton.setEnabled(isEditingEnabled);
- delButton.setEnabled(isEditingEnabled);
- eolButton.setEnabled(isEditingEnabled);
- eorButton.setEnabled(isEditingEnabled);
- for(Component c : typesChoice.getComponents()) {
- c.setEnabled(isEditingEnabled);
- }
- // en/disable the components in the featuresBox
- Vector<Component> components = new Vector<Component>();
- Collections.addAll(components, featuresBox.getComponents());
- while(!components.isEmpty()) {
- Component component = components.remove(0);
- if(component instanceof JToggleButton || component instanceof
JTextField) {
- component.setEnabled(isEditingEnabled);
- } else if(component instanceof Container) {
- Collections.addAll(components, ((Container)component).getComponents());
- }
- }
- // enable/disable the key binding actions
- if(isEditingEnabled) {
- actionMap.put("solAction", solAction);
- actionMap.put("sorAction", sorAction);
- actionMap.put("delAction", delAction);
- actionMap.put("eolAction", eolAction);
- actionMap.put("eorAction", eorAction);
- } else {
- actionMap.put("solAction", null);
- actionMap.put("sorAction", null);
- actionMap.put("delAction", null);
- actionMap.put("eolAction", null);
- actionMap.put("eorAction", null);
- }
- // reapply the orientation settings after editing is enabled or disabled
- changeOrientation(currentOrientation);
- }
-
- @Override
- public void changeOrientation(ComponentOrientation orientation) {
- if(orientation == null) return;
- // remember the current orientation
- this.currentOrientation = orientation;
- // input map
- InputMap inputMap =
- ((JComponent)dialog.getContentPane())
- .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
- Action solAction = actionMap.get("solAction");
- Action sorAction = actionMap.get("sorAction");
- Action eolAction = actionMap.get("eolAction");
- Action eorAction = actionMap.get("eorAction");
- if(orientation == ComponentOrientation.RIGHT_TO_LEFT) {
- // in right to left orientation
- // extending start offset is equal to extending end offset
- solButton.setAction(eorAction);
- solButton.setToolTipText(EOR_DESC);
- setShortCuts(inputMap, SOL_KEY_STROKES, "eorAction");
- solButton.setIcon(MainFrame.getIcon("extend-left"));
- // shrinking start offset is equal to shrinking end offset
- sorButton.setAction(eolAction);
- sorButton.setToolTipText(EOL_DESC);
- setShortCuts(inputMap, SOR_KEY_STROKES, "eolAction");
- sorButton.setIcon(MainFrame.getIcon("extend-right"));
- // shrinking end offset is equal to shrinking start offset
- eolButton.setAction(sorAction);
- eolButton.setToolTipText(SOR_DESC);
- setShortCuts(inputMap, EOL_KEY_STROKES, "sorAction");
- eolButton.setIcon(MainFrame.getIcon("extend-left"));
- // extending end offset is extending start offset
- eorButton.setAction(solAction);
- eorButton.setToolTipText(SOL_DESC);
- setShortCuts(inputMap, EOR_KEY_STROKES, "solAction");
- eorButton.setIcon(MainFrame.getIcon("extend-right"));
- } else {
- solButton.setAction(solAction);
- solButton.setToolTipText(SOL_DESC);
- setShortCuts(inputMap, SOL_KEY_STROKES, "solAction");
- solButton.setIcon(MainFrame.getIcon("extend-left"));
- sorButton.setAction(sorAction);
- sorButton.setToolTipText(SOR_DESC);
- setShortCuts(inputMap, SOR_KEY_STROKES, "sorAction");
- sorButton.setIcon(MainFrame.getIcon("extend-right"));
- eolButton.setAction(eolAction);
- eolButton.setToolTipText(EOL_DESC);
- setShortCuts(inputMap, EOL_KEY_STROKES, "eolAction");
- eolButton.setIcon(MainFrame.getIcon("extend-left"));
- eorButton.setAction(eorAction);
- eorButton.setToolTipText(EOR_DESC);
- setShortCuts(inputMap, EOR_KEY_STROKES, "eorAction");
- eorButton.setIcon(MainFrame.getIcon("extend-right"));
- }
- }
-
- /**
- * Utility method to set short cuts
- *
- * @param inputMap
- * @param keyStrokes
- * @param action
- */
- private void setShortCuts(InputMap inputMap, String[] keyStrokes,
- String action) {
- for(String aKeyStroke : keyStrokes) {
- inputMap.put(KeyStroke.getKeyStroke(aKeyStroke), action);
- }
- }
-
- /**
- * current orientation set by the user
- */
- private ComponentOrientation currentOrientation = null;
-
- /* various tool tips for buttons used for changing offsets */
- private final String SOL_DESC = "<html><b>Extend start</b><small>"
- + "<br>LEFT = 1 character" + "<br> + SHIFT = 5 characters, "
- + "<br> + CTRL + SHIFT = 10 characters</small></html>";
-
- private final String SOR_DESC = "<html><b>Shrink start</b><small>"
- + "<br>RIGHT = 1 character" + "<br> + SHIFT = 5 characters, "
- + "<br> + CTRL + SHIFT = 10 characters</small></html>";
-
- private final String EOL_DESC = "<html><b>Shrink end</b><small>"
- + "<br>ALT + LEFT = 1 character" + "<br> + SHIFT = 5 characters, "
- + "<br> + CTRL + SHIFT = 10 characters</small></html>";
-
- private final String EOR_DESC = "<html><b>Extend end</b><small>"
- + "<br>ALT + RIGHT = 1 character" + "<br> + SHIFT = 5 characters, "
- + "<br> + CTRL + SHIFT = 10 characters</small></html>";
-
- /* various shortcuts we define */
- private final String[] SOL_KEY_STROKES = new String[]{"LEFT", "shift LEFT",
- "control shift released LEFT"};
-
- private final String[] SOR_KEY_STROKES = new String[]{"RIGHT", "shift RIGHT",
- "control shift released RIGHT"};
-
- private final String[] EOL_KEY_STROKES = new String[]{"LEFT", "alt LEFT",
- "control alt released LEFT"};
-
- private final String[] EOR_KEY_STROKES = new String[]{"RIGHT", "alt RIGHT",
- "control alt released RIGHT"};
-}
Added: gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.classpath
===================================================================
--- gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.classpath
(rev 0)
+++ gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.classpath
2016-11-25 12:55:26 UTC (rev 19799)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry excluding="**" kind="src" output="target/classes"
path="src/main/resources">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/test-classes"
path="src/test/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con"
path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.project
===================================================================
--- gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.project
(rev 0)
+++ gate/branches/sawdust2/plugins/Schema_Annotation_Editor/.project
2016-11-25 12:55:26 UTC (rev 19799)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>GATE-plugin-Schema_Annotation_Editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
Deleted: gate/branches/sawdust2/plugins/Schema_Annotation_Editor/creole.xml
===================================================================
--- gate/branches/sawdust2/plugins/Schema_Annotation_Editor/creole.xml
2016-11-25 12:53:48 UTC (rev 19798)
+++ gate/branches/sawdust2/plugins/Schema_Annotation_Editor/creole.xml
2016-11-25 12:55:26 UTC (rev 19799)
@@ -1,14 +0,0 @@
-<?xml version="1.0"?>
-<!-- $Id$ -->
-<!-- creole.xml directory file for Schema-restricted annotation editor -->
-<CREOLE-DIRECTORY>
- <!-- creole.xml for Visual Resources -->
- <CREOLE>
- <RESOURCE>
- <NAME>Schema Annotations Editor</NAME>
- <CLASS>gate.gui.annedit.SchemaAnnotationEditor</CLASS>
- <COMMENT>An annotation editor restricted by schemas.</COMMENT>
- <HELPURL>http://gate.ac.uk/userguide/sec:corpora:schemas</HELPURL>
- </RESOURCE>
- </CREOLE>
-</CREOLE-DIRECTORY>
\ No newline at end of file
Added: gate/branches/sawdust2/plugins/Schema_Annotation_Editor/pom.xml
===================================================================
--- gate/branches/sawdust2/plugins/Schema_Annotation_Editor/pom.xml
(rev 0)
+++ gate/branches/sawdust2/plugins/Schema_Annotation_Editor/pom.xml
2016-11-25 12:55:26 UTC (rev 19799)
@@ -0,0 +1,38 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>uk.ac.gate.plugins</groupId>
+ <artifactId>base-plugin</artifactId>
+ <!-- this should be the version of GATE you wish to build
against -->
+ <version>9.0-SNAPSHOT</version>
+ <relativePath>../../Plugin_Base/pom.xml</relativePath>
+ </parent>
+
+ <!-- this is the description of this plugin -->
+ <groupId>uk.ac.gate.plugins</groupId>
+ <artifactId>schema-annotation-editor</artifactId>
+ <version>9.0-SNAPSHOT</version>
+
+ <licenses>
+ <license>
+ <name>GNU Lesser General Public License (LGPL), Version
3</name>
+ <url>http://www.gnu.org/licenses/lgpl-3.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <organization>
+ <name>GATE</name>
+ <url>http://gate.ac.uk</url>
+ </organization>
+
+ <dependencies>
+ <!-- add any other libraries your plugin depends on. Any other
GATE plugins
+ you depend on at compile time should use the provided
scope -->
+ </dependencies>
+
+</project>
Copied:
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
(from rev 19798,
gate/branches/sawdust2/gate-core/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java)
===================================================================
---
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
(rev 0)
+++
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/java/gate/gui/annedit/SchemaAnnotationEditor.java
2016-11-25 12:55:26 UTC (rev 19799)
@@ -0,0 +1,1308 @@
+/*
+ * Copyright (c) 1995-2012, The University of Sheffield. See the file
+ * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
+ *
+ * This file is part of GATE (see http://gate.ac.uk/), and is free software,
+ * licenced under the GNU Library General Public License, Version 2, June 1991
+ * (in the distribution as file licence.html, and also available at
+ * http://gate.ac.uk/gate/licence.html).
+ *
+ * AnnotationEditor.java
+ *
+ * Valentin Tablan, Sep 10, 2007
+ *
+ * $Id$
+ */
+package gate.gui.annedit;
+
+import gate.Annotation;
+import gate.AnnotationSet;
+import gate.Factory;
+import gate.FeatureMap;
+import gate.Gate;
+import gate.LanguageResource;
+import gate.Resource;
+import gate.creole.AbstractVisualResource;
+import gate.creole.AnnotationSchema;
+import gate.creole.FeatureSchema;
+import gate.creole.ResourceInstantiationException;
+import gate.creole.metadata.CreoleResource;
+import gate.event.CreoleEvent;
+import gate.event.CreoleListener;
+import gate.gui.MainFrame;
+import gate.swing.JChoice;
+import gate.util.GateException;
+import gate.util.GateRuntimeException;
+import gate.util.InvalidOffsetException;
+import gate.util.LuckyException;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Container;
+import java.awt.Dialog;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.HeadlessException;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.Icon;
+import javax.swing.InputMap;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JToggleButton;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.border.Border;
+import javax.swing.event.AncestorEvent;
+import javax.swing.event.AncestorListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+
+/**
+ * An annotation editor that enforces the annotation schemas currently loaded
in
+ * the system. Once the editing of an annotation is started, it cannot be
+ * completed until the annotation complies with the schema for that annotation
+ * type.
+ */
+@SuppressWarnings("serial")
+@CreoleResource(name = "Schema Annotations Editor", comment="An annotation
editor restricted by schemas.",
helpURL="http://gate.ac.uk/userguide/sec:corpora:schemas")
+public class SchemaAnnotationEditor extends AbstractVisualResource implements
+
OwnedAnnotationEditor {
+
+ @Override
+ public void editAnnotation(Annotation ann, AnnotationSet set) {
+ // the external components we listen to (the text and the list view) can
+ // change outside of our control, so we need to update the values
frequently
+ updateListeners();
+ this.annotation = ann;
+ this.annSet = set;
+ // update the selection in the list view
+ // this is necessary because sometimes the call to eidtAnnotaiton is
+ // internally received from the search and annotate function.
+ // update the editor display
+ String annType = annotation == null ? null : annotation.getType();
+ // update the border for the types choice
+ if(annType == null) {
+ // no annotation -> ok
+ if(typesChoice.getBorder() != typeDefaultBorder)
+ typesChoice.setBorder(typeDefaultBorder);
+ } else {
+ if(schemasByType.containsKey(annType)) {
+ // accepted type
+ if(typesChoice.getBorder() != typeDefaultBorder)
+ typesChoice.setBorder(typeDefaultBorder);
+ } else {
+ // wrong type
+ if(typesChoice.getBorder() != typeHighlightBorder)
+ typesChoice.setBorder(typeHighlightBorder);
+ }
+ }
+ // update the features editor
+ SchemaFeaturesEditor newFeaturesEditor = featureEditorsByType.get(annType);
+ // if new type, we need to change the features editor and selected type
+ // button
+ if(newFeaturesEditor != featuresEditor) {
+ typesChoice.setSelectedItem(annType);
+ if(featuresEditor != null) {
+ featuresBox.remove(featuresEditor);
+ featuresEditor.editFeatureMap(null);
+ }
+ featuresEditor = newFeaturesEditor;
+ if(featuresEditor != null) {
+ featuresBox.add(featuresEditor);
+ }
+ }
+ if(featuresEditor != null) {
+ FeatureMap features = ann.getFeatures();
+ if(features == null) {
+ features = Factory.newFeatureMap();
+ ann.setFeatures(features);
+ }
+ featuresEditor.editFeatureMap(features);
+ }
+ // enable editing if there is an annotation, disable if not
+ setEditingEnabled(annType != null);
+ if(dialog != null) {
+ if(annotation != null) {
+ placeDialog(annotation.getStartNode().getOffset().intValue(),
+ annotation.getEndNode().getOffset().intValue());
+ } else {
+ // this should only occur when the dialog is pinned, so offsets are
+ // irrelevant
+ placeDialog(0, 0);
+ }
+ }
+ }
+
+ /**
+ * This editor implementation is designed to enforce schema compliance. This
+ * method will return <tt>false</tt> if the current annotation type does not
+ * have a schema or if the features of the current annotation do not comply
+ * with the schema.
+ *
+ * @see gate.gui.annedit.OwnedAnnotationEditor#editingFinished()
+ */
+ @Override
+ public boolean editingFinished() {
+ if(annotation == null) return true;
+ // if the dialog is hidden, we've missed the train and we can't force
+ // compliance for the old annotation any more. Just give up and
+ // allow further editing
+ if(!dialog.isVisible()) return true;
+ if(!schemasByType.containsKey(annotation.getType())) return false;
+ // we need to check that:
+ // 1) all required features have values
+ // 2) all features known by schema that have values, comply with the schema
+
+ AnnotationSchema aSchema = schemasByType.get(annotation.getType());
+ if(aSchema.getFeatureSchemaSet() == null
+ || aSchema.getFeatureSchemaSet().isEmpty()) {
+ // known type but no schema restrictions -> OK
+ return true;
+ }
+ FeatureMap annotationFeatures = annotation.getFeatures();
+ Map<String, FeatureSchema> featureSchemaByName =
+ new HashMap<String, FeatureSchema>();
+ // store all the feature schemas, and check the required ones
+ for(FeatureSchema aFeatureSchema : aSchema.getFeatureSchemaSet()) {
+ featureSchemaByName.put(aFeatureSchema.getFeatureName(), aFeatureSchema);
+ Object featureValue =
+ annotationFeatures == null ? null : annotationFeatures
+ .get(aFeatureSchema.getFeatureName());
+ if(aFeatureSchema.isRequired() && featureValue == null) return false;
+ }
+ // check all the actual values for compliance
+ for(Object featureName : annotationFeatures.keySet()) {
+ Object featureValue = annotationFeatures.get(featureName);
+ FeatureSchema fSchema = featureSchemaByName.get(featureName);
+ if(fSchema != null) {
+ // this is a schema feature
+ if(fSchema.getFeatureValueClass().equals(Boolean.class)
+ || fSchema.getFeatureValueClass().equals(Integer.class)
+ || fSchema.getFeatureValueClass().equals(Short.class)
+ || fSchema.getFeatureValueClass().equals(Byte.class)
+ || fSchema.getFeatureValueClass().equals(Float.class)
+ || fSchema.getFeatureValueClass().equals(Double.class)) {
+ if(featureValue instanceof String) {
+ // try to convert numbers
+ try {
+ if (fSchema.getFeatureValueClass().equals(Integer.class)) {
+ featureValue = Integer.valueOf((String) featureValue);
+ } else if (fSchema.getFeatureValueClass().equals(Short.class)) {
+ featureValue = Short.valueOf((String) featureValue);
+ } else if (fSchema.getFeatureValueClass().equals(Byte.class)) {
+ featureValue = Byte.valueOf((String) featureValue);
+ } else if (fSchema.getFeatureValueClass().equals(Double.class)) {
+ featureValue = Double.valueOf((String) featureValue);
+ } else if (fSchema.getFeatureValueClass().equals(Float.class)) {
+ featureValue = Float.valueOf((String) featureValue);
+ }
+ annotationFeatures.put(featureName, featureValue);
+ } catch (NumberFormatException e) {
+ // could not convert
+ return false;
+ }
+ } else if(!fSchema.getFeatureValueClass().isAssignableFrom(
+ featureValue.getClass())) {
+ // not a String, nor the exact correct class: invalid value type
+ return false;
+ }
+ } else if(fSchema.getFeatureValueClass().equals(String.class)) {
+ if(fSchema.getPermittedValues() != null
+ && !fSchema.getPermittedValues().contains(featureValue)) {
+ // invalid value
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Does nothing, as this editor does not support cancelling and rollbacks.
+ */
+ @Override
+ public void cancelAction() throws GateException {
+ }
+
+ /**
+ * Returns <tt>true</tt> always as this editor is generic and can edit any
+ * annotation type.
+ */
+ @Override
+ public boolean canDisplayAnnotationType(String annotationType) {
+ return true;
+ }
+
+ /**
+ * Does nothing as this editor works in auto-commit mode (changes are
+ * implemented immediately).
+ */
+ @Override
+ public void okAction() throws GateException {
+ }
+
+ /**
+ * Returns <tt>false</tt>, as this editor does not support cancel operations.
+ */
+ @Override
+ public boolean supportsCancel() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see gate.gui.annedit.AnnotationEditor#isActive()
+ */
+ @Override
+ public boolean isActive() {
+ return dialog.isVisible();
+ }
+
+ /**
+ * Finds the best location for the editor dialog for a given span of text
+ */
+ @Override
+ public void placeDialog(int start, int end) {
+ if(pinnedButton.isSelected()) {
+ // just resize
+ Point where = null;
+ if(dialog.isVisible()) {
+ // where = dialog.getLocationOnScreen();
+ where = dialog.getLocation();
+ }
+ dialog.pack();
+ if(where != null) {
+ dialogLocation.move(where.x, where.y);
+ dialog.setLocation(dialogLocation);
+ }
+ } else {
+ // calculate position
+ try {
+ Rectangle startRect = owner.getTextComponent().modelToView(start);
+ Rectangle endRect = owner.getTextComponent().modelToView(end);
+ Point topLeft = owner.getTextComponent().getLocationOnScreen();
+ int x = topLeft.x + startRect.x;
+ int y = topLeft.y + endRect.y + endRect.height;
+ // make sure the window doesn't start lower
+ // than the end of the visible rectangle
+ Rectangle visRect = owner.getTextComponent().getVisibleRect();
+ int maxY = topLeft.y + visRect.y + visRect.height;
+ // make sure window doesn't get off-screen
+ dialog.pack();
+ // responding to changed orientation
+ if(currentOrientation == ComponentOrientation.RIGHT_TO_LEFT) {
+ x = x - dialog.getSize().width;
+ if(x < 0) x = 0;
+ }
+ // dialog.validate();
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ boolean revalidate = false;
+ if(dialog.getSize().width > screenSize.width) {
+ dialog.setSize(screenSize.width, dialog.getSize().height);
+ revalidate = true;
+ }
+ if(dialog.getSize().height > screenSize.height) {
+ dialog.setSize(dialog.getSize().width, screenSize.height);
+ revalidate = true;
+ }
+ if(revalidate) dialog.validate();
+ // calculate max X
+ int maxX = screenSize.width - dialog.getSize().width;
+ // calculate max Y
+ if(maxY + dialog.getSize().height > screenSize.height) {
+ maxY = screenSize.height - dialog.getSize().height;
+ }
+ // correct position
+ if(y > maxY) y = maxY;
+ if(x > maxX) x = maxX;
+ dialogLocation.move(x, y);
+ dialog.setLocation(dialogLocation);
+ } catch(BadLocationException ble) {
+ // this should never occur
+ throw new GateRuntimeException(ble);
+ }
+ }
+ if(!dialog.isVisible()) dialog.setVisible(true);
+ }
+
+ protected static final int HIDE_DELAY = 1500;
+
+ protected static final int SHIFT_INCREMENT = 5;
+
+ protected static final int CTRL_SHIFT_INCREMENT = 10;
+
+ /**
+ * The annotation currently being edited.
+ */
+ protected Annotation annotation;
+
+ /**
+ * The annotation set containing the currently edited annotation.
+ */
+ protected AnnotationSet annSet;
+
+ /**
+ * The controlling object for this editor.
+ */
+ private AnnotationEditorOwner owner;
+
+ /**
+ * The text component (obtained from the owner) that this editor listens to.
+ */
+ private JTextComponent textComponent;
+
+ /**
+ * JChoice used for selecting the annotation type.
+ */
+ protected JChoice<String> typesChoice;
+
+ /**
+ * The default border for the types choice
+ */
+ protected Border typeDefaultBorder;
+
+ /**
+ * The highlight border for the types choice
+ */
+ protected Border typeHighlightBorder;
+
+ /**
+ * The dialog used to show this annotation editor.
+ */
+ protected JDialog dialog;
+
+ protected CreoleListener creoleListener;
+
+ /**
+ * Listener used to hide the editing window when the text is hidden.
+ */
+ protected AncestorListener textAncestorListener;
+
+ /**
+ * Stores the Annotation schema objects available in the system. The
+ * annotation types are used as keys for the map.
+ */
+ protected Map<String, AnnotationSchema> schemasByType;
+
+ /**
+ * Caches the features editor for each annotation type.
+ */
+ protected Map<String, SchemaFeaturesEditor> featureEditorsByType;
+
+ /**
+ * The box used to host the features editor pane.
+ */
+ protected Box featuresBox;
+
+ /**
+ * Toggle button used to pin down the dialog.
+ */
+ protected JToggleButton pinnedButton;
+
+ /**
+ * The current features editor, one of the ones stored in
+ * {@link #featureEditorsByType}.
+ */
+ protected SchemaFeaturesEditor featuresEditor = null;
+
+ protected MouseEvent pressed;
+
+ public SchemaAnnotationEditor() {
+ initData();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see gate.creole.AbstractVisualResource#init()
+ */
+ @Override
+ public Resource init() throws ResourceInstantiationException {
+ super.init();
+ initGui();
+ initListeners();
+ return this;
+ }
+
+ protected void updateListeners() {
+ if(owner != null) {
+ // we have a new owner
+ // if the components that we listen to have changed, we need to update
the
+ // listeners
+ if(textComponent != getOwner().getTextComponent()) {
+ // remove old listener
+ if(textComponent != null) {
+ textComponent.removeAncestorListener(textAncestorListener);
+ }
+ this.textComponent = owner.getTextComponent();
+ // register new listener
+ if(textComponent != null) {
+ textComponent.addAncestorListener(textAncestorListener);
+ }
+ }
+ } else {
+ // no new owner -> just remove old listeners
+ if(textComponent != null) {
+ textComponent.removeAncestorListener(textAncestorListener);
+ }
+ }
+ }
+
+ protected void initData() {
+ schemasByType = new TreeMap<String, AnnotationSchema>();
+ for(LanguageResource aSchema : Gate.getCreoleRegister().getLrInstances(
+ "gate.creole.AnnotationSchema")) {
+ schemasByType.put(((AnnotationSchema)aSchema).getAnnotationName(),
+ (AnnotationSchema)aSchema);
+ }
+ creoleListener = new CreoleListener() {
+ @Override
+ public void resourceLoaded(CreoleEvent e) {
+ Resource newResource = e.getResource();
+ if(newResource instanceof AnnotationSchema) {
+ AnnotationSchema aSchema = (AnnotationSchema)newResource;
+ schemasByType.put(aSchema.getAnnotationName(), aSchema);
+ }
+ }
+
+ @Override
+ public void resourceUnloaded(CreoleEvent e) {
+ Resource newResource = e.getResource();
+ if(newResource instanceof AnnotationSchema) {
+ AnnotationSchema aSchema = (AnnotationSchema)newResource;
+ if(schemasByType.containsValue(aSchema)) {
+ schemasByType.remove(aSchema.getAnnotationName());
+ }
+ }
+ }
+
+ @Override
+ public void datastoreOpened(CreoleEvent e) {
+ }
+
+ @Override
+ public void datastoreCreated(CreoleEvent e) {
+ }
+
+ @Override
+ public void datastoreClosed(CreoleEvent e) {
+ }
+
+ @Override
+ public void resourceRenamed(Resource resource, String oldName,
+ String newName) {
+ }
+ };
+ Gate.getCreoleRegister().addCreoleListener(creoleListener);
+ textAncestorListener = new AncestorListener() {
+ /**
+ * A flag used to mark the fact that the dialog is active and was hidden
+ * by this listener.
+ */
+ private boolean dialogActive = false;
+
+ @Override
+ public void ancestorAdded(AncestorEvent event) {
+ if(dialogActive) {
+ if(annotation != null) {
+ placeDialog(annotation.getStartNode().getOffset().intValue(),
+ annotation.getEndNode().getOffset().intValue());
+ }
+ dialogActive = false;
+ }
+ }
+
+ @Override
+ public void ancestorMoved(AncestorEvent event) {
+ if(dialog.isVisible() && annotation != null) {
+ placeDialog(annotation.getStartNode().getOffset().intValue(),
+ annotation.getEndNode().getOffset().intValue());
+ }
+ }
+
+ @Override
+ public void ancestorRemoved(AncestorEvent event) {
+ if(dialog.isVisible()) {
+ dialogActive = true;
+ dialog.setVisible(false);
+ }
+ }
+ };
+ }
+
+ @Override
+ public void cleanup() {
+ Gate.getCreoleRegister().removeCreoleListener(creoleListener);
+ }
+
+ protected void initGui() {
+ // make the dialog
+ Window parentWindow =
+ SwingUtilities.windowForComponent(owner.getTextComponent());
+ if(parentWindow != null) {
+ dialog =
+ parentWindow instanceof Frame ? new JDialog((Frame)parentWindow,
+ "Annotation Editor Dialog", false) : new JDialog(
+ (Dialog)parentWindow, "Annotation Editor Dialog", false);
+ dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+ MainFrame.getGuiRoots().add(dialog);
+ }
+ setLayout(new BorderLayout());
+ // build the toolbar
+ JPanel tBar = new JPanel();
+ tBar.setLayout(new GridBagLayout());
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.gridx = GridBagConstraints.RELATIVE;
+ constraints.gridy = 0;
+ constraints.weightx = 0;
+ solButton = new IconOnlyButton(null);
+ solButton.setIcon(MainFrame.getIcon("bounds-sol"));
+ solButton.setPressedIcon(MainFrame.getIcon("bounds-sol-pressed"));
+ tBar.add(solButton, constraints);
+ JLabel aLabel = new JLabel(MainFrame.getIcon("bounds-left"));
+ aLabel.setBorder(null);
+ tBar.add(aLabel, constraints);
+ sorButton = new IconOnlyButton(null);
+ sorButton.setIcon(MainFrame.getIcon("bounds-sor"));
+ sorButton.setPressedIcon(MainFrame.getIcon("bounds-sor-pressed"));
+ tBar.add(sorButton, constraints);
+ aLabel = new JLabel(MainFrame.getIcon("bounds-span"));
+ aLabel.setBorder(null);
+ tBar.add(aLabel, constraints);
+ eolButton = new IconOnlyButton(null);
+ eolButton.setIcon(MainFrame.getIcon("bounds-eol"));
+ eolButton.setPressedIcon(MainFrame.getIcon("bounds-eol-pressed"));
+ tBar.add(eolButton, constraints);
+ aLabel = new JLabel(MainFrame.getIcon("bounds-right"));
+ aLabel.setBorder(null);
+ tBar.add(aLabel, constraints);
+ eorButton = new IconOnlyButton(null);
+ eorButton.setIcon(MainFrame.getIcon("bounds-eor"));
+ eorButton.setPressedIcon(MainFrame.getIcon("bounds-eor-pressed"));
+ tBar.add(eorButton, constraints);
+ tBar.add(Box.createHorizontalStrut(15), constraints);
+ tBar.add(delButton = new SmallButton(null), constraints);
+ constraints.weightx = 1;
+ tBar.add(Box.createHorizontalGlue(), constraints);
+ constraints.weightx = 0;
+ pinnedButton = new JToggleButton(MainFrame.getIcon("pin"));
+ pinnedButton.setSelectedIcon(MainFrame.getIcon("pin-in"));
+ pinnedButton.setSelected(false);
+ pinnedButton.setToolTipText("Press to pin window in place.");
+ pinnedButton.setMargin(new Insets(0, 2, 0, 2));
+ pinnedButton.setBorderPainted(false);
+ pinnedButton.setContentAreaFilled(false);
+ tBar.add(pinnedButton);
+ add(tBar, BorderLayout.NORTH);
+ // build the main pane
+ mainPane = new JPanel();
+ mainPane.setLayout(new BorderLayout());
+ featureEditorsByType = new HashMap<String, SchemaFeaturesEditor>();
+ // for each schema we need to create a type button and a features editor
+ for(String annType : schemasByType.keySet()) {
+ AnnotationSchema annSchema = schemasByType.get(annType);
+ SchemaFeaturesEditor aFeaturesEditor =
+ new SchemaFeaturesEditor(annSchema);
+ featureEditorsByType.put(annType, aFeaturesEditor);
+ }
+ List<String> typeList = new ArrayList<String>(schemasByType.keySet());
+ Collections.sort(typeList);
+ String[] typesArray = new String[typeList.size()];
+ typeList.toArray(typesArray);
+ typesChoice = new JChoice<String>(typesArray);
+ typesChoice.setDefaultButtonMargin(new Insets(0, 2, 0, 2));
+ typesChoice.setMaximumFastChoices(20);
+ typesChoice.setMaximumWidth(300);
+ String aTitle = "Type ";
+ Border titleBorder = BorderFactory.createTitledBorder(aTitle);
+ typeDefaultBorder =
+ BorderFactory.createCompoundBorder(titleBorder,
+ BorderFactory.createEmptyBorder(2, 2, 2, 2));
+ typeHighlightBorder =
+ BorderFactory.createCompoundBorder(titleBorder,
+ BorderFactory.createLineBorder(Color.RED, 2));
+ typesChoice.setBorder(typeDefaultBorder);
+ aLabel = new JLabel(aTitle);
+ typesChoice
+ .setMinimumSize(new Dimension(aLabel.getPreferredSize().width, 0));
+ mainPane.add(typesChoice, BorderLayout.NORTH);
+ // add the features box
+ featuresBox = Box.createVerticalBox();
+ aTitle = "Features ";
+ featuresBox.setBorder(BorderFactory.createTitledBorder(aTitle));
+ aLabel = new JLabel(aTitle);
+ mainPane.add(featuresBox, BorderLayout.SOUTH);
+ add(mainPane, BorderLayout.CENTER);
+ // add the search and annotate GUI at the bottom of the annotator editor
+ SearchAndAnnotatePanel searchPanel =
+ new SearchAndAnnotatePanel(mainPane.getBackground(), this, dialog);
+ add(searchPanel, BorderLayout.SOUTH);
+ dialog.add(this);
+ dialog.pack();
+ }
+
+ protected void initListeners() {
+ typesChoice.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String newType;
+ if(typesChoice.getSelectedItem() == null) {
+ newType = "";
+ } else {
+ newType = typesChoice.getSelectedItem().toString();
+ }
+ if(annotation != null && annSet != null
+ && !annotation.getType().equals(newType)) {
+ // annotation type change
+ Integer oldId = annotation.getId();
+ Annotation oldAnn = annotation;
+ annSet.remove(oldAnn);
+ try {
+ annSet.add(oldId, oldAnn.getStartNode().getOffset(), oldAnn
+ .getEndNode().getOffset(), newType, oldAnn.getFeatures());
+ Annotation newAnn = annSet.get(oldId);
+ // update the selection to the new annotation
+ getOwner().selectAnnotation(new AnnotationDataImpl(annSet,
newAnn));
+ editAnnotation(newAnn, annSet);
+ owner.annotationChanged(newAnn, annSet, oldAnn.getType());
+ } catch(InvalidOffsetException ioe) {
+ // this should never happen
+ throw new LuckyException(ioe);
+ }
+ }
+ }
+ });
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ if(editingFinished()) {
+ // we can close
+ dialog.setVisible(false);
+ if(pinnedButton.isSelected()) pinnedButton.setSelected(false);
+ } else {
+ // let's be really snotty
+ getToolkit().beep();
+ }
+ }
+ });
+ dialog.getRootPane().addMouseListener(new MouseAdapter() {
+ // allow dialog to be dragged with a mouse
+ @Override
+ public void mousePressed(MouseEvent me) {
+ pressed = me;
+ }
+ });
+ dialog.getRootPane().addMouseMotionListener(new MouseMotionAdapter() {
+ Point location;
+
+ // allow a dialog to be dragged with a mouse
+ @Override
+ public void mouseDragged(MouseEvent me) {
+ location = dialog.getLocation(location);
+ int x = location.x - pressed.getX() + me.getX();
+ int y = location.y - pressed.getY() + me.getY();
+ dialog.setLocation(x, y);
+ pinnedButton.setSelected(true);
+ }
+ });
+ dialog.addComponentListener(new ComponentAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.awt.event.ComponentAdapter#componentMoved(java.awt.event.
+ * ComponentEvent)
+ */
+ @Override
+ public void componentMoved(ComponentEvent e) {
+ Point newLocation = dialog.getLocation();
+ if(!newLocation.equals(dialogLocation)) {
+ pinnedButton.setSelected(true);
+ }
+ }
+ });
+ InputMap inputMap =
+ ((JComponent)dialog.getContentPane())
+ .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ actionMap = ((JComponent)dialog.getContentPane()).getActionMap();
+ // add the key-action bindings of this Component to the parent window
+ solAction =
+ new StartOffsetLeftAction("", MainFrame.getIcon("extend-left"),
+ SOL_DESC, KeyEvent.VK_LEFT);
+ solButton.setAction(solAction);
+ setShortCuts(inputMap, SOL_KEY_STROKES, "solAction");
+ actionMap.put("solAction", solAction);
+ sorAction =
+ new StartOffsetRightAction("", MainFrame.getIcon("extend-right"),
+ SOR_DESC, KeyEvent.VK_RIGHT);
+ sorButton.setAction(sorAction);
+ setShortCuts(inputMap, SOR_KEY_STROKES, "sorAction");
+ actionMap.put("sorAction", sorAction);
+ delAction =
+ new DeleteAnnotationAction("", MainFrame.getIcon("remove-annotation"),
+ "Delete the annotation", KeyEvent.VK_DELETE);
+ delButton.setAction(delAction);
+ inputMap.put(KeyStroke.getKeyStroke("alt DELETE"), "delAction");
+ actionMap.put("delAction", delAction);
+ eolAction =
+ new EndOffsetLeftAction("", MainFrame.getIcon("extend-left"), EOL_DESC,
+ KeyEvent.VK_LEFT);
+ eolButton.setAction(eolAction);
+ setShortCuts(inputMap, EOL_KEY_STROKES, "eolAction");
+ actionMap.put("eolAction", eolAction);
+ eorAction =
+ new EndOffsetRightAction("", MainFrame.getIcon("extend-right"),
+ EOR_DESC, KeyEvent.VK_RIGHT);
+ eorButton.setAction(eorAction);
+ setShortCuts(inputMap, EOR_KEY_STROKES, "eorAction");
+ actionMap.put("eorAction", eorAction);
+ Action dismissAction = new AbstractAction() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ dialog.setVisible(false);
+ }
+ };
+ inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "dismissAction");
+ actionMap.put("dismissAction", dismissAction);
+ }
+
+ /**
+ * Stores the currently set dialog location (which is used to identify cases
+ * when the dialog was moved by hand, which causes the dialog to be pinned).
+ */
+ private Point dialogLocation = new Point(0, 0);
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ try {
+ Gate.init();
+ JFrame aFrame = new JFrame("New Annotation Editor");
+ aFrame.setSize(800, 600);
+ aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ JDialog annDialog =
+ new JDialog(aFrame, "Annotation Editor Dialog", false);
+ annDialog.setFocusableWindowState(false);
+ // annDialog.setResizable(false);
+ // annDialog.setUndecorated(true);
+ SchemaAnnotationEditor pane = new SchemaAnnotationEditor();
+ annDialog.add(pane);
+ annDialog.pack();
+ // JToolBar tBar = new JToolBar("Annotation Editor",
JToolBar.HORIZONTAL);
+ // tBar.setLayout(new BorderLayout());
+ // tBar.setMinimumSize(tBar.getPreferredSize());
+ // tBar.add(pane);
+ // aFrame.getContentPane().add(tBar, BorderLayout.NORTH);
+ StringBuffer strBuf = new StringBuffer();
+ for(int i = 0; i < 100; i++) {
+ strBuf.append("The quick brown fox jumped over the lazy dog.\n");
+ }
+ JTextArea aTextPane = new JTextArea(strBuf.toString());
+ JScrollPane scroller = new JScrollPane(aTextPane);
+ aFrame.getContentPane().add(scroller, BorderLayout.CENTER);
+ // Box aBox = Box.createVerticalBox();
+ // aFrame.getContentPane().add(aBox);
+ //
+ // FeatureEditor aFeatEditor = new FeatureEditor("F-nominal-small",
+ // FeatureType.nominal, "val1");
+ // aFeatEditor.setValues(new String[]{"val1", "val2", "val3"});
+ // aBox.add(aFeatEditor.getGui());
+ //
+ // aFeatEditor = new FeatureEditor("F-nominal-large",
+ // FeatureType.nominal, "val1");
+ // aFeatEditor.setValues(new String[]{"val1", "val2", "val3", "val4",
+ // "val5",
+ // "val6", "val7", "val8", "val9"});
+ // aBox.add(aFeatEditor.getGui());
+ //
+ // aFeatEditor = new FeatureEditor("F-boolean-true",
+ // FeatureType.bool, "true");
+ // aBox.add(aFeatEditor.getGui());
+ //
+ // aFeatEditor = new FeatureEditor("F-boolean-false",
+ // FeatureType.bool, "false");
+ // aBox.add(aFeatEditor.getGui());
+ aFrame.setVisible(true);
+ System.out.println("Window up");
+ annDialog.setVisible(true);
+ System.out.println("Dialog up");
+ } catch(HeadlessException e) {
+ e.printStackTrace();
+ } catch(GateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Base class for actions on annotations.
+ */
+ protected abstract class AnnotationAction extends AbstractAction {
+ public AnnotationAction(String text, Icon icon, String desc, int mnemonic)
{
+ super(text, icon);
+ putValue(SHORT_DESCRIPTION, desc);
+ putValue(MNEMONIC_KEY, mnemonic);
+ }
+ }
+
+ protected class StartOffsetLeftAction extends AnnotationAction {
+ private static final long serialVersionUID = 1L;
+
+ public StartOffsetLeftAction(String text, Icon icon, String desc,
+ int mnemonic) {
+ super(text, icon, desc, mnemonic);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ int increment = 1;
+ if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
+ // CTRL pressed -> use tokens for advancing
+ increment = SHIFT_INCREMENT;
+ if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
+ increment = CTRL_SHIFT_INCREMENT;
+ }
+ }
+ long newValue =
+ annotation.getStartNode().getOffset().longValue() - increment;
+ if(newValue < 0) newValue = 0;
+ try {
+ moveAnnotation(annSet, annotation, new Long(newValue), annotation
+ .getEndNode().getOffset());
+ } catch(InvalidOffsetException ioe) {
+ throw new GateRuntimeException(ioe);
+ }
+ }
+ }
+
+ protected class StartOffsetRightAction extends AnnotationAction {
+ private static final long serialVersionUID = 1L;
+
+ public StartOffsetRightAction(String text, Icon icon, String desc,
+ int mnemonic) {
+ super(text, icon, desc, mnemonic);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ long endOffset = annotation.getEndNode().getOffset().longValue();
+ int increment = 1;
+ if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
+ // CTRL pressed -> use tokens for advancing
+ increment = SHIFT_INCREMENT;
+ if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
+ increment = CTRL_SHIFT_INCREMENT;
+ }
+ }
+ long newValue =
+ annotation.getStartNode().getOffset().longValue() + increment;
+ if(newValue > endOffset) newValue = endOffset;
+ try {
+ moveAnnotation(annSet, annotation, new Long(newValue), annotation
+ .getEndNode().getOffset());
+ } catch(InvalidOffsetException ioe) {
+ throw new GateRuntimeException(ioe);
+ }
+ }
+ }
+
+ protected class EndOffsetLeftAction extends AnnotationAction {
+ private static final long serialVersionUID = 1L;
+
+ public EndOffsetLeftAction(String text, Icon icon, String desc, int
mnemonic) {
+ super(text, icon, desc, mnemonic);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ long startOffset = annotation.getStartNode().getOffset().longValue();
+ int increment = 1;
+ if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
+ // CTRL pressed -> use tokens for advancing
+ increment = SHIFT_INCREMENT;
+ if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
+ increment = CTRL_SHIFT_INCREMENT;
+ }
+ }
+ long newValue =
+ annotation.getEndNode().getOffset().longValue() - increment;
+ if(newValue < startOffset) newValue = startOffset;
+ try {
+ moveAnnotation(annSet, annotation, annotation.getStartNode()
+ .getOffset(), new Long(newValue));
+ } catch(InvalidOffsetException ioe) {
+ throw new GateRuntimeException(ioe);
+ }
+ }
+ }
+
+ protected class EndOffsetRightAction extends AnnotationAction {
+ private static final long serialVersionUID = 1L;
+
+ public EndOffsetRightAction(String text, Icon icon, String desc,
+ int mnemonic) {
+ super(text, icon, desc, mnemonic);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ long maxOffset = owner.getDocument().getContent().size().longValue() - 1;
+ int increment = 1;
+ if((evt.getModifiers() & ActionEvent.SHIFT_MASK) > 0) {
+ // CTRL pressed -> use tokens for advancing
+ increment = SHIFT_INCREMENT;
+ if((evt.getModifiers() & ActionEvent.CTRL_MASK) > 0) {
+ increment = CTRL_SHIFT_INCREMENT;
+ }
+ }
+ long newValue =
+ annotation.getEndNode().getOffset().longValue() + increment;
+ if(newValue > maxOffset) newValue = maxOffset;
+ try {
+ moveAnnotation(annSet, annotation, annotation.getStartNode()
+ .getOffset(), new Long(newValue));
+ } catch(InvalidOffsetException ioe) {
+ throw new GateRuntimeException(ioe);
+ }
+ }
+ }
+
+ protected class DeleteAnnotationAction extends AnnotationAction {
+ private static final long serialVersionUID = 1L;
+
+ public DeleteAnnotationAction(String text, Icon icon, String desc,
+ int mnemonic) {
+ super(text, icon, desc, mnemonic);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ annSet.remove(annotation);
+ // clear the dialog
+ editAnnotation(null, annSet);
+ if(!pinnedButton.isSelected()) {
+ // if not pinned, hide the dialog.
+ dialog.setVisible(false);
+ } else {
+ setEditingEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * Changes the span of an existing annotation by creating a new annotation
+ * with the same ID, type and features but with the new start and end
offsets.
+ *
+ * @param set
+ * the annotation set
+ * @param oldAnnotation
+ * the annotation to be moved
+ * @param newStartOffset
+ * the new start offset
+ * @param newEndOffset
+ * the new end offset
+ */
+ protected void moveAnnotation(AnnotationSet set, Annotation oldAnnotation,
+ Long newStartOffset, Long newEndOffset) throws InvalidOffsetException {
+ // Moving is done by deleting the old annotation and creating a new one.
+ // If this was the last one of one type it would mess up the gui which
+ // "forgets" about this type and then it recreates it (with a different
+ // colour and not visible.
+ // In order to avoid this problem, we'll create a new temporary annotation.
+ Annotation tempAnn = null;
+ if(set.get(oldAnnotation.getType()).size() == 1) {
+ // create a clone of the annotation that will be deleted, to act as a
+ // placeholder
+ Integer tempAnnId =
+ set.add(oldAnnotation.getStartNode(), oldAnnotation.getStartNode(),
+ oldAnnotation.getType(), oldAnnotation.getFeatures());
+ tempAnn = set.get(tempAnnId);
+ }
+ Integer oldID = oldAnnotation.getId();
+ set.remove(oldAnnotation);
+ set.add(oldID, newStartOffset, newEndOffset, oldAnnotation.getType(),
+ oldAnnotation.getFeatures());
+ Annotation newAnn = set.get(oldID);
+ // update the selection to the new annotation
+ getOwner().selectAnnotation(new AnnotationDataImpl(set, newAnn));
+ editAnnotation(newAnn, set);
+ // remove the temporary annotation
+ if(tempAnn != null) set.remove(tempAnn);
+ owner.annotationChanged(newAnn, set, null);
+ }
+
+ /**
+ * A JButton with content are not filled and border not painted (in order to
+ * save screen real estate)
+ */
+ protected class SmallButton extends JButton {
+ private static final long serialVersionUID = 1L;
+
+ public SmallButton(Action a) {
+ super(a);
+ // setBorder(null);
+ setMargin(new Insets(0, 2, 0, 2));
+ // setBorderPainted(false);
+ // setContentAreaFilled(false);
+ }
+ }
+
+ protected class IconOnlyButton extends JButton {
+ private static final long serialVersionUID = 1L;
+
+ public IconOnlyButton(Action a) {
+ super(a);
+ setMargin(new Insets(0, 0, 0, 0));
+ setBorder(null);
+ setBorderPainted(false);
+ setContentAreaFilled(false);
+ }
+ }
+
+ protected IconOnlyButton solButton;
+
+ protected IconOnlyButton sorButton;
+
+ protected SmallButton delButton;
+
+ protected IconOnlyButton eolButton;
+
+ protected IconOnlyButton eorButton;
+
+ protected JPanel mainPane;
+
+ /**
+ * Action bindings for the popup window.
+ */
+ ActionMap actionMap;
+
+ private StartOffsetLeftAction solAction;
+
+ private StartOffsetRightAction sorAction;
+
+ private DeleteAnnotationAction delAction;
+
+ private EndOffsetLeftAction eolAction;
+
+ private EndOffsetRightAction eorAction;
+
+ /**
+ * @return the owner
+ */
+ @Override
+ public AnnotationEditorOwner getOwner() {
+ return owner;
+ }
+
+ /**
+ * @param owner
+ * the owner to set
+ */
+ @Override
+ public void setOwner(AnnotationEditorOwner owner) {
+ // if the owner is new, register existing listeners to new owner elements
+ if(this.owner != owner) {
+ this.owner = owner;
+ updateListeners();
+ }
+ }
+
+ @Override
+ public AnnotationSet getAnnotationSetCurrentlyEdited() {
+ return annSet;
+ }
+
+ @Override
+ public Annotation getAnnotationCurrentlyEdited() {
+ return annotation;
+ }
+
+ @Override
+ public void setPinnedMode(boolean pinned) {
+ pinnedButton.setSelected(pinned);
+ }
+
+ @Override
+ public void setEditingEnabled(boolean isEditingEnabled) {
+ solButton.setEnabled(isEditingEnabled);
+ sorButton.setEnabled(isEditingEnabled);
+ delButton.setEnabled(isEditingEnabled);
+ eolButton.setEnabled(isEditingEnabled);
+ eorButton.setEnabled(isEditingEnabled);
+ for(Component c : typesChoice.getComponents()) {
+ c.setEnabled(isEditingEnabled);
+ }
+ // en/disable the components in the featuresBox
+ Vector<Component> components = new Vector<Component>();
+ Collections.addAll(components, featuresBox.getComponents());
+ while(!components.isEmpty()) {
+ Component component = components.remove(0);
+ if(component instanceof JToggleButton || component instanceof
JTextField) {
+ component.setEnabled(isEditingEnabled);
+ } else if(component instanceof Container) {
+ Collections.addAll(components, ((Container)component).getComponents());
+ }
+ }
+ // enable/disable the key binding actions
+ if(isEditingEnabled) {
+ actionMap.put("solAction", solAction);
+ actionMap.put("sorAction", sorAction);
+ actionMap.put("delAction", delAction);
+ actionMap.put("eolAction", eolAction);
+ actionMap.put("eorAction", eorAction);
+ } else {
+ actionMap.put("solAction", null);
+ actionMap.put("sorAction", null);
+ actionMap.put("delAction", null);
+ actionMap.put("eolAction", null);
+ actionMap.put("eorAction", null);
+ }
+ // reapply the orientation settings after editing is enabled or disabled
+ changeOrientation(currentOrientation);
+ }
+
+ @Override
+ public void changeOrientation(ComponentOrientation orientation) {
+ if(orientation == null) return;
+ // remember the current orientation
+ this.currentOrientation = orientation;
+ // input map
+ InputMap inputMap =
+ ((JComponent)dialog.getContentPane())
+ .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ Action solAction = actionMap.get("solAction");
+ Action sorAction = actionMap.get("sorAction");
+ Action eolAction = actionMap.get("eolAction");
+ Action eorAction = actionMap.get("eorAction");
+ if(orientation == ComponentOrientation.RIGHT_TO_LEFT) {
+ // in right to left orientation
+ // extending start offset is equal to extending end offset
+ solButton.setAction(eorAction);
+ solButton.setToolTipText(EOR_DESC);
+ setShortCuts(inputMap, SOL_KEY_STROKES, "eorAction");
+ solButton.setIcon(MainFrame.getIcon("extend-left"));
+ // shrinking start offset is equal to shrinking end offset
+ sorButton.setAction(eolAction);
+ sorButton.setToolTipText(EOL_DESC);
+ setShortCuts(inputMap, SOR_KEY_STROKES, "eolAction");
+ sorButton.setIcon(MainFrame.getIcon("extend-right"));
+ // shrinking end offset is equal to shrinking start offset
+ eolButton.setAction(sorAction);
+ eolButton.setToolTipText(SOR_DESC);
+ setShortCuts(inputMap, EOL_KEY_STROKES, "sorAction");
+ eolButton.setIcon(MainFrame.getIcon("extend-left"));
+ // extending end offset is extending start offset
+ eorButton.setAction(solAction);
+ eorButton.setToolTipText(SOL_DESC);
+ setShortCuts(inputMap, EOR_KEY_STROKES, "solAction");
+ eorButton.setIcon(MainFrame.getIcon("extend-right"));
+ } else {
+ solButton.setAction(solAction);
+ solButton.setToolTipText(SOL_DESC);
+ setShortCuts(inputMap, SOL_KEY_STROKES, "solAction");
+ solButton.setIcon(MainFrame.getIcon("extend-left"));
+ sorButton.setAction(sorAction);
+ sorButton.setToolTipText(SOR_DESC);
+ setShortCuts(inputMap, SOR_KEY_STROKES, "sorAction");
+ sorButton.setIcon(MainFrame.getIcon("extend-right"));
+ eolButton.setAction(eolAction);
+ eolButton.setToolTipText(EOL_DESC);
+ setShortCuts(inputMap, EOL_KEY_STROKES, "eolAction");
+ eolButton.setIcon(MainFrame.getIcon("extend-left"));
+ eorButton.setAction(eorAction);
+ eorButton.setToolTipText(EOR_DESC);
+ setShortCuts(inputMap, EOR_KEY_STROKES, "eorAction");
+ eorButton.setIcon(MainFrame.getIcon("extend-right"));
+ }
+ }
+
+ /**
+ * Utility method to set short cuts
+ *
+ * @param inputMap
+ * @param keyStrokes
+ * @param action
+ */
+ private void setShortCuts(InputMap inputMap, String[] keyStrokes,
+ String action) {
+ for(String aKeyStroke : keyStrokes) {
+ inputMap.put(KeyStroke.getKeyStroke(aKeyStroke), action);
+ }
+ }
+
+ /**
+ * current orientation set by the user
+ */
+ private ComponentOrientation currentOrientation = null;
+
+ /* various tool tips for buttons used for changing offsets */
+ private final String SOL_DESC = "<html><b>Extend start</b><small>"
+ + "<br>LEFT = 1 character" + "<br> + SHIFT = 5 characters, "
+ + "<br> + CTRL + SHIFT = 10 characters</small></html>";
+
+ private final String SOR_DESC = "<html><b>Shrink start</b><small>"
+ + "<br>RIGHT = 1 character" + "<br> + SHIFT = 5 characters, "
+ + "<br> + CTRL + SHIFT = 10 characters</small></html>";
+
+ private final String EOL_DESC = "<html><b>Shrink end</b><small>"
+ + "<br>ALT + LEFT = 1 character" + "<br> + SHIFT = 5 characters, "
+ + "<br> + CTRL + SHIFT = 10 characters</small></html>";
+
+ private final String EOR_DESC = "<html><b>Extend end</b><small>"
+ + "<br>ALT + RIGHT = 1 character" + "<br> + SHIFT = 5 characters, "
+ + "<br> + CTRL + SHIFT = 10 characters</small></html>";
+
+ /* various shortcuts we define */
+ private final String[] SOL_KEY_STROKES = new String[]{"LEFT", "shift LEFT",
+ "control shift released LEFT"};
+
+ private final String[] SOR_KEY_STROKES = new String[]{"RIGHT", "shift RIGHT",
+ "control shift released RIGHT"};
+
+ private final String[] EOL_KEY_STROKES = new String[]{"LEFT", "alt LEFT",
+ "control alt released LEFT"};
+
+ private final String[] EOR_KEY_STROKES = new String[]{"RIGHT", "alt RIGHT",
+ "control alt released RIGHT"};
+}
Copied:
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/resources/creole.xml
(from rev 19798,
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/creole.xml)
===================================================================
---
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/resources/creole.xml
(rev 0)
+++
gate/branches/sawdust2/plugins/Schema_Annotation_Editor/src/main/resources/creole.xml
2016-11-25 12:55:26 UTC (rev 19799)
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<!-- creole.xml directory file for Schema-restricted annotation editor -->
+<CREOLE-DIRECTORY>
+
+</CREOLE-DIRECTORY>
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs