1   /*
2    * JIntellitype ----------------- Copyright 2005-2006 Emil A. Lefkof III
3    * 
4    * I always give it my best shot to make a program useful and solid, but remeber
5    * that there is absolutely no warranty for using this program as stated in the
6    * following terms:
7    * 
8    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9    * use this file except in compliance with the License. You may obtain a copy of
10   * the License at
11   * 
12   * http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   */
20  package com.melloware;
21  
22  import java.awt.BorderLayout;
23  import java.awt.Event;
24  import java.awt.Frame;
25  import java.awt.GraphicsEnvironment;
26  import java.awt.Point;
27  import java.awt.Rectangle;
28  import java.awt.event.ActionEvent;
29  import java.awt.event.ActionListener;
30  
31  import javax.swing.JButton;
32  import javax.swing.JFrame;
33  import javax.swing.JPanel;
34  import javax.swing.JScrollPane;
35  import javax.swing.JTextArea;
36  import javax.swing.border.EtchedBorder;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  
41  import com.melloware.jintellitype.HotkeyListener;
42  import com.melloware.jintellitype.IntellitypeListener;
43  import com.melloware.jintellitype.JIntellitype;
44  
45  /**
46   * Swing based test application to test all the functions of the JIntellitype
47   * library.
48   * <p>
49   * Copyright (c) 2006 Melloware, Inc. <http://www.melloware.com>
50   * @author Emil A. Lefkof III <elefkof@ksmpartners.com>
51   * @version 1.0
52   */
53  public class JIntellitypeTester extends JFrame implements HotkeyListener, IntellitypeListener {
54  
55     /**
56      * Logger for this class
57      */
58     private static final Log LOG = LogFactory.getLog(JIntellitypeTester.class);
59     private static JIntellitypeTester mainFrame;
60     private static final int WINDOWS_A = 88;
61     private static final int ALT_SHIFT_B = 89;
62     private static final int CTRL_SHIFT_C = 90;
63     private static final int PRINT_SCREEN = 91;
64     private static final int F9 = 92;
65     private JButton btnRegisterHotKey = new JButton();
66     private JButton btnUnregisterHotKey = new JButton();
67     private JPanel bottomPanel = new JPanel();
68     private JPanel mainPanel = new JPanel();
69     private JPanel topPanel = new JPanel();
70     private JScrollPane scrollPane = new JScrollPane();
71     private JTextArea textArea = new JTextArea();
72  
73     /**
74      * Creates new form.
75      */
76     public JIntellitypeTester() {
77        initComponents();
78     }
79  
80     /**
81      * Main method to launch this application.
82      * <p>
83      * @param args any command line arguments
84      */
85     public static void main(String[] args) {
86        LOG.info("JIntellitype Tester");
87        // first check to see if an instance of this application is already
88        // running, use the name of the window title of this JFrame for checking
89        if (JIntellitype.checkInstanceAlreadyRunning("JIntellitype Test Application")) {
90           LOG.error("An instance of this application is already running");
91           System.exit(1);
92        }
93        
94        // next check to make sure JIntellitype DLL can be found and we are on 
95        // a Windows operating System
96        if (!JIntellitype.isJIntellitypeSupported()) {
97           LOG.error("JIntellitype.DLL is not found in the path or this is not Windows 32bit OS.");
98           System.exit(1);
99        }
100 
101       mainFrame = new JIntellitypeTester();
102       mainFrame.setTitle("JIntellitype Test Application");
103       center(mainFrame);
104       mainFrame.setVisible(true);
105       mainFrame.initJIntellitype();
106    }
107 
108    /*
109     * (non-Javadoc)
110     * @see com.melloware.jintellitype.HotkeyListener#onHotKey(int)
111     */
112    public void onHotKey(int aIdentifier) {
113       output("WM_HOTKEY message received " + Integer.toString(aIdentifier));
114    }
115 
116    /*
117     * (non-Javadoc)
118     * @see com.melloware.jintellitype.IntellitypeListener#onIntellitype(int)
119     */
120    public void onIntellitype(int aCommand) {
121 
122       switch (aCommand) {
123       case JIntellitype.APPCOMMAND_BROWSER_BACKWARD:
124          output("BROWSER_BACKWARD message received " + Integer.toString(aCommand));
125          break;
126       case JIntellitype.APPCOMMAND_BROWSER_FAVOURITES:
127          output("BROWSER_FAVOURITES message received " + Integer.toString(aCommand));
128          break;
129       case JIntellitype.APPCOMMAND_BROWSER_FORWARD:
130          output("BROWSER_FORWARD message received " + Integer.toString(aCommand));
131          break;
132       case JIntellitype.APPCOMMAND_BROWSER_HOME:
133          output("BROWSER_HOME message received " + Integer.toString(aCommand));
134          break;
135       case JIntellitype.APPCOMMAND_BROWSER_REFRESH:
136          output("BROWSER_REFRESH message received " + Integer.toString(aCommand));
137          break;
138       case JIntellitype.APPCOMMAND_BROWSER_SEARCH:
139          output("BROWSER_SEARCH message received " + Integer.toString(aCommand));
140          break;
141       case JIntellitype.APPCOMMAND_BROWSER_STOP:
142          output("BROWSER_STOP message received " + Integer.toString(aCommand));
143          break;
144       case JIntellitype.APPCOMMAND_LAUNCH_APP1:
145          output("LAUNCH_APP1 message received " + Integer.toString(aCommand));
146          break;
147       case JIntellitype.APPCOMMAND_LAUNCH_APP2:
148          output("LAUNCH_APP2 message received " + Integer.toString(aCommand));
149          break;
150       case JIntellitype.APPCOMMAND_LAUNCH_MAIL:
151          output("LAUNCH_MAIL message received " + Integer.toString(aCommand));
152          break;
153       case JIntellitype.APPCOMMAND_MEDIA_NEXTTRACK:
154          output("MEDIA_NEXTTRACK message received " + Integer.toString(aCommand));
155          break;
156       case JIntellitype.APPCOMMAND_MEDIA_PLAY_PAUSE:
157          output("MEDIA_PLAY_PAUSE message received " + Integer.toString(aCommand));
158          break;
159       case JIntellitype.APPCOMMAND_MEDIA_PREVIOUSTRACK:
160          output("MEDIA_PREVIOUSTRACK message received " + Integer.toString(aCommand));
161          break;
162       case JIntellitype.APPCOMMAND_MEDIA_STOP:
163          output("MEDIA_STOP message received " + Integer.toString(aCommand));
164          break;
165       case JIntellitype.APPCOMMAND_VOLUME_DOWN:
166          output("VOLUME_DOWN message received " + Integer.toString(aCommand));
167          break;
168       case JIntellitype.APPCOMMAND_VOLUME_UP:
169          output("VOLUME_UP message received " + Integer.toString(aCommand));
170          break;
171       case JIntellitype.APPCOMMAND_VOLUME_MUTE:
172          output("VOLUME_MUTE message received " + Integer.toString(aCommand));
173          break;
174       default:
175          output("Undefined INTELLITYPE message caught " + Integer.toString(aCommand));
176          break;
177       }
178    }
179 
180    /**
181     * Centers window on desktop.
182     * <p>
183     * @param aFrame the Frame to center
184     */
185    private static void center(JFrame aFrame) {
186       LOG.debug("Centering Window");
187       final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
188       final Point centerPoint = ge.getCenterPoint();
189       final Rectangle bounds = ge.getMaximumWindowBounds();
190       final int w = Math.min(aFrame.getWidth(), bounds.width);
191       final int h = Math.min(aFrame.getHeight(), bounds.height);
192       final int x = centerPoint.x - (w / 2);
193       final int y = centerPoint.y - (h / 2);
194       aFrame.setBounds(x, y, w, h);
195       if ((w == bounds.width) && (h == bounds.height)) {
196          aFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
197       }
198       aFrame.validate();
199    }
200 
201    /**
202     * Method to register a hotkey using the RegisterHotKey Windows API call.
203     * <p>
204     * @param aEvent the ActionEvent fired.
205     */
206    private void btnRegisterHotKey_actionPerformed(ActionEvent aEvent) {
207       LOG.debug("RegisterHotKey");
208 
209       // assign the WINDOWS+A key to the unique id 88 for identification
210       JIntellitype.getInstance().registerHotKey(WINDOWS_A, JIntellitype.MOD_WIN, (int) 'A');
211       JIntellitype.getInstance().registerHotKey(ALT_SHIFT_B, JIntellitype.MOD_ALT + JIntellitype.MOD_SHIFT, (int) 'B');
212       JIntellitype.getInstance().registerSwingHotKey(CTRL_SHIFT_C, Event.CTRL_MASK + Event.SHIFT_MASK, (int) 'C');
213       
214       // use a 0 for the modifier if you just want a single keystroke to be a hotkey
215       JIntellitype.getInstance().registerHotKey(PRINT_SCREEN, 0, 44);
216       JIntellitype.getInstance().registerHotKey(F9, 0, 120);
217       // clear the text area
218       textArea.setText("");
219       output("RegisterHotKey WINDOWS+A was assigned uniqueID 88");
220       output("RegisterHotKey ALT+SHIFT+B was assigned uniqueID 89");
221       output("RegisterHotKey CTRL+SHIFT+C was assigned uniqueID 90");
222       output("RegisterHotKey PRINT_SCREEN was assigned uniqueID 91");
223       output("RegisterHotKey F9 was assigned uniqueID 92");
224       output("Press WINDOWS+A or ALT+SHIFT+B or CTRL+SHIFT+C in another application and you will see the debug output in the textarea.");
225    }
226 
227    /**
228     * Method to unregister a hotkey using the UnregisterHotKey Windows API call.
229     * <p>
230     * @param aEvent the ActionEvent fired.
231     */
232    private void btnUnregisterHotKey_actionPerformed(ActionEvent aEvent) {
233       LOG.debug("UnregisterHotKey");
234       JIntellitype.getInstance().unregisterHotKey(WINDOWS_A);
235       JIntellitype.getInstance().unregisterHotKey(ALT_SHIFT_B);
236       JIntellitype.getInstance().unregisterHotKey(CTRL_SHIFT_C);
237       JIntellitype.getInstance().unregisterHotKey(PRINT_SCREEN);
238       JIntellitype.getInstance().unregisterHotKey(F9);
239       output("UnregisterHotKey WINDOWS+A");
240       output("UnregisterHotKey ALT+SHIFT+B");
241       output("UnregisterHotKey CTRL+SHIFT+C");
242       output("UnregisterHotKey PRINT_SCREEN");
243       output("UnregisterHotKey F9");
244       output("Press WINDOWS+A or ALT+SHIFT+B in another application and you will NOT see the debug output in the textarea.");
245    }
246 
247    /**
248     * This method is called from within the constructor to initialize the form.
249     */
250    private void initComponents() {
251       LOG.info("Initializing UI");
252 
253       mainPanel.setLayout(new BorderLayout());
254       topPanel.setBorder(new EtchedBorder(1));
255       bottomPanel.setLayout(new BorderLayout());
256       bottomPanel.setBorder(new EtchedBorder(1));
257       btnRegisterHotKey.setText("RegisterHotKey");
258       btnRegisterHotKey.addActionListener(new ActionListener() {
259          public void actionPerformed(ActionEvent e) {
260             btnRegisterHotKey_actionPerformed(e);
261          }
262       });
263       btnUnregisterHotKey.setText("UnregisterHotKey");
264       btnUnregisterHotKey.addActionListener(new ActionListener() {
265          public void actionPerformed(ActionEvent e) {
266             btnUnregisterHotKey_actionPerformed(e);
267          }
268       });
269       topPanel.add(btnRegisterHotKey);
270       topPanel.add(btnUnregisterHotKey);
271       scrollPane.getViewport().add(textArea);
272       bottomPanel.add(scrollPane, BorderLayout.CENTER);
273       mainPanel.add(topPanel, BorderLayout.NORTH);
274       mainPanel.add(bottomPanel, BorderLayout.CENTER);
275 
276       this.addWindowListener(new java.awt.event.WindowAdapter() {
277          public void windowClosing(java.awt.event.WindowEvent evt) {
278             LOG.info("Exiting Application");
279             // don't forget to clean up any resources before close
280             JIntellitype.getInstance().cleanUp();
281             System.exit(0);
282          }
283       });
284 
285       this.getContentPane().add(mainPanel);
286       this.pack();
287       this.setSize(800, 600);
288    }
289 
290    /**
291     * Initialize the JInitellitype library making sure the DLL is located.
292     * 
293     */
294    public void initJIntellitype() {
295       try {
296 
297          // initialize JIntellitype with the frame so all windows commands can
298          // be attached to this window
299          JIntellitype.getInstance().addHotKeyListener(this);
300          JIntellitype.getInstance().addIntellitypeListener(this);
301          output("JIntellitype initialized");
302       } catch (RuntimeException ex) {
303          output("Either you are not on Windows, or there is a problem with the JIntellitype library!");
304          LOG.error(ex, ex);
305       }
306    }
307 
308    /**
309     * Send the output to the log and the text area.
310     * <p>
311     * @param text the text to output
312     */
313    private void output(String text) {
314       if (LOG.isInfoEnabled()) {
315          LOG.info(text);
316       }
317       textArea.append(text);
318       textArea.append("\n");
319    }
320 
321 }