Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/tuneology/irremote/IRRemotePanel.java


1   /*
2     IRRemotePanel.java
3   
4     Copyright (C) 2002 Fran Taylor
5   
6     This library is free software; you can redistribute it and/or modify
7     it under the terms of the GNU Lesser General Public License as
8     published by the Free Software Foundation; either version 2.1 of the
9     License, or (at your option) any later version.
10  
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15  
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19    
20    $Id: IRRemotePanel.java,v 1.2 2002/11/05 08:32:59 xnarf Exp $
21  
22  */
23  
24  package com.tuneology.irremote;
25  
26  import java.awt.*;
27  import java.awt.event.*;
28  import java.io.*;
29  import java.util.*;
30  import javax.swing.*;
31  import javax.swing.table.*;
32  import javax.swing.event.*;
33  
34  /**
35   * This class represents a Swing component used to edit IR bindings.
36   *
37   * @version $Id: IRRemotePanel.java,v 1.2 2002/11/05 08:32:59 xnarf Exp $
38   * 
39   * @author Fran Taylor
40   */
41  public class IRRemotePanel extends Box {
42      /**
43       *
44       * @param l the IR component to be configured.
45       */
46      public IRRemotePanel(IRComponent l) {
47    super(BoxLayout.Y_AXIS);
48          ir = l;
49          /* internally here we have two arrays: 
50             an array of strings, each representing a possible IR command 
51             an array of actions, each representing a possible action to take
52             The IR command list is not editable.
53             The action is editable via the ActionEditor class
54          */
55    commands = l.getCommands();
56    actions = new AbstractAction[commands.length];
57    prevActions = new AbstractAction[commands.length];
58          
59    add(new JLabel(getResourceString("irBoxLabel")));
60    Vector irListeners = ir.getListeners();
61          if (!irListeners.contains(nullAction))
62              irListeners.add(nullAction);
63          /* labels is a list of strings, one for each event, containing ite name */
64    String[] labels = new String[irListeners.size()];
65    for(int i = 0; i < irListeners.size(); i++)
66        labels[i] = (String) ((AbstractAction) irListeners.get(i)).getValue(IRComponent.IR_COMMAND);
67          /* instantiate our table with combo box for selecting an action */
68    actionEditor = new ActionEditor(labels, irListeners);
69    ActionRenderer actionRenderer = new ActionRenderer();
70    tbl = new JTable(new AbstractTableModel() {
71      public String getColumnName(int col) { return getResourceString((col == 0) ? "commandLabel" : "actionLabel"); }
72      public int getColumnCount() { return 2; }
73      public int getRowCount() { return commands.length; }
74      public boolean isCellEditable(int row, int col) { return (col == 1) ? true : false; }
75      /**
76       * These two methods pass data to and receive edited data from
77       * the ActionEditor combo box class.
78       */
79      public Object getValueAt(int row, int column) { 
80          return (column == 0) ? ((Object) commands[row]) : ((Object) getAction(row) ); }
81      public void setValueAt(Object val, int row, int col) {
82          if (col == 1) {
83                          /* hang onto the previous value */
84                          if (prevActions[row] == null)
85                              prevActions[row] = actions[row];
86                          actions[row] = (AbstractAction) val;
87                      }
88                  }
89                  public Class getColumnClass(int col) { return (col == 0) ? String.class : AbstractAction.class; }
90              } );
91          tbl.setDefaultRenderer(AbstractAction.class, actionRenderer);
92          tbl.setDefaultEditor(AbstractAction.class, actionEditor);
93          tbl.setRowHeight(18);
94          JScrollPane jsp = new JScrollPane(tbl);
95          jsp.setPreferredSize(new Dimension(325, 200));
96          jsp.setColumnHeaderView(tbl.getTableHeader());
97          add(jsp);
98          revert();
99      }
100     /**
101      * Set the user interface to reflect the current state.
102      */
103     public void revert() {
104         Vector v = ir.getListeners();
105         for(int i = 0; i < v.size(); i++) {
106             AbstractAction act = ((AbstractAction) v.get(i));
107             String bindings = (String) act.getValue(IRComponent.IR_BINDING);
108             String action = (String) act.getValue(IRComponent.IR_COMMAND);
109             if (bindings != null) {
110                 StringTokenizer tok = new StringTokenizer(bindings, ",");
111                 while(tok.hasMoreTokens()) {
112                     String binding = tok.nextToken();
113                     for(int j = 0; j < commands.length; j++) {
114                         if (commands[j].equals(binding)) {
115                             actions[j] = act;
116                             break;
117                         }
118                     }
119                 }
120             }
121         }
122     }
123     /**
124      * Set the current state to reflect the user interface.
125      */
126     public void update() {
127         actionEditor.stopCellEditing();
128         for(int i = 0; i < actions.length; i++) {
129             /* edit this event out of the previous listener's list */
130             AbstractAction prevListener = prevActions[i];
131             if ((prevListener != null) & (prevListener != nullAction)) {
132                 String cmd = (String) prevListener.getValue(IRComponent.IR_COMMAND);
133                 String events = (String) prevListener.getValue(IRComponent.IR_BINDING);
134                 /* we have to remove a listener before we can edit its binding list */
135                 ir.removeActionListener(prevListener);
136                 StringTokenizer tok = new StringTokenizer((events == null) ? "" : events, ",");
137                 events = "";
138                 while(tok.hasMoreTokens()) {
139                     String str = tok.nextToken();
140                     /* put all events except this one back in the string */
141                     if (!str.equals(commands[i])) {
142                         /* add a comma if necessary */
143                         if (!events.equals("")) events += ",";
144                         events += str;
145                     } else {
146                     }
147                 }
148                 prevListener.putValue(IRComponent.IR_BINDING, events);
149                 ir.addActionListener(prevListener);
150             }
151             /* add this event to the new listener's list */
152             AbstractAction listener = actions[i]; 
153             if ((listener != null) & (listener != nullAction)) {
154                 String cmd = (String) listener.getValue(IRComponent.IR_COMMAND);
155                 String events = (String) listener.getValue(IRComponent.IR_BINDING);
156                 /* we have to remove a listener before we can edit its binding list */
157                 ir.removeActionListener(listener);
158                 StringTokenizer tok = new StringTokenizer((events == null) ? "" : events);
159                 events = commands[i];
160                 while(tok.hasMoreTokens()) {
161                     String str = tok.nextToken();
162                     /* it's always necessary to add a comma */
163                     if (!str.equals(commands[i]))
164                         events += "," + str;
165                 }
166                 listener.putValue(IRComponent.IR_BINDING, events);
167                 ir.addActionListener(listener);
168             }
169         }
170     }
171     /**
172      * Add a listener callback to the remote control. 
173      * 
174      * @param listener
175      */
176     public void addActionListener(AbstractAction listener) {
177         String action = (String) listener.getValue(IRComponent.IR_COMMAND);
178         String cmd = (String) listener.getValue(IRComponent.IR_BINDING);
179         ir.addActionListener(listener);
180         for(int i = 0; i < actions.length; i++) if (commands[i].equals(cmd)) actions[i] = listener;
181     }
182     /**
183      * Remove a listener callback from the remote control.
184      * 
185      * @param listener
186      */
187     public void removeActionListener(AbstractAction listener) {
188         String action = (String) listener.getValue(IRComponent.IR_COMMAND);
189         String cmd = (String) listener.getValue(IRComponent.IR_BINDING);
190         ir.removeActionListener(listener);
191         for(int i = 0; i < actions.length; i++) if (commands[i].equals(cmd)) actions[i] = null;
192     }
193     /**
194      * Returns an array of all the defined IR actions.
195      * 
196      * @return An array of all the defined IR actions.
197      */
198     public AbstractAction[] getActions() { return actions; }
199 
200     /**
201      * Returns an array of all the possible IR commands.
202      *
203      * @return An array of all the possible IR commands.
204      */
205     public String[] getCommands() { return commands; }
206 
207     private class ActionRenderer extends JLabel implements TableCellRenderer {
208         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
209                                                        boolean hasFocus, int row, int column) {
210             AbstractAction act = (AbstractAction) value;
211             String txt = "";
212             switch(column) {
213             case 0:
214                 return new JLabel(commands[row]);
215             case 1:
216                 if (act != null)
217                     return new JLabel((String) act.getValue(IRComponent.IR_COMMAND));
218                 else
219                     return new JLabel("");
220             default:
221                 return null;
222             }
223         }
224     }
225     /**
226      * This is the combo box embedded in the IR command mapping table. 
227      */
228     private class ActionEditor extends JComboBox implements TableCellEditor {
229         public ActionEditor(String[] labels, Vector values) { 
230             super(labels);
231             this.values = values;
232             listeners = new Vector();
233         }
234         public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int col) {
235             // set the combo box value for the action
236             AbstractAction act = (AbstractAction) value;
237             if (act != null) {
238                 String str = (String) act.getValue(IRComponent.IR_COMMAND);
239                 setSelectedItem(str);
240                 table.setRowSelectionInterval(row, row);
241                 table.setColumnSelectionInterval(col, col);
242                 origValue = act;
243             } else {
244                 System.out.println("getTableCellEditorComponent: value at (" + row + ", " + col + ") is null");
245             }
246             return this;
247         } 
248         public Object getCellEditorValue() {
249             int i = getSelectedIndex(); 
250             return ((i == -1) ? nullAction : (AbstractAction) values.get(i));
251         }
252         public boolean isCellEditable(EventObject eo) { return true; }
253         public boolean shouldSelectCell(EventObject eo) { return true; }
254         public boolean stopCellEditing() { fireEditingStopped(); return true; }
255         public void cancelCellEditing() { fireEditingCanceled(); }
256         public void addCellEditorListener(CellEditorListener cel) { listeners.add(cel); }
257         public void removeCellEditorListener(CellEditorListener cel) { listeners.remove(cel); }
258         protected void fireEditingStopped() {
259             ChangeEvent ce = new ChangeEvent(this);
260             for(int i = 0; i < listeners.size(); i++)
261                 ((CellEditorListener)listeners.get(i)).editingStopped(ce);
262         }
263         protected void fireEditingCanceled() {
264             setSelectedItem(origValue);
265             ChangeEvent ce = new ChangeEvent(this);
266             for(int i = 0; i < listeners.size(); i++)
267                 ((CellEditorListener)listeners.get(i)).editingCanceled(ce);
268         }
269         private Vector values;
270         private Vector listeners;
271         private AbstractAction origValue;
272     }
273     private AbstractAction getAction(int i) {
274         AbstractAction a = actions[i];
275         return (a == null) ? nullAction : a;
276     }
277     private String getUIAction(int i) {
278         AbstractAction a = actions[i];
279         if ((a == null) || (a == nullAction)) return null;
280         return (String) a.getValue(IRComponent.IR_COMMAND);
281     }
282     private static String getResourceString(String nm) {
283         String str;
284         try {
285             str = resources.getString(nm);
286         } catch (MissingResourceException mre) {
287             str = null;
288         }
289         return str;
290     }
291     private JTable tbl;
292     private IRComponent ir;
293     private String[] commands;
294     private AbstractAction[] prevActions;
295     private AbstractAction[] actions;
296     private ActionEditor actionEditor;
297     private static AbstractAction nullAction;
298     private static ResourceBundle resources;
299     static {
300         try {
301             resources = ResourceBundle.getBundle("resources.IRRemotePanel");
302         } catch (MissingResourceException e) {
303             System.err.println("Can't find resource");
304             System.exit(1);
305         }
306   nullAction = new AbstractAction() { 
307     public void actionPerformed(ActionEvent e) { } 
308     public String toString() { return getResourceString("noActionString"); }
309       };
310   nullAction.putValue(IRComponent.IR_COMMAND, getResourceString("noActionString"));
311     }
312 }
313 /*
314    Local Variables:
315    mode:java
316    indent-tabs-mode:nil 
317    c-basic-offset:4 
318    c-indent-level:4 
319    c-continued-statement-offset:4 
320    c-brace-offset:-4 
321    c-brace-imaginary-offset:-4 
322    c-argdecl-indent:0
323    c-label-offset:0
324    End:
325 */