source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/PrefJPanel.java@ 4929

Last change on this file since 4929 was 4929, checked in by Don-vip, 12 years ago

see #7386 - Do not list unknown keyCodes when using a non-English locale

  • Property svn:eol-style set to native
File size: 25.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences;
3
4import java.awt.Dimension;
5import java.awt.GridBagConstraints;
6import java.awt.GridBagLayout;
7import java.awt.Insets;
8import java.awt.Toolkit;
9
10import static org.openstreetmap.josm.tools.I18n.tr;
11
12import java.awt.event.KeyEvent;
13import java.util.ArrayList;
14import java.util.LinkedHashMap;
15import java.util.HashMap;
16import java.util.Map;
17
18import java.util.regex.PatternSyntaxException;
19import javax.swing.AbstractAction;
20import javax.swing.BorderFactory;
21import javax.swing.BoxLayout;
22import javax.swing.DefaultComboBoxModel;
23import javax.swing.JCheckBox;
24import javax.swing.JComboBox;
25import javax.swing.JEditorPane;
26import javax.swing.JLabel;
27import javax.swing.JPanel;
28import javax.swing.JScrollPane;
29import javax.swing.JTabbedPane;
30import javax.swing.JTable;
31import javax.swing.JTextField;
32import javax.swing.KeyStroke;
33import javax.swing.ListSelectionModel;
34import javax.swing.RowFilter;
35import javax.swing.SwingConstants;
36import javax.swing.event.DocumentEvent;
37import javax.swing.event.DocumentListener;
38import javax.swing.event.ListSelectionEvent;
39import javax.swing.event.ListSelectionListener;
40import javax.swing.table.AbstractTableModel;
41import javax.swing.table.TableModel;
42
43import javax.swing.table.TableRowSorter;
44import org.openstreetmap.josm.Main;
45import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
46import org.openstreetmap.josm.tools.Shortcut;
47
48/**
49 * This is the keyboard preferences content.
50 * If someone wants to merge it with ShortcutPreference.java, feel free.
51 */
52public class PrefJPanel extends JPanel {
53
54 // table of shortcuts
55 private AbstractTableModel model;
56 // comboboxes of modifier groups, mapping selectedIndex to real data
57 private static int[] modifInts = new int[]{
58 -1,
59 0,
60 KeyEvent.SHIFT_DOWN_MASK,
61 KeyEvent.CTRL_DOWN_MASK,
62 KeyEvent.ALT_DOWN_MASK,
63 KeyEvent.META_DOWN_MASK,
64 KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK,
65 KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK,
66 KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK,
67 KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK,
68 KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK,
69 KeyEvent.ALT_DOWN_MASK | KeyEvent.META_DOWN_MASK,
70 KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK,
71 KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK
72 };
73 // and here are the texts fro the comboboxes
74 private static String[] modifList = new String[] {
75 tr("disabled"),
76 tr("no modifier"),
77 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[2]).getModifiers()),
78 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[3]).getModifiers()),
79 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[4]).getModifiers()),
80 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[5]).getModifiers()),
81 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[6]).getModifiers()),
82 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[7]).getModifiers()),
83 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[8]).getModifiers()),
84 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[9]).getModifiers()),
85 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[10]).getModifiers()),
86 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[11]).getModifiers()),
87 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[12]).getModifiers()),
88 KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, modifInts[13]).getModifiers())
89 };
90 // this are the display(!) texts for the checkboxes. Let the JVM do the i18n for us <g>.
91 // Ok, there's a real reason for this: The JVM should know best how the keys are labelled
92 // on the physical keyboard. What language pack is installed in JOSM is completely
93 // independent from the keyboard's labelling. But the operation system's locale
94 // usually matches the keyboard. This even works with my English Windows and my German
95 // keyboard.
96 private static String SHIFT = KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.SHIFT_DOWN_MASK).getModifiers());
97 private static String CTRL = KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK).getModifiers());
98 private static String ALT = KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.ALT_DOWN_MASK).getModifiers());
99 private static String META = KeyEvent.getKeyModifiersText(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.META_DOWN_MASK).getModifiers());
100
101 // A list of keys to present the user. Sadly this really is a list of keys Java knows about,
102 // not a list of real physical keys. If someone knows how to get that list?
103 private static Map<Integer, String> keyList = setKeyList();
104
105 private static Map<Integer, String> setKeyList() {
106 Map<Integer, String> list = new LinkedHashMap<Integer, String>();
107 String unknown = Toolkit.getProperty("AWT.unknown", "Unknown");
108 // I hate this, but I found no alternative...
109 for (int i = 0; i < 65534; i++) {
110 String s = KeyEvent.getKeyText(i);
111 if (s != null && s.length() > 0 && !s.contains(unknown)) {
112 list.put(Integer.valueOf(i), s);
113 //System.out.println(i+": "+s);
114 }
115 }
116 list.put(Integer.valueOf(-1), "");
117 return list;
118 }
119
120 private JComboBox bxPrim1 = new JComboBox();
121 private JComboBox bxPrim2 = new JComboBox();
122 private JComboBox bxPrim3 = new JComboBox();
123 private JComboBox bxPrim4 = new JComboBox();
124 private JComboBox bxSec1 = new JComboBox();
125 private JComboBox bxSec2 = new JComboBox();
126 private JComboBox bxSec3 = new JComboBox();
127 private JComboBox bxSec4 = new JComboBox();
128 private JComboBox bxTer1 = new JComboBox();
129 private JComboBox bxTer2 = new JComboBox();
130 private JComboBox bxTer3 = new JComboBox();
131 private JComboBox bxTer4 = new JComboBox();
132 private JCheckBox cbAlt = new JCheckBox();
133 private JCheckBox cbCtrl = new JCheckBox();
134 private JCheckBox cbMeta = new JCheckBox();
135 private JCheckBox cbShift = new JCheckBox();
136 private JCheckBox cbDefault = new JCheckBox();
137 private JCheckBox cbDisable = new JCheckBox();
138 private JComboBox tfKey = new JComboBox();
139
140 JTable shortcutTable = new JTable();
141
142 private JTextField filterField = new JTextField();
143
144 /** Creates new form prefJPanel */
145 // Ain't those auto-generated comments helpful or what? <g>
146 public PrefJPanel(AbstractTableModel model) {
147 this.model = model;
148 initComponents();
149 }
150
151 private void initComponents() {
152 JPanel editGroupPane = new JPanel();
153 JPanel hotkeyGroupPane = new JPanel();
154
155 JPanel listPane = new JPanel();
156 JScrollPane listScrollPane = new JScrollPane();
157 JPanel menuGroupPane = new JPanel();
158 JPanel modifierTab = new JPanel();
159 JTabbedPane prefTabPane = new JTabbedPane();
160 JPanel shortcutEditPane = new JPanel();
161 JPanel shortcutTab = new JPanel();
162 JPanel subwindowGroupPane = new JPanel();
163 JPanel infoTab = new JPanel();
164
165 CbAction action = new CbAction(this);
166 BxAction action2 = new BxAction();
167
168 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
169
170 // If someone wants to move this text into some resource, feel free.
171 infoTab.setLayout(new BoxLayout(shortcutTab, BoxLayout.Y_AXIS));
172 JEditorPane editor = new JEditorPane();
173 editor.setEditable(false);
174 editor.setContentType("text/html");
175 editor.setText(
176 tr("<h1><a name=\"top\">Keyboard Shortcuts</a></h1>")+
177 tr("<p>Please note that shortcut keys are assigned to the actions when JOSM is started. So you need to <b>restart</b> "
178 +"JOSM to see your changes.</p>")+
179 tr("<p>Furthermore, the shortcuts are activated when the actions are assigned to a menu entry of a button for the first "
180 +"time. So some of your changes may become active even without restart --- but also without collision handling. "
181 +"This is another reason to <b>restart</b> JOSM after making any changes here.</p>")+
182 tr("<p>You may notice that the key selection list on the next page lists all keys that exist on all kinds of keyboards "
183 +"Java knows about, not just those keys that exist on your keyboard. Please only use values that correspond to "
184 +"a real key on your keyboard. If your keyboard has no ''Copy'' key (PC keyboard do not have them, Sun keyboards do), "
185 +"then do not use it. Also there are ''keys'' listed that correspond to a shortcut on your keyboard (e.g. '':''/Colon). "
186 +"Please do not use them either, use the base key ('';''/Semicolon on US keyboards, ''.''/Period on German keyboards, etc.) "
187 +"instead. Not doing so may result in conflicts, as there is no way for JOSM to know that Ctrl+Shift+; and Ctrl+: "
188 +"actually is the same thing on an US keyboard.</p>")+
189 tr("<h1>Modifier Groups</h1>")+
190 tr("<p>The last page lists the modifier keys JOSM will automatically assign to shortcuts. For every of the four kinds "
191 +"of shortcuts there are three alternatives. JOSM will try those alternatives in the listed order when managing a "
192 +"conflict. If all alternatives result in shortcuts that are already taken, it will assign a random shortcut "
193 +"instead.</p>")+
194 tr("<p>The pseudo-modifier ''disabled'' will disable the shortcut when encountered.</p>")
195 );
196 editor.setCaretPosition(0); // scroll up
197 prefTabPane.addTab(tr("Read First"), new JScrollPane(editor));
198
199 shortcutTab.setLayout(new BoxLayout(shortcutTab, BoxLayout.Y_AXIS));
200
201 shortcutTab.add(buildFilterPanel());
202 listPane.setLayout(new java.awt.GridLayout());
203
204 // This is the list of shortcuts:
205 shortcutTable.setModel(model);
206 shortcutTable.getSelectionModel().addListSelectionListener(new CbAction(this));
207 shortcutTable.setFillsViewportHeight(true);
208 shortcutTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
209 shortcutTable.setAutoCreateRowSorter(true);
210 listScrollPane.setViewportView(shortcutTable);
211
212 listPane.add(listScrollPane);
213
214 shortcutTab.add(listPane);
215
216 // and here follows the edit area. I won't object to someone re-designing it, it looks, um, "minimalistic" ;)
217 shortcutEditPane.setLayout(new java.awt.GridLayout(5, 2));
218
219 cbDefault.setAction(action);
220 cbDefault.setText(tr("Use default"));
221 cbShift.setAction(action);
222 cbShift.setText(SHIFT); // see above for why no tr()
223 cbDisable.setAction(action);
224 cbDisable.setText(tr("Disable"));
225 cbCtrl.setAction(action);
226 cbCtrl.setText(CTRL); // see above for why no tr()
227 cbAlt.setAction(action);
228 cbAlt.setText(ALT); // see above for why no tr()
229 tfKey.setAction(action);
230 tfKey.setModel(new DefaultComboBoxModel(keyList.values().toArray()));
231 cbMeta.setAction(action);
232 cbMeta.setText(META); // see above for why no tr()
233
234
235 shortcutEditPane.add(cbDefault);
236 shortcutEditPane.add(new JLabel());
237 shortcutEditPane.add(cbShift);
238 shortcutEditPane.add(cbDisable);
239 shortcutEditPane.add(cbCtrl);
240 shortcutEditPane.add(new JLabel(tr("Key:"), SwingConstants.LEFT));
241 shortcutEditPane.add(cbAlt);
242 shortcutEditPane.add(tfKey);
243 shortcutEditPane.add(cbMeta);
244
245 shortcutEditPane.add(new JLabel(tr("Attention: Use real keyboard keys only!")));
246
247 action.actionPerformed(null); // init checkboxes
248
249 shortcutTab.add(shortcutEditPane);
250
251 prefTabPane.addTab(tr("Keyboard Shortcuts"), shortcutTab);
252
253 // next is the modfier group tab.
254 // Would be a nice array if I had done it by hand. But then, it would be finished next year or so...
255 modifierTab.setLayout(new java.awt.GridLayout(0, 1));
256 JScrollPane modifierScroller = new JScrollPane(modifierTab);
257
258 editGroupPane.setBorder(BorderFactory.createTitledBorder(tr("Edit Shortcuts")));
259 editGroupPane.setLayout(new java.awt.GridLayout(3, 5));
260
261 JComboBox[] bxArray = new JComboBox[] {
262 bxPrim1,bxSec1,bxTer1,bxPrim2,bxSec2,bxTer2,
263 bxPrim3,bxSec3,bxTer3,bxPrim4,bxSec4,bxTer4};
264 for (JComboBox bxi: bxArray) bxi.setModel(new DefaultComboBoxModel(modifList));
265
266 editGroupPane.add(new JLabel(tr("Primary modifier:")));
267 editGroupPane.add(bxPrim1);
268 editGroupPane.add(new JLabel(tr("Secondary modifier:")));
269 editGroupPane.add(bxSec1);
270 editGroupPane.add(new JLabel(tr("Tertiary modifier:")));
271 editGroupPane.add(bxTer1);
272 modifierTab.add(editGroupPane);
273
274 menuGroupPane.setBorder(BorderFactory.createTitledBorder(tr("Menu Shortcuts")));
275 menuGroupPane.setLayout(new java.awt.GridLayout(3, 5));
276 menuGroupPane.add(new JLabel(tr("Primary modifier:")));
277 menuGroupPane.add(bxPrim2);
278 menuGroupPane.add(new JLabel(tr("Secondary modifier:")));
279 menuGroupPane.add(bxSec2);
280 menuGroupPane.add(new JLabel(tr("Tertiary modifier:")));
281 menuGroupPane.add(bxTer2);
282 modifierTab.add(menuGroupPane);
283
284 hotkeyGroupPane.setBorder(BorderFactory.createTitledBorder(tr("Hotkey Shortcuts")));
285 hotkeyGroupPane.setLayout(new java.awt.GridLayout(3, 5));
286 hotkeyGroupPane.add(new JLabel(tr("Primary modifier:")));
287 hotkeyGroupPane.add(bxPrim3);
288 hotkeyGroupPane.add(new JLabel((tr("Secondary modifier:"))));
289 hotkeyGroupPane.add(bxSec3);
290 hotkeyGroupPane.add(new JLabel(tr("Tertiary modifier:")));
291 hotkeyGroupPane.add(bxTer3);
292 modifierTab.add(hotkeyGroupPane);
293
294 subwindowGroupPane.setBorder(BorderFactory.createTitledBorder(tr("Subwindow Shortcuts")));
295 subwindowGroupPane.setLayout(new java.awt.GridLayout(3, 5));
296 subwindowGroupPane.add(new JLabel(tr("Primary modifier:")));
297 subwindowGroupPane.add(bxPrim4);
298 subwindowGroupPane.add(new JLabel(tr("Secondary modifier:")));
299 subwindowGroupPane.add(bxSec4);
300 subwindowGroupPane.add(new JLabel(tr("Tertiary modifier:")));
301 subwindowGroupPane.add(bxTer4);
302
303 initbx();
304 for (JComboBox bxi: bxArray) bxi.setAction(action2);
305
306 modifierTab.add(subwindowGroupPane);
307
308 prefTabPane.addTab(tr("Modifier Groups"), modifierScroller);
309
310 add(prefTabPane);
311 }
312
313 private JPanel buildFilterPanel() {
314 // copied from PluginPreference
315 JPanel pnl = new JPanel(new GridBagLayout());
316 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
317 GridBagConstraints gc = new GridBagConstraints();
318
319 gc.anchor = GridBagConstraints.NORTHWEST;
320 gc.fill = GridBagConstraints.HORIZONTAL;
321 gc.weightx = 0.0;
322 gc.insets = new Insets(0,0,0,5);
323 pnl.add(new JLabel(tr("Search:")), gc);
324
325 gc.gridx = 1;
326 gc.weightx = 1.0;
327 pnl.add(filterField, gc);
328 filterField.setToolTipText(tr("Enter a search expression"));
329 SelectAllOnFocusGainedDecorator.decorate(filterField);
330 filterField.getDocument().addDocumentListener(new FilterFieldAdapter());
331 pnl.setMaximumSize(new Dimension(300,10));
332 return pnl;
333 }
334
335 private void disableAllModifierCheckboxes() {
336 cbDefault.setEnabled(false);
337 cbDisable.setEnabled(false);
338 cbShift.setEnabled(false);
339 cbCtrl.setEnabled(false);
340 cbAlt.setEnabled(false);
341 cbMeta.setEnabled(false);
342 }
343
344 // this allows to edit shortcuts. it:
345 // * sets the edit controls to the selected shortcut
346 // * enabled/disables the controls as needed
347 // * writes the user's changes to the shortcut
348 // And after I finally had it working, I realized that those two methods
349 // are playing ping-pong (politically correct: table tennis, I know) and
350 // even have some duplicated code. Feel free to refactor, If you have
351 // more expirience with GUI coding than I have.
352 private class CbAction extends AbstractAction implements ListSelectionListener {
353 private PrefJPanel panel;
354 public CbAction (PrefJPanel panel) {
355 this.panel = panel;
356 }
357 public void valueChanged(ListSelectionEvent e) {
358 ListSelectionModel lsm = panel.shortcutTable.getSelectionModel(); // can't use e here
359 if (!lsm.isSelectionEmpty()) {
360 int row = panel.shortcutTable.convertRowIndexToModel(lsm.getMinSelectionIndex());
361 Shortcut sc = (Shortcut)panel.model.getValueAt(row, -1);
362 panel.cbDefault.setSelected(!sc.getAssignedUser());
363 panel.cbDisable.setSelected(sc.getKeyStroke() == null);
364 panel.cbShift.setSelected(sc.getAssignedModifier() != -1 && (sc.getAssignedModifier() & KeyEvent.SHIFT_DOWN_MASK) != 0);
365 panel.cbCtrl.setSelected(sc.getAssignedModifier() != -1 && (sc.getAssignedModifier() & KeyEvent.CTRL_DOWN_MASK) != 0);
366 panel.cbAlt.setSelected(sc.getAssignedModifier() != -1 && (sc.getAssignedModifier() & KeyEvent.ALT_DOWN_MASK) != 0);
367 panel.cbMeta.setSelected(sc.getAssignedModifier() != -1 && (sc.getAssignedModifier() & KeyEvent.META_DOWN_MASK) != 0);
368 if (sc.getKeyStroke() != null) {
369 tfKey.setSelectedItem(keyList.get(sc.getKeyStroke().getKeyCode()));
370 } else {
371 tfKey.setSelectedItem(keyList.get(-1));
372 }
373 if (!sc.isChangeable()) {
374 disableAllModifierCheckboxes();
375 panel.tfKey.setEnabled(false);
376 } else {
377 panel.cbDefault.setEnabled(true);
378 actionPerformed(null);
379 }
380 model.fireTableCellUpdated(row, 1);
381 } else {
382 panel.disableAllModifierCheckboxes();
383 panel.tfKey.setEnabled(false);
384 }
385 }
386 public void actionPerformed(java.awt.event.ActionEvent e) {
387 ListSelectionModel lsm = panel.shortcutTable.getSelectionModel();
388 if (lsm != null && !lsm.isSelectionEmpty()) {
389 if (e != null) { // only if we've been called by a user action
390 int row = panel.shortcutTable.convertRowIndexToModel(lsm.getMinSelectionIndex());
391 Shortcut sc = (Shortcut)panel.model.getValueAt(row, -1);
392 if (panel.cbDisable.isSelected()) {
393 sc.setAssignedModifier(-1);
394 } else if (panel.tfKey.getSelectedItem().equals("")) {
395 sc.setAssignedModifier(KeyEvent.VK_CANCEL);
396 } else {
397 sc.setAssignedModifier(
398 (panel.cbShift.isSelected() ? KeyEvent.SHIFT_DOWN_MASK : 0) |
399 (panel.cbCtrl.isSelected() ? KeyEvent.CTRL_DOWN_MASK : 0) |
400 (panel.cbAlt.isSelected() ? KeyEvent.ALT_DOWN_MASK : 0) |
401 (panel.cbMeta.isSelected() ? KeyEvent.META_DOWN_MASK : 0)
402 );
403 for (Map.Entry<Integer, String> entry : keyList.entrySet()) {
404 if (entry.getValue().equals(panel.tfKey.getSelectedItem())) {
405 sc.setAssignedKey(entry.getKey());
406 }
407 }
408 }
409 sc.setAssignedUser(!panel.cbDefault.isSelected());
410 valueChanged(null);
411 }
412 boolean state = !panel.cbDefault.isSelected();
413 panel.cbDisable.setEnabled(state);
414 state = state && !panel.cbDisable.isSelected();
415 panel.cbShift.setEnabled(state);
416 panel.cbCtrl.setEnabled(state);
417 panel.cbAlt.setEnabled(state);
418 panel.cbMeta.setEnabled(state);
419 panel.tfKey.setEnabled(state);
420 } else {
421 panel.disableAllModifierCheckboxes();
422 panel.tfKey.setEnabled(false);
423 }
424 }
425 }
426
427 // this handles the modifier groups
428 private class BxAction extends AbstractAction {
429 public void actionPerformed(java.awt.event.ActionEvent e) {
430 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_EDIT), modifInts[bxPrim1.getSelectedIndex()]);
431 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT1 +Shortcut.GROUP_EDIT), modifInts[ bxSec1.getSelectedIndex()]);
432 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT2 +Shortcut.GROUP_EDIT), modifInts[ bxTer1.getSelectedIndex()]);
433
434 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_MENU), modifInts[bxPrim2.getSelectedIndex()]);
435 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT1 +Shortcut.GROUP_MENU), modifInts[ bxSec2.getSelectedIndex()]);
436 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT2 +Shortcut.GROUP_MENU), modifInts[ bxTer2.getSelectedIndex()]);
437
438 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_HOTKEY), modifInts[bxPrim3.getSelectedIndex()]);
439 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT1 +Shortcut.GROUP_HOTKEY), modifInts[ bxSec3.getSelectedIndex()]);
440 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT2 +Shortcut.GROUP_HOTKEY), modifInts[ bxTer3.getSelectedIndex()]);
441
442 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_LAYER), modifInts[bxPrim4.getSelectedIndex()]);
443 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT1 +Shortcut.GROUP_LAYER), modifInts[ bxSec4.getSelectedIndex()]);
444 Main.pref.putInteger("shortcut.groups."+(Shortcut.GROUPS_ALT2 +Shortcut.GROUP_LAYER), modifInts[ bxTer4.getSelectedIndex()]);
445 }
446 }
447
448 private void initbx() {
449 HashMap<Integer, Integer> groups = Main.platform.initShortcutGroups(false);
450 setBx(bxPrim1, groups, Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_EDIT);
451 setBx(bxSec1, groups, Shortcut.GROUPS_ALT1 +Shortcut.GROUP_EDIT);
452 setBx(bxTer1, groups, Shortcut.GROUPS_ALT2 +Shortcut.GROUP_EDIT);
453
454 setBx(bxPrim2, groups, Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_MENU);
455 setBx(bxSec2, groups, Shortcut.GROUPS_ALT1 +Shortcut.GROUP_MENU);
456 setBx(bxTer2, groups, Shortcut.GROUPS_ALT2 +Shortcut.GROUP_MENU);
457
458 setBx(bxPrim3, groups, Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_HOTKEY);
459 setBx(bxSec3, groups, Shortcut.GROUPS_ALT1 +Shortcut.GROUP_HOTKEY);
460 setBx(bxTer3, groups, Shortcut.GROUPS_ALT2 +Shortcut.GROUP_HOTKEY);
461
462 setBx(bxPrim4, groups, Shortcut.GROUPS_DEFAULT+Shortcut.GROUP_LAYER);
463 setBx(bxSec4, groups, Shortcut.GROUPS_ALT1 +Shortcut.GROUP_LAYER);
464 setBx(bxTer4, groups, Shortcut.GROUPS_ALT2 +Shortcut.GROUP_LAYER);
465 }
466 private void setBx(JComboBox bx, HashMap<Integer, Integer> groups, int key) {
467 int target = Main.pref.getInteger("shortcut.groups."+key, groups.get(key));
468 for (int i = 0; i < modifInts.length; i++) {
469 if (modifInts[i] == target) {
470 bx.setSelectedIndex(i);
471 }
472 }
473 }
474
475
476 class FilterFieldAdapter implements DocumentListener {
477 public void filter() {
478 String expr = filterField.getText().trim();
479 if (expr.length()==0) { expr=null; }
480 try {
481 final TableRowSorter<? extends TableModel> sorter =
482 ((TableRowSorter<? extends TableModel> )shortcutTable.getRowSorter());
483 if (expr == null) {
484 sorter.setRowFilter(null);
485 } else {
486 // split search string on whitespace, do case-insensitive AND search
487 ArrayList<RowFilter<Object, Object>> andFilters = new ArrayList<RowFilter<Object, Object>>();
488 for (String word : expr.split("\\s+")) {
489 andFilters.add(RowFilter.regexFilter("(?i)" + word));
490 }
491 sorter.setRowFilter(RowFilter.andFilter(andFilters));
492 }
493 }
494 catch (PatternSyntaxException ex) { }
495 catch (ClassCastException ex2) { /* eliminate warning */ }
496 }
497
498 public void changedUpdate(DocumentEvent arg0) { filter(); }
499 public void insertUpdate(DocumentEvent arg0) { filter(); }
500 public void removeUpdate(DocumentEvent arg0) { filter(); }
501 }
502
503}
Note: See TracBrowser for help on using the repository browser.