f@0
|
1 /*
|
f@0
|
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
|
f@0
|
3
|
f@0
|
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
|
f@0
|
5
|
f@0
|
6 This program is free software: you can redistribute it and/or modify
|
f@0
|
7 it under the terms of the GNU General Public License as published by
|
f@0
|
8 the Free Software Foundation, either version 3 of the License, or
|
f@0
|
9 (at your option) any later version.
|
f@0
|
10
|
f@0
|
11 This program is distributed in the hope that it will be useful,
|
f@0
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
f@0
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
f@0
|
14 GNU General Public License for more details.
|
f@0
|
15
|
f@0
|
16 You should have received a copy of the GNU General Public License
|
f@0
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
f@0
|
18 */
|
f@0
|
19 package uk.ac.qmul.eecs.ccmi.speech;
|
f@0
|
20
|
f@0
|
21 import java.awt.event.ActionEvent;
|
f@0
|
22 import java.awt.event.KeyEvent;
|
f@0
|
23
|
f@0
|
24 import javax.swing.AbstractAction;
|
f@0
|
25 import javax.swing.JTree;
|
f@0
|
26 import javax.swing.KeyStroke;
|
f@0
|
27 import javax.swing.tree.DefaultMutableTreeNode;
|
f@0
|
28 import javax.swing.tree.TreePath;
|
f@0
|
29
|
f@0
|
30 import uk.ac.qmul.eecs.ccmi.sound.PlayerListener;
|
f@0
|
31 import uk.ac.qmul.eecs.ccmi.sound.SoundEvent;
|
f@0
|
32 import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;
|
f@0
|
33
|
f@0
|
34 /**
|
f@0
|
35 *
|
f@0
|
36 */
|
f@0
|
37 @SuppressWarnings("serial")
|
f@0
|
38 public class TreeSonifier {
|
f@0
|
39
|
f@0
|
40 public void sonify(final JTree tree){
|
f@0
|
41 /* select the root node as selected */
|
f@0
|
42 tree.setSelectionRow(0);
|
f@0
|
43 /* Overwrite keystrokes up,down,left,right arrows and space, shift, ctrl */
|
f@0
|
44 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0),"down");
|
f@0
|
45 tree.getActionMap().put("down", new AbstractAction(){
|
f@0
|
46 @Override
|
f@0
|
47 public void actionPerformed(ActionEvent evt) {
|
f@0
|
48 DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
|
f@0
|
49 /* look if we've got a sibling node after (we are not at the bottom) */
|
f@0
|
50 DefaultMutableTreeNode nextTreeNode = treeNode.getNextSibling();
|
f@0
|
51 SoundEvent loop = null;
|
f@0
|
52 if(nextTreeNode == null){
|
f@0
|
53 DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent();
|
f@0
|
54 if(parent == null) /* root node, just stay there */
|
f@0
|
55 nextTreeNode = treeNode;
|
f@0
|
56 else /* loop = go to first child of own parent */
|
f@0
|
57 nextTreeNode = (DefaultMutableTreeNode)parent.getFirstChild();
|
f@0
|
58 loop = SoundEvent.LIST_BOTTOM_REACHED;
|
f@0
|
59 }
|
f@0
|
60 tree.setSelectionPath(new TreePath(nextTreeNode.getPath()));
|
f@0
|
61 final String currentPathSpeech = currentPathSpeech(tree);
|
f@0
|
62 SoundFactory.getInstance().play(loop, new PlayerListener(){
|
f@0
|
63 public void playEnded() {
|
f@0
|
64 NarratorFactory.getInstance().speak(currentPathSpeech);
|
f@0
|
65 }
|
f@0
|
66 });
|
f@0
|
67 }});
|
f@0
|
68
|
f@0
|
69 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0),"up");
|
f@0
|
70 tree.getActionMap().put("up", new AbstractAction(){
|
f@0
|
71 @Override
|
f@0
|
72 public void actionPerformed(ActionEvent evt) {
|
f@0
|
73 DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
|
f@0
|
74 DefaultMutableTreeNode previousTreeNode = treeNode.getPreviousSibling();
|
f@0
|
75 SoundEvent loop = null;
|
f@0
|
76 if(previousTreeNode == null){
|
f@0
|
77 DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent();
|
f@0
|
78 if(parent == null) /* root node */
|
f@0
|
79 previousTreeNode = treeNode;
|
f@0
|
80 else
|
f@0
|
81 previousTreeNode = (DefaultMutableTreeNode)parent.getLastChild();
|
f@0
|
82 loop = SoundEvent.LIST_TOP_REACHED;
|
f@0
|
83 }
|
f@0
|
84 tree.setSelectionPath(new TreePath(previousTreeNode.getPath()));
|
f@0
|
85 final String currentPathSpeech = currentPathSpeech(tree);
|
f@0
|
86 SoundFactory.getInstance().play(loop, new PlayerListener(){
|
f@0
|
87 public void playEnded() {
|
f@0
|
88 NarratorFactory.getInstance().speak(currentPathSpeech);
|
f@0
|
89 }
|
f@0
|
90 });
|
f@0
|
91 }});
|
f@0
|
92
|
f@0
|
93 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0),"right");
|
f@0
|
94 tree.getActionMap().put("right", new AbstractAction(){
|
f@0
|
95 @Override
|
f@0
|
96 public void actionPerformed(ActionEvent evt) {
|
f@0
|
97 TreePath path = tree.getSelectionPath();
|
f@0
|
98 DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
|
f@0
|
99 if(treeNode.isLeaf()){
|
f@0
|
100 SoundFactory.getInstance().play(SoundEvent.ERROR);
|
f@0
|
101 }
|
f@0
|
102 else{
|
f@0
|
103 tree.expandPath(path);
|
f@0
|
104 tree.setSelectionPath(new TreePath(((DefaultMutableTreeNode)treeNode.getFirstChild()).getPath()));
|
f@0
|
105 final String currentPathSpeech = currentPathSpeech(tree);
|
f@0
|
106 SoundFactory.getInstance().play(SoundEvent.TREE_NODE_EXPAND,new PlayerListener(){
|
f@0
|
107 @Override
|
f@0
|
108 public void playEnded() {
|
f@0
|
109 NarratorFactory.getInstance().speak(currentPathSpeech);
|
f@0
|
110 }
|
f@0
|
111 });
|
f@0
|
112 }
|
f@0
|
113 }
|
f@0
|
114 });
|
f@0
|
115
|
f@0
|
116 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"left");
|
f@0
|
117 tree.getActionMap().put("left", new AbstractAction(){
|
f@0
|
118 @Override
|
f@0
|
119 public void actionPerformed(ActionEvent evt) {
|
f@0
|
120 TreePath path = tree.getSelectionPath();
|
f@0
|
121 DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
|
f@0
|
122 DefaultMutableTreeNode parent = (DefaultMutableTreeNode)treeNode.getParent();
|
f@0
|
123 if(parent == null){/* root node */
|
f@0
|
124 SoundFactory.getInstance().play(SoundEvent.ERROR);
|
f@0
|
125 }
|
f@0
|
126 else{
|
f@0
|
127 TreePath newPath = new TreePath(((DefaultMutableTreeNode)parent).getPath());
|
f@0
|
128 tree.setSelectionPath(newPath);
|
f@0
|
129 tree.collapsePath(newPath);
|
f@0
|
130 final String currentPathSpeech = currentPathSpeech(tree);
|
f@0
|
131 SoundFactory.getInstance().play(SoundEvent.TREE_NODE_COLLAPSE,new PlayerListener(){
|
f@0
|
132 @Override
|
f@0
|
133 public void playEnded() {
|
f@0
|
134 NarratorFactory.getInstance().speak(currentPathSpeech);
|
f@0
|
135 }
|
f@0
|
136 });
|
f@0
|
137 }
|
f@0
|
138 }
|
f@0
|
139 });
|
f@0
|
140
|
f@0
|
141 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0),"space");
|
f@0
|
142 tree.getActionMap().put("space",new AbstractAction(){
|
f@0
|
143 @Override
|
f@0
|
144 public void actionPerformed(ActionEvent arg0) {
|
f@0
|
145 space(tree);
|
f@0
|
146 }
|
f@0
|
147 });
|
f@0
|
148 /* make the tree ignore the page up and page down keys */
|
f@0
|
149 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0),"none");
|
f@0
|
150 tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0),"none");
|
f@0
|
151 }
|
f@0
|
152
|
f@0
|
153 protected String currentPathSpeech(JTree tree) {
|
f@0
|
154 TreePath path = tree.getSelectionPath();
|
f@0
|
155 DefaultMutableTreeNode selectedPathTreeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
|
f@0
|
156 return selectedPathTreeNode.toString();
|
f@0
|
157 }
|
f@0
|
158
|
f@0
|
159 protected void space(JTree tree){
|
f@0
|
160 NarratorFactory.getInstance().speak(currentPathSpeech(tree));
|
f@0
|
161 }
|
f@0
|
162
|
f@0
|
163 }
|