/Users/lyon/j4p/src/gui/run/ShortcutUtils.java

1    /** 
2     * Created by IntelliJ IDEA. 
3     * User: dlyon 
4     * Date: Feb 24, 2004 
5     * Time: 1:13:09 PM 
6     * To change this template use Options | File Templates. 
7     */ 
8    package gui.run; 
9     
10   import utils.StringUtils; 
11    
12   import javax.swing.AbstractButton; 
13   import javax.swing.JLabel; 
14   import javax.swing.JMenuItem; 
15   import javax.swing.JTabbedPane; 
16   import javax.swing.JTextField; 
17   import javax.swing.KeyStroke; 
18    
19   public class ShortcutUtils { 
20       public static final char META_CHARACTER = '['; 
21       public static final char KEYSTRING_START = '{'; 
22       public static final char KEYSTRING_END = '}'; 
23    
24       public static boolean hasAccelerator(String s) { 
25           int i1 = s.indexOf(KEYSTRING_START); 
26           int i2 = s.indexOf(KEYSTRING_END); 
27           if (i1 == -1 || i2 == -1) return false; 
28           return true; 
29       } 
30    
31       /** 
32        * returns true if there is no META_CHARACTER 
33        * '[' and no KEYSTRING_START and no 
34        * KEYSTRING_END. E.g. no "{...}" pair.  
35        * 
36        * @param s 
37        * @return 
38        */ 
39       public static boolean hasShortcut(String s) { 
40           int i1 = s.indexOf(META_CHARACTER); 
41           int i2 = s.indexOf(KEYSTRING_START); 
42           int i3 = s.indexOf(KEYSTRING_END); 
43           if (i1 == -1 && 
44                   ((i2 == -1) || (i3 == -1))) 
45               return false; 
46           return true; 
47       } 
48    
49       public static char getMnemonicChar(String s) { 
50           if (-1 == s.indexOf(META_CHARACTER)) 
51               return ' '; 
52           int i1 = s.indexOf(META_CHARACTER); 
53           return s.charAt(i1 + 1); 
54       } 
55    
56       public static String getAcceleratorString(String s) { 
57           if (!hasAccelerator(s)) return ""; 
58           return s.substring(s.indexOf(KEYSTRING_START) + 1, 
59                   s.indexOf(KEYSTRING_END)); 
60       } 
61    
62       public static KeyStroke getKeyStroke(String s) { 
63           return KeyStroke.getKeyStroke(getAcceleratorString(s)); 
64       } 
65    
66       public static String stripMnemonicMetaChar(String s) { 
67           String newString = 
68                   StringUtils.replaceFirstInstance(s, 
69                           META_CHARACTER + "", 
70                           ""); 
71           return 
72                   newString; 
73       } 
74    
75       public static String stripAcceleratorString(String s) { 
76           if (!hasAccelerator(s)) 
77               return s; 
78           int i = s.indexOf(KEYSTRING_START); 
79           return s.substring(0, i); 
80       } 
81    
82    
83       public static void print(Object o) { 
84           System.out.println(o); 
85       } 
86    
87       /** 
88        * This was supposed to search the tab list 
89        * and add mnemonics, but, for some reason, it 
90        * does not work. This is the bug 4624207 
91        * http://developer.java.sun.com/developer/bugParade/bugs/4624207.html 
92        * and it was fixed in 1.5 
93        * 
94        * @param jtp 
95        */ 
96       public static void addShortcut(JTabbedPane jtp) { 
97           int n = jtp.getTabCount(); 
98           for (int i = 0; i < n; i++) { 
99               String s = jtp.getTitleAt(i); 
100              if (!hasShortcut(s)) continue; 
101              jtp.setMnemonicAt(i, 
102                      java.awt.event.KeyEvent.VK_1); 
103              jtp.setTitleAt(i, 
104                      stripMnemonicMetaChar(s)); 
105          } 
106   
107      } 
108   
109      /** 
110       * "this is a shortcut [c" "this has no 
111       * shortcut [" "this has no shortcut either" 
112       * 
113       * @param ab 
114       */ 
115      public static void addShortcut(AbstractButton ab) { 
116          addMnemonic(ab); 
117          addAccelerator(ab); 
118      } 
119   
120      public static void addShortcut(JTextField tf) { 
121          addFocusAccelerator(tf); 
122      } 
123   
124      public static void addShortcut(JLabel tf) { 
125          addDisplayedMnemonic(tf); 
126      } 
127   
128      private static void addDisplayedMnemonic(JLabel tf) { 
129          String s = tf.getText(); 
130          if (!hasMnemonic(s)) return; 
131          tf.setDisplayedMnemonic(getMnemonicChar(s)); 
132          tf.setText(stripMnemonicMetaChar(s)); 
133          tf.setToolTipText(tf.getText()); 
134      } 
135   
136      /** 
137       * Adds the accelerator without altering textfield contents. 
138       * This does NOT alter the appearance of the textfield, 
139       * it only sets the accelerator. Also, the <code>label</code> is 
140       * used as the tool tip text. 
141       * 
142       * @param label label upon which accelerator is based. 
143       * @param tf    textfield to which accelerator is to be added. 
144       */ 
145      public static void addFocusAccelerator(String label, JTextField tf) { 
146          if (!hasMnemonic(label)) return; 
147          tf.setFocusAccelerator(getMnemonicChar(label)); 
148          tf.setToolTipText(stripMnemonicMetaChar(label)); 
149      } 
150   
151      private static void addFocusAccelerator(JTextField tf) { 
152          String s = tf.getText(); 
153          if (!hasMnemonic(s)) return; 
154          tf.setFocusAccelerator(getMnemonicChar(s)); 
155          tf.setText(stripMnemonicMetaChar(s)); 
156          tf.setToolTipText(tf.getText()); 
157      } 
158   
159      private static void addMnemonic(AbstractButton ab) { 
160          String s = ab.getText(); 
161          if (!hasMnemonic(s)) return; 
162          ab.setMnemonic(getMnemonicChar(s)); 
163          ab.setText(stripMnemonicMetaChar(s)); 
164      } 
165   
166   
167      private static void addAccelerator(AbstractButton ab) { 
168          if (ab instanceof JMenuItem) 
169              addAccelerator((JMenuItem) ab); 
170      } 
171   
172   
173      private static boolean hasMnemonic(String s) { 
174          int mc = s.indexOf(META_CHARACTER); 
175          if (-1 == mc) 
176              return false; 
177          if (s.length() == mc - 1) return false; 
178          return true; 
179      } 
180   
181      /** 
182       * Accelerator strings are embedded in the 
183       * label of a JMenuItem. For example: "my 
184       * label{alt shift X} "another label {control 
185       * DELETE} works on JCheckBoxMenuItem and 
186       * JRadioButtonMenuItem 
187       * 
188       * @param jmi 
189       */ 
190      public static void addAccelerator(JMenuItem jmi) { 
191          print("Adding accelerator"); 
192          String s = jmi.getText(); 
193          testString(s); 
194          if (!hasAccelerator(s)) return; 
195   
196          jmi.setAccelerator(getKeyStroke(s)); 
197          jmi.setText(stripAcceleratorString(s)); 
198      } 
199   
200      public static void main(String args[]) { 
201          String s = "this is a [test{alt shift X}"; 
202          testString(s); 
203      } 
204   
205      private static void testString(String s) { 
206          print(s); 
207          print("stripChar=" + 
208                  stripMnemonicMetaChar(s)); 
209          print("The shortcut char=" + 
210                  getMnemonicChar(s)); 
211          print("hasKeyString=" + 
212                  hasAccelerator(s)); 
213          print("keyString=" + 
214                  getAcceleratorString(s)); 
215          print("keyStroke=" + 
216                  KeyStroke.getKeyStroke(getAcceleratorString(s))); 
217          print("stripKeyString=" + 
218                  stripAcceleratorString(s)); 
219      } 
220  } 
221