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