Commit a56d94e9 authored by Christos Christodoulopoulos's avatar Christos Christodoulopoulos
Browse files

Version 3.23 released

Catching all exceptions and casting them to messages rather than sending them to console
Removed the annotation index (first of two numbers) from the drop-down list
Modified the context window to add an indication if an utterance doesn't have SRL
 - Created a context-to-annotation map that can be used later on
 Added '=' as a shortcut for predicate
 Added list of commonly used shortcuts in the F1 menu
 Added a bracket-verification method during tree editing
parent b9fb6854
......@@ -15,4 +15,27 @@ First, make sure the folder containing the main `jubilee.jar` file contains the
Then, in the command line, navigate to the project's folder and run:
java -jar jubilee.jar -u <USERNAME>
\ No newline at end of file
java -jar jubilee.jar -u <USERNAME>
### Keyboard shortcuts
The **Help** menu (`F1`) will provide the same list of shortcuts
#### Corpus File Actions
| Open new file | `cmd/ctrl` + `o` |
| Save current file | `cmd/ctrl` + `s` |
#### Navigation
| Next annotation | `.` |
| Previous annotation | `,` |
| Jump to annotation | `cmd/ctrl` + `j` |
#### Frameset information
| Next roleset | `]` |
| Previous roleset | `[` |
| See examples | `cmd/ctrl` + `e` |
#### Annotation/Editing
| Edit tree | `cmd/ctrl` + `t` |
| Add predicate | `=` |
| Add Arg[0-5] | `0-5` |
| Add ArgP-Gov | `x` |
| Add ArgP-Obj | `y` |
\ No newline at end of file
......@@ -7,7 +7,9 @@ import org.json.JSONObject;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The Jubilee corpus for each annotation task. It consists of a list of {@link JBDataStructure}s
......@@ -17,55 +19,58 @@ public class JBCorpus {
private List<JBDataStructure> annotations;
private List<String> contexts;
private Map<Integer, List<JBDataStructure>> contextToAnnotation;
private int lastEditIndex;
private JBDataStructure currentAnnotationOriginal;
private String corpusFile;
private int currentAnnotationIndex;
private String annotator;
public JBCorpus(String file, String annotator) {
public JBCorpus(String file, String annotator) throws Exception {
this.annotator = annotator;
annotations = new ArrayList<JBDataStructure>();
contexts = new ArrayList<String>();
contextToAnnotation = new HashMap<Integer, List<JBDataStructure>>();
corpusFile = file;
currentAnnotationIndex = 0;
currentAnnotationOriginal = new JBDataStructure();
readCorpus();
}
public void readCorpus() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(corpusFile)));
String fileString = "";
String line;
while ((line = in.readLine()) != null) {
fileString += line;
}
public void readCorpus() throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(corpusFile)));
String fileString = "";
String line;
while ((line = in.readLine()) != null) {
fileString += line;
}
JSONObject corpus = new JSONObject(fileString);
lastEditIndex = corpus.getInt("lastEditIndex");
JSONArray annotationsArray = corpus.getJSONArray("annotations");
for (int i = 0; i < annotationsArray.length(); i++) {
JSONObject annotation = annotationsArray.getJSONObject(i);
String treeString = annotation.getString("tree");
String pbInstanceString = annotation.getString("pbInstance");
int position = annotation.getInt("indexInContext");
JBDataStructure structure = new JBDataStructure(treeString, pbInstanceString, position);
annotations.add(structure);
}
JSONObject corpus = new JSONObject(fileString);
lastEditIndex = corpus.getInt("lastEditIndex");
JSONArray annotationsArray = corpus.getJSONArray("annotations");
for (int i = 0; i < annotationsArray.length(); i++) {
JSONObject annotation = annotationsArray.getJSONObject(i);
String treeString = annotation.getString("tree");
String pbInstanceString = annotation.getString("pbInstance");
int position = annotation.getInt("indexInContext");
JBDataStructure structure = new JBDataStructure(treeString, pbInstanceString, position);
annotations.add(structure);
List<JBDataStructure> annotationList;
if (contextToAnnotation.containsKey(position))
annotationList = contextToAnnotation.get(position);
else annotationList = new ArrayList<JBDataStructure>();
annotationList.add(structure);
contextToAnnotation.put(position, annotationList);
}
JSONArray contextsArray = corpus.getJSONArray("contexts");
for (int i = 0; i < contextsArray.length(); i++) {
String context = contextsArray.getString(i);
contexts.add(context);
}
} catch (Exception e) {
System.err.println("Error reading the corpus");
e.printStackTrace();
System.exit(-1);
JSONArray contextsArray = corpus.getJSONArray("contexts");
for (int i = 0; i < contextsArray.length(); i++) {
String context = contextsArray.getString(i);
contexts.add(context);
}
}
......@@ -137,24 +142,28 @@ public class JBCorpus {
}
public void removeCurrentAnnotation() {
JBDataStructure currentAnnotation = getCurrentAnnotation();
int indexInContext = currentAnnotation.getIndexInContext();
List<JBDataStructure> annotationsForContext = contextToAnnotation.get(indexInContext);
if (annotationsForContext.size() == 1) contextToAnnotation.remove(indexInContext);
else {
annotationsForContext.remove(currentAnnotation);
contextToAnnotation.put(indexInContext, annotationsForContext);
}
annotations.remove(currentAnnotationIndex);
}
public void addAnnotation(String annotator, String lemma) {
public void addAnnotation(String annotator, String lemma) throws Exception {
JBDataStructure current = getCurrentAnnotation();
// Start from copying the current annotation
JBDataStructure newAnnotation = null;
try {
String framesetLemma = lemma;
if (lemma.contains("-p"))
framesetLemma = lemma.split("-")[0];
String pbInstanceString = annotator + " " + lemma + " " + framesetLemma + ".XX#";
newAnnotation = new JBDataStructure(current.getTbTree().toTextTree(), pbInstanceString,
current.getIndexInContext());
} catch (Exception e) {
e.printStackTrace();
}
String framesetLemma = lemma;
if (lemma.contains("-p"))
framesetLemma = lemma.split("-")[0];
String pbInstanceString = annotator + " " + lemma + " " + framesetLemma + ".XX#";
JBDataStructure newAnnotation = new JBDataStructure(current.getTbTree().toTextTree(), pbInstanceString,
current.getIndexInContext());
annotations.add(currentAnnotationIndex, newAnnotation);
contextToAnnotation.get(current.getIndexInContext()).add(newAnnotation);
}
public void backup(JBDataStructure currentAnnotation) {
......@@ -165,11 +174,6 @@ public class JBCorpus {
}
}
public void replaceAnnotation(int i, JBDataStructure dataStructure) {
annotations.remove(i);
annotations.add(i, dataStructure);
}
// --------------------- Getters --------------------- //
public JBDataStructure getAnnotation(int index) {
......@@ -200,4 +204,8 @@ public class JBCorpus {
public List<String> getContexts() {
return contexts;
}
public List<JBDataStructure> getAnnotationsFromContext(int contextInd) {
return contextToAnnotation.get(contextInd);
}
}
......@@ -23,6 +23,8 @@
*/
package jubilee.toolkit;
import jubilee.datastructure.JBDataStructure;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
......@@ -103,6 +105,8 @@ public class JBArgPanel extends JPanel implements ActionListener {
public void updateArg(String arg) {
if (arg.equals(ERASE))
tree.updateArg(null, ERASE);
else if (arg.equals(JBDataStructure.REL))
tree.updateArg(null, JBDataStructure.REL);
else if (arg.equals("M-SLC"))
tree.updateArg(null, "LINK-SLC");
else
......
......@@ -45,6 +45,7 @@ public class JBMenuBar extends JMenuBar {
JMenuItem fsPrev, fsNext, fsViewExample, fsViewArgument, fsViewRolesetComment;
JMenuItem[] argArgs, argFunc;
JMenuItem argErase;
JMenuItem helpShortcuts;
JMenuItem helpAbout;
private int menuShortcutKeyMask;
......@@ -66,11 +67,16 @@ public class JBMenuBar extends JMenuBar {
void setMenuArgTag(ArrayList<String[]> args) {
mn_args.removeAll();
argArgs = new JMenuItem[JBArgPanel.NUM_ARG+args.size()-1];
argArgs = new JMenuItem[JBArgPanel.NUM_ARG+args.size()];
JBDataStructure.REL = args.get(0)[0];
// predicate tag
argArgs[0] = getJMenuItem(JBDataStructure.REL, 0, KeyEvent.VK_EQUALS, 0);
mn_args.add(argArgs[0]);
mn_args.addSeparator();
// number argument-tags
int k = 0;
int k = 1;
for (int i=0; i<JBArgPanel.NUM_ARG; i++) {
argArgs[k] = getJMenuItem(String.valueOf(i), 48+i, 48+i, 0);
mn_args.add(argArgs[k++]);
......@@ -164,7 +170,7 @@ public class JBMenuBar extends JMenuBar {
for (int i=0; i<operators.size(); i++) {
String[] operator = operators.get(i);
argFunc[i] = getJMenuItem(operator[0], 0, operator[1].charAt(0), menuShortcutKeyMask+KeyEvent.SHIFT_MASK);
argFunc[i] = getJMenuItem(operator[0], 0, operator[1].charAt(0), KeyEvent.SHIFT_MASK);
mArgFunc.add(argFunc[i]);
}
......@@ -175,10 +181,11 @@ public class JBMenuBar extends JMenuBar {
private void initMenuHelp() {
JMenu mHelp = new JMenu("Help");
mHelp.setMnemonic(KeyEvent.VK_H);
helpAbout = getJMenuItem("About", KeyEvent.VK_A, KeyEvent.VK_F1, 0);
helpShortcuts = getJMenuItem("Shortcuts", KeyEvent.VK_S, KeyEvent.VK_F1, 0);
helpAbout = getJMenuItem("About", KeyEvent.VK_A, KeyEvent.VK_F2, 0);
mHelp.add(helpShortcuts);
mHelp.add(helpAbout);
add(mHelp);
}
......
......@@ -245,19 +245,24 @@ public class JBOpenDialog extends JDialog implements ActionListener, ItemListene
String corpusStr = tok.nextToken();
jbtk.initProperties(corpusStr, m_dataset);
jbtk.readReferenceMaterial();
if (!ls_newTask.isSelectionEmpty()) {
String[] tmp = getFileList(ls_newTask.getSelectedValue(), true);
if (tmp != null)
jbtk.openFile(tmp, true);
else
return;
}
else {
String[] tmp = getFileList(ls_myTask.getSelectedValue(), false);
jbtk.openFile(tmp, false);
}
try {
if (!ls_newTask.isSelectionEmpty()) {
String[] tmp = getFileList(ls_newTask.getSelectedValue(), true);
if (tmp != null)
jbtk.openFile(tmp, true);
else
return;
} else {
String[] tmp = getFileList(ls_myTask.getSelectedValue(), false);
jbtk.openFile(tmp, false);
}
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "There was an error: \n" + e.getMessage(), "Error reading the corpus",
JOptionPane.ERROR_MESSAGE);
return;
}
dispose();
}
......
......@@ -60,13 +60,13 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
private JList<String> ls_gold;
private DefaultListModel<String> lm_gold;
private JBTreePanel tv_tree;
private JBFramesetPanel framesetPanel;
private JBArgPanel argPanel;
private JBMenuBar mbar;
private JBCorpus corpus;
private JBCorpus[] moreCorpora;
int i_currSetting = 0; // current project setting (i.e. english.sample.path)
int i_maxAnn;
......@@ -84,7 +84,7 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
s_sysDir = sysDir;
str_userID = userID;
i_maxAnn = maxAnn;
Container cp = getContentPane();
initComponents();
initBounds(cp);
......@@ -120,7 +120,7 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
{
return str_userID.equalsIgnoreCase(DataManager.GOLD_ID);
}
String getUserID()
{
return str_userID;
......@@ -138,13 +138,13 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
terminalsList = DataManager.getContents("terminals.txt");
nonTerminalsList = DataManager.getContents("non-terminals.txt");
}
// -------------------- initialize components --------------------
private void initComponents() {
bt_prev = new JButton("Prev");
bt_prev.addActionListener(this);
bt_next = new JButton("Next");
bt_next.addActionListener(this);
......@@ -160,25 +160,25 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
comboJump.setMaximumRowCount(20);
comboJump.addItemListener(this);
comboJump.setFocusable(false);
tf_annotator = new JTextField(str_userID);
tf_annotator.setEditable(false);
tf_annotator.setFocusable(false);
ta_context = new JTextArea();
ta_context.setEditable(false);
ta_context.setBackground(Color.white);
ta_context.setRows(16);
ta_context.setLineWrap(true);
tv_tree = new JBTreePanel();
framesetPanel = new JBFramesetPanel();
framesetPanel.setBorder(new TitledBorder("Frameset View"));
argPanel = new JBArgPanel(tv_tree, this);
argPanel.setBorder(new TitledBorder("Argument View"));
mbar = new JBMenuBar(this);
setJMenuBar(mbar);
}
......@@ -186,11 +186,11 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
private JPanel getTreePanel() {
JPanel treePanel = new JPanel();
treePanel.setLayout(new BorderLayout());
// top of the treeview
JPanel top = new JPanel();
top.setLayout(new BorderLayout());
JPanel top1 = new JPanel();
top1.setLayout(new GridLayout(0,4));
top1.add(bt_prev);
......@@ -198,18 +198,18 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
top1.add(comboJump);
top1.add(tf_annotator);
top.add(top1, BorderLayout.NORTH);
if (isGold()) {
lm_gold = new DefaultListModel<String>();
ls_gold = new JList<String>(lm_gold);
ls_gold.setFont(new Font("Courier", Font.PLAIN, 12));
ls_gold.addListSelectionListener(this);
ls_gold.setVisibleRowCount(3);
ls_gold.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
top.add(new JScrollPane(ls_gold), BorderLayout.SOUTH);
}
// bottom of the treeview
JScrollPane sentencePane = new JScrollPane(ta_context);
......@@ -231,18 +231,18 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
treePanel.add(tv_tree, BorderLayout.CENTER);
treePanel.add(bottomPanel, BorderLayout.SOUTH);
treePanel.setBorder(new TitledBorder("Treebank View"));
return treePanel;
}
private void initBounds(Container cp) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int fr_wt = (int)screenSize.getWidth() - 50;
int fr_ht = (int)screenSize.getHeight() - 50;
JSplitPane sp_right = new JSplitPane(JSplitPane.VERTICAL_SPLIT, framesetPanel, argPanel);
JSplitPane sp_main = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, getTreePanel(), sp_right);
sp_main.setDividerLocation((int)(fr_wt*0.65));
sp_right.setDividerLocation((int)(fr_ht*0.5));
......@@ -250,19 +250,19 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
cp.add(sp_main, BorderLayout.CENTER);
setBounds(0, 0, fr_wt, fr_ht);
}
// called from JBOpenDialog
void initProperties(String corpusStr, HashMap<String, String> dataset) {
ArrayList<String[]> argTag = DataManager.getContents(corpusStr + DataManager.ARGS_FILE_EXT);
str_dataset = dataset;
mbar.setMenuArgTag(argTag);
argPanel.updateArgButtons(argTag);
framesetPanel.setProperties(str_dataset.get(DataManager.FRAMESET));
}
// called from JBOpenDialog
void openFile(String[] filename, boolean isNewTask) {
void openFile(String[] filename, boolean isNewTask) throws Exception {
str_annFile = str_dataset.get(DataManager.ANNOTATION) + File.separator + filename[0] + "." + str_userID;
setTitle(str_frameTitle + " - " + filename[0]);
......@@ -279,7 +279,7 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
}
else
corpus = new JBCorpus(str_annFile, str_userID);
if (isGold()) {
moreCorpora = new JBCorpus[filename.length-1];
for (int i=1; i<filename.length; i++) {
......@@ -288,26 +288,19 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
moreCorpora[i-1] = new JBCorpus(filename[i], DataManager.GOLD_ID);
}
}
framesetPanel.setCorpus(corpus);
// Create the context window
String contextText = "";
for (String line : corpus.getContexts()) contextText += line+"\n";
ta_context.setText(contextText);
comboJump.removeAllItems();
for (int i = 0; i < corpus.getSize(); i++) {
int position = corpus.getAnnotation(i).getIndexInContext();
String contextId = corpus.getContext(position);
comboJump.insertItemAt(i + " - \"" + contextId.substring(0, contextId.indexOf(":")) + "\"", i);
}
buildContextWindow();
buildComboBox();
// Go to the last sentence that the user annotated
comboJump.setSelectedIndex(corpus.getLastEditIndex());
}
// ---------------------- Listener/Adpater Start ----------------------
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mbar.fileOpen) menuFileOpen();
else if (e.getSource() == mbar.fileSave) menuFileSave();
......@@ -323,13 +316,14 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
else if (e.getSource() == mbar.fsViewArgument) tv_tree.viewArgument();
else if (e.getSource() == mbar.fsViewRolesetComment) framesetPanel.viewRolesetComment();
else if (e.getSource() == mbar.argErase) argPanel.updateArg(e.getActionCommand());
else if (e.getSource() == mbar.helpShortcuts) menuHelpShortcuts();
else if (e.getSource() == mbar.helpAbout) menuHelpAbout();
else if (e.getSource() == buttonRemoveAnnotation) actionButtonRemoveAnnotation();
else if (e.getSource() == buttonAddAnnotation) actionButtonAddAnnotation();
menuArgumentArg(e);
menuArgumentFunc(e);
}
public void itemStateChanged(ItemEvent e) {
if (e.getSource() == comboJump && comboJump.getSelectedIndex() >= 0) {
corpus.setCurrentAnnotationIndex(comboJump.getSelectedIndex());
......@@ -338,14 +332,14 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
updateGoldList();
}
}
public void valueChanged(ListSelectionEvent e) {
if (e.getSource() == ls_gold && ls_gold.getSelectedIndex() > 0) {
corpus.copyCurrent(moreCorpora[ls_gold.getSelectedIndex() - 1]);
updateGoldTopList();
}
}
public void updateAll() {
JBDataStructure annotation = corpus.getCurrentAnnotation();
tv_tree.setAnnotation(annotation);
......@@ -380,7 +374,7 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
catch (BadLocationException e) {e.printStackTrace();}
ta_context.setCaretPosition(bExtraId);
}
private void updateGoldList() {
if (isGold()) {
lm_gold.removeAllElements();
......@@ -395,7 +389,7 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
ls_gold.invalidate();
}
}
void updateGoldTopList() {
if (isGold()) {
JBDataStructure annotation = corpus.getCurrentAnnotation();
......@@ -422,17 +416,19 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
int index = corpus.getCurrentAnnotationIndex();
corpus.removeCurrentAnnotation();
// Rebuild the context window (in case we have removed all annotations for this utterance)
buildContextWindow();
// Rebuild the combo box
comboJump.removeAllItems();
for (int i = 0; i < corpus.getSize(); i++) {
int position = corpus.getAnnotation(i).getIndexInContext();
String contextId = corpus.getContext(position);
comboJump.insertItemAt(i + " - \"" + contextId.substring(0, contextId.indexOf(":")) + "\"", i);
}
buildComboBox();
// Now move to the next annotation
if (index < corpus.getSize()) comboJump.setSelectedIndex(index);
else comboJump.setSelectedIndex(index - 1);
// Finally mark that the corpus has changed
if (!getTitle().startsWith(EDITED))
setTitle(EDITED + getTitle());
}
}
......@@ -444,33 +440,60 @@ public class JBToolkit extends JFrame implements ActionListener, ItemListener, L
if (response != null) {
// Add the new annotation
corpus.addAnnotation(str_userID, response);
// Rebuild the combo box
comboJump.removeAllItems();
for (int i = 0; i < corpus.getSize(); i++) {
int position = corpus.getAnnotation(i).getIndexInContext();
String contextId = corpus.getContext(position);
comboJump.insertItemAt(i + " - \"" + contextId.substring(0, contextId.indexOf(":")) + "\"", i);
}
try {
corpus.addAnnotation(str_userID, response);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "There was an error: \n" + e.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
// Rebuild the combo box
buildComboBox();
// Now move to the next annotation
comboJump.setSelectedIndex(corpus.getCurrentAnnotationIndex());
// Finally mark that the corpus has changed
if (!getTitle().startsWith(EDITED))
setTitle(EDITED + getTitle());
}
}