f@0: /* f@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool f@0: f@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) f@0: f@0: This program is free software: you can redistribute it and/or modify f@0: it under the terms of the GNU General Public License as published by f@0: the Free Software Foundation, either version 3 of the License, or f@0: (at your option) any later version. f@0: f@0: This program is distributed in the hope that it will be useful, f@0: but WITHOUT ANY WARRANTY; without even the implied warranty of f@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@0: GNU General Public License for more details. f@0: f@0: You should have received a copy of the GNU General Public License f@0: along with this program. If not, see . f@0: */ f@0: package uk.ac.qmul.eecs.ccmi.speech; f@0: f@0: import java.awt.event.ActionEvent; f@0: import java.awt.event.KeyEvent; f@0: f@0: import javax.swing.AbstractAction; f@0: import javax.swing.JTree; f@0: import javax.swing.KeyStroke; f@0: import javax.swing.tree.DefaultMutableTreeNode; f@0: import javax.swing.tree.TreePath; f@0: f@0: import uk.ac.qmul.eecs.ccmi.sound.PlayerListener; f@0: import uk.ac.qmul.eecs.ccmi.sound.SoundEvent; f@0: import uk.ac.qmul.eecs.ccmi.sound.SoundFactory; f@0: f@0: /** f@0: * f@0: */ f@0: @SuppressWarnings("serial") f@0: public class TreeSonifier { f@0: f@0: public void sonify(final JTree tree){ f@0: /* select the root node as selected */ f@0: tree.setSelectionRow(0); f@0: /* Overwrite keystrokes up,down,left,right arrows and space, shift, ctrl */ f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0),"down"); f@0: tree.getActionMap().put("down", new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); f@0: /* look if we've got a sibling node after (we are not at the bottom) */ f@0: DefaultMutableTreeNode nextTreeNode = treeNode.getNextSibling(); f@0: SoundEvent loop = null; f@0: if(nextTreeNode == null){ f@0: DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent(); f@0: if(parent == null) /* root node, just stay there */ f@0: nextTreeNode = treeNode; f@0: else /* loop = go to first child of own parent */ f@0: nextTreeNode = (DefaultMutableTreeNode)parent.getFirstChild(); f@0: loop = SoundEvent.LIST_BOTTOM_REACHED; f@0: } f@0: tree.setSelectionPath(new TreePath(nextTreeNode.getPath())); f@0: final String currentPathSpeech = currentPathSpeech(tree); f@0: SoundFactory.getInstance().play(loop, new PlayerListener(){ f@0: public void playEnded() { f@0: NarratorFactory.getInstance().speak(currentPathSpeech); f@0: } f@0: }); f@0: }}); f@0: f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0),"up"); f@0: tree.getActionMap().put("up", new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); f@0: DefaultMutableTreeNode previousTreeNode = treeNode.getPreviousSibling(); f@0: SoundEvent loop = null; f@0: if(previousTreeNode == null){ f@0: DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent(); f@0: if(parent == null) /* root node */ f@0: previousTreeNode = treeNode; f@0: else f@0: previousTreeNode = (DefaultMutableTreeNode)parent.getLastChild(); f@0: loop = SoundEvent.LIST_TOP_REACHED; f@0: } f@0: tree.setSelectionPath(new TreePath(previousTreeNode.getPath())); f@0: final String currentPathSpeech = currentPathSpeech(tree); f@0: SoundFactory.getInstance().play(loop, new PlayerListener(){ f@0: public void playEnded() { f@0: NarratorFactory.getInstance().speak(currentPathSpeech); f@0: } f@0: }); f@0: }}); f@0: f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"right"); f@0: tree.getActionMap().put("right", new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: TreePath path = tree.getSelectionPath(); f@0: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent(); f@0: if(treeNode.isLeaf()){ f@0: SoundFactory.getInstance().play(SoundEvent.ERROR); f@0: } f@0: else{ f@0: tree.expandPath(path); f@0: tree.setSelectionPath(new TreePath(((DefaultMutableTreeNode)treeNode.getFirstChild()).getPath())); f@0: final String currentPathSpeech = currentPathSpeech(tree); f@0: SoundFactory.getInstance().play(SoundEvent.TREE_NODE_EXPAND,new PlayerListener(){ f@0: @Override f@0: public void playEnded() { f@0: NarratorFactory.getInstance().speak(currentPathSpeech); f@0: } f@0: }); f@0: } f@0: } f@0: }); f@0: f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"left"); f@0: tree.getActionMap().put("left", new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent evt) { f@0: TreePath path = tree.getSelectionPath(); f@0: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent(); f@0: DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent(); f@0: if(parent == null){/* root node */ f@0: SoundFactory.getInstance().play(SoundEvent.ERROR); f@0: } f@0: else{ f@0: TreePath newPath = new TreePath(((DefaultMutableTreeNode)parent).getPath()); f@0: tree.setSelectionPath(newPath); f@0: tree.collapsePath(newPath); f@0: final String currentPathSpeech = currentPathSpeech(tree); f@0: SoundFactory.getInstance().play(SoundEvent.TREE_NODE_COLLAPSE,new PlayerListener(){ f@0: @Override f@0: public void playEnded() { f@0: NarratorFactory.getInstance().speak(currentPathSpeech); f@0: } f@0: }); f@0: } f@0: } f@0: }); f@0: f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0),"space"); f@0: tree.getActionMap().put("space",new AbstractAction(){ f@0: @Override f@0: public void actionPerformed(ActionEvent arg0) { f@0: space(tree); f@0: } f@0: }); f@0: /* make the tree ignore the page up and page down keys */ f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0),"none"); f@0: tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0),"none"); f@0: } f@0: f@0: protected String currentPathSpeech(JTree tree) { f@0: TreePath path = tree.getSelectionPath(); f@0: DefaultMutableTreeNode selectedPathTreeNode = (DefaultMutableTreeNode)path.getLastPathComponent(); f@0: return selectedPathTreeNode.toString(); f@0: } f@0: f@0: protected void space(JTree tree){ f@0: NarratorFactory.getInstance().speak(currentPathSpeech(tree)); f@0: } f@0: f@0: }