// This file is part of Penn TotalRecall <http://memory.psych.upenn.edu/TotalRecall>. // // TotalRecall is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 3 only. // // TotalRecall is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with TotalRecall. If not, see <http://www.gnu.org/licenses/>. package components.annotations; import info.GUIConstants; import info.MyShapes; import info.SysInfo; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JComponent; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import components.MyFrame; import control.CurAudio; /** * A custom interface component for displaying committed annotations to the user. * * @author Yuvi Masory */ public class AnnotationDisplay extends JScrollPane { private static final String title = "Annotations"; private static AnnotationDisplay instance; private static AnnotationTable table; /** * Creates a new instance of the component, initializing internal components, key bindings, listeners, * and various aspects of appearance. */ private AnnotationDisplay() { table = AnnotationTable.getInstance(); getViewport().setView(table); setPreferredSize(GUIConstants.annotationDisplayDimension); setMaximumSize(GUIConstants.annotationDisplayDimension); setBorder(MyShapes.createMyUnfocusedTitledBorder(title)); //since AnnotationDisplay is a clickable area, we must write focus handling code for the event it is clicked on //passes focus to the table if it is focusable (not empty), otherwise giving focus to the frame addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent e) { if(table.isFocusable()) { table.requestFocusInWindow(); } else { MyFrame.getInstance().requestFocusInWindow(); } } }); //overrides JScrollPane key bindings for the benefit of SeekAction's key bindings getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "none"); getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "none"); } public static Annotation[] getAnnotationsInOrder() { return table.getModel().toArray(); } public static void addAnnotation(Annotation ann) { if(ann == null) { throw new IllegalArgumentException("annotation/s cannot be null"); } if(SysInfo.sys.forceListen) { CurAudio.getListener().offerGreatestProgress(CurAudio.getMaster().millisToFrames(ann.getTime())); } table.getModel().addElement(ann); } public static void addAnnotations(Iterable<Annotation> anns) { if(anns == null) { throw new IllegalArgumentException("annotations cannot be null"); } if(SysInfo.sys.forceListen) { for(Annotation a: anns) { CurAudio.getListener().offerGreatestProgress(CurAudio.getMaster().millisToFrames(a.getTime())); } } table.getModel().addElements(anns); } public static void removeAnnotation(int rowIndex) { table.getModel().removeElementAt(rowIndex); } public static void removeAllAnnotations() { table.getModel().removeAllElements(); } public static AnnotationDisplay getInstance() { if (instance == null) { instance = new AnnotationDisplay(); } return instance; } public static int getNumAnnotations() { return table.getModel().size(); } }