1 9 package bluej.editor.moe; 10 11 import javax.swing.FocusManager ; 12 import java.awt.*; 13 import java.awt.event.*; 14 import javax.swing.*; import javax.swing.event.ListSelectionListener ; 17 import javax.swing.event.ListSelectionEvent ; 18 19 import java.util.Properties ; 20 21 import bluej.Config; 22 import bluej.utility.Debug; 23 import bluej.utility.DialogManager; 24 import bluej.utility.EscapeDialog; 25 import bluej.utility.FixedMultiLineLabel; 26 27 34 35 public final class FunctionDialog extends EscapeDialog 36 37 implements ActionListener, ListSelectionListener , ItemListener 38 { 39 41 static final String title = Config.getString("editor.functions.title"); 42 static final String close = Config.getString("close"); 43 static final String defaultsLabel = Config.getString("editor.functions.defaults"); 44 static final String categoriesLabel = Config.getString("editor.functions.categories"); 45 static final String keyLabel = Config.getString("editor.functions.keys"); 46 static final String addKeyLabel = Config.getString("editor.functions.addkey"); 47 static final String delKeyLabel = Config.getString("editor.functions.delkey"); 48 49 51 private FocusManager focusMgr; 52 private JButton defaultsButton; 53 private JButton closeButton; 54 private JButton addKeyButton; 55 private JButton delKeyButton; 56 private JComboBox categoryMenu; 57 private JList functionList; 58 private JList keyList; 59 private FixedMultiLineLabel helpLabel; 60 61 private MoeActions actions; private Action currentAction; private KeyStroke[] currentKeys; 65 private Action[] functions; private int[] categoryIndex; private int firstDisplayedFunc; private Properties help; 69 70 72 public FunctionDialog(JFrame parent, Action[] actiontable, 73 String [] categories, int[] categoryIndex) 74 { 75 super(parent, title, true); 76 focusMgr = FocusManager.getCurrentManager(); 77 actions = MoeActions.getActions(null); 78 currentAction = null; 79 currentKeys = null; 80 functions = actiontable; 81 this.categoryIndex = categoryIndex; 82 makeDialog(categories); 83 openHelpFile(); 84 } 85 86 89 private void handleClose() 90 { 91 removeKeyListener(); 92 if(!actions.save()) 93 DialogManager.showError(this, "cannot-save-keys"); 94 setVisible(false); 95 } 96 97 100 private void handleDefaults() 101 { 102 int answer = DialogManager.askQuestion(this, "default-keys"); 103 if(answer == 0) { 104 actions.setDefaultKeyBindings(); 105 handleFuncListSelect(); 106 } 107 } 108 109 112 private void handleFuncListSelect() 113 { 114 int index = functionList.getSelectedIndex(); 115 if(index == -1) 116 return; 118 120 currentAction = functions[firstDisplayedFunc + index]; 121 122 124 updateKeyList(currentAction); 125 String helpText = 126 getHelpText((String )currentAction.getValue(Action.NAME)); 127 helpLabel.setText(helpText); 128 } 129 130 133 private void handleKeyListSelect() 134 { 135 delKeyButton.setEnabled(true); 136 } 137 138 141 private void handleAddKey() 142 { 143 helpLabel.setText(getHelpText("press-key")); 144 addKeyListener(); 145 } 146 147 150 private void handleDelKey() 151 { 152 if(currentKeys == null) 153 return; 155 int index = keyList.getSelectedIndex(); 156 if(index == -1) 157 return; 159 actions.removeKeyStrokeBinding(currentKeys[index]); 160 updateKeyList(currentAction); 161 } 162 163 166 private void updateKeyList(Action action) 167 { 168 currentKeys = actions.getKeyStrokesForAction(action); 169 if(currentKeys == null) 170 clearKeyList(); 171 else { 172 String [] keyStrings = getKeyStrings(currentKeys); 173 keyList.setListData(keyStrings); 174 delKeyButton.setEnabled(false); 175 } 176 addKeyButton.setEnabled(true); 177 } 178 179 182 private String [] getKeyStrings(KeyStroke[] keys) 183 { 184 String [] keyStrings = new String [keys.length]; 185 for(int i = 0; i < keys.length; i++) { 186 int modifiers = keys[i].getModifiers(); 187 keyStrings[i] = KeyEvent.getKeyModifiersText(modifiers); 188 if(keyStrings[i].length() > 0) 189 keyStrings[i] += "+"; 190 keyStrings[i] += KeyEvent.getKeyText(keys[i].getKeyCode()); 191 } 192 return keyStrings; 193 } 194 195 private void clearKeyList() 196 { 197 keyList.setListData(new String [0]); 198 } 199 200 private void clearHelpText() 201 { 202 helpLabel.setText(null); 203 } 204 205 private void openHelpFile() 206 { 207 help = Config.getMoeHelp(); 208 } 209 210 private String getHelpText(String function) 211 { 212 if(help == null) 213 return null; 214 return help.getProperty(function); 215 } 216 217 private void addKeyListener() 218 { 219 FocusManager.setCurrentManager(new KeyCatcher()); 220 } 221 222 private void removeKeyListener() 223 { 224 FocusManager.setCurrentManager(focusMgr); 225 } 226 227 public boolean isFocusTraversable() 228 { 229 return true; 230 } 231 232 234 236 240 public void actionPerformed(ActionEvent event) 241 { 242 Object src = event.getSource(); 243 244 if(src == closeButton) 245 handleClose(); 246 else if(src == defaultsButton) 247 handleDefaults(); 248 else if(src == addKeyButton) 249 handleAddKey(); 250 else if(src == delKeyButton) 251 handleDelKey(); 252 } 253 254 256 259 public void itemStateChanged(ItemEvent evt) 260 { 261 int selected = categoryMenu.getSelectedIndex(); 262 263 firstDisplayedFunc = categoryIndex[selected]; 264 int lastFunc = categoryIndex[selected + 1]; 265 266 String [] names = new String [lastFunc - firstDisplayedFunc]; 267 268 for(int i = firstDisplayedFunc; i < lastFunc; i++) { 269 names[i-firstDisplayedFunc] = 270 (String )functions[i].getValue(Action.NAME); 271 } 272 functionList.setListData(names); 273 clearKeyList(); 274 clearHelpText(); 275 addKeyButton.setEnabled(false); 276 delKeyButton.setEnabled(false); 277 currentAction = null; 278 currentKeys = null; 279 } 280 281 283 286 public void valueChanged(ListSelectionEvent event) 287 { 288 if(event.getValueIsAdjusting()) return; 290 291 Object src = event.getSource(); 292 293 if(src == functionList) 294 handleFuncListSelect(); 295 else if(src == keyList) 296 handleKeyListSelect(); 297 } 298 299 301 private void makeDialog(String [] categories) 302 { 303 JPanel mainPanel = (JPanel)getContentPane(); mainPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); 305 306 308 JPanel helpPanel = new JPanel(new GridLayout()); 309 helpPanel.setBorder(BorderFactory.createCompoundBorder( 310 BorderFactory.createEmptyBorder(10,0,0,0), 311 BorderFactory.createLineBorder(Color.black))); 312 helpLabel = new FixedMultiLineLabel(4); 313 helpLabel.setBackground(MoeEditor.infoColor); 314 helpPanel.add(helpLabel); 315 mainPanel.add(helpPanel, BorderLayout.SOUTH); 316 317 319 JPanel controlPanel = new JPanel(new BorderLayout()); 320 321 323 JPanel buttonPanel = new JPanel(); 324 buttonPanel.setLayout(new GridLayout(0,1,5,5)); 325 326 closeButton = new JButton(close); 327 closeButton.addActionListener(this); 328 buttonPanel.add(closeButton); 329 330 defaultsButton = new JButton(defaultsLabel); 331 defaultsButton.addActionListener(this); 332 buttonPanel.add(defaultsButton); 333 334 JPanel buttonFramePanel = new JPanel(); 335 buttonFramePanel.setLayout(new BorderLayout(0,0)); 336 buttonFramePanel.add(buttonPanel, BorderLayout.NORTH); 338 339 controlPanel.add(buttonFramePanel, BorderLayout.EAST); 340 341 343 JPanel keyPanel = new JPanel(); 344 keyPanel.setLayout(new BorderLayout()); 345 keyPanel.setBorder(BorderFactory.createTitledBorder( 346 BorderFactory.createEtchedBorder(), 347 keyLabel)); 348 349 keyList = new JList(); 350 keyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 351 keyList.setPrototypeCellValue("shift-ctrl-delete"); 352 keyList.addListSelectionListener(this); 353 keyList.setVisibleRowCount(4); 354 JScrollPane scrollPane; 355 scrollPane = new JScrollPane(keyList); 356 keyPanel.add(scrollPane, BorderLayout.CENTER); 357 358 JPanel keyButtonPanel = new JPanel(); 359 addKeyButton = new JButton(addKeyLabel); 360 addKeyButton.addActionListener(this); 361 addKeyButton.setMargin(new Insets(2,2,2,2)); 362 keyButtonPanel.add(addKeyButton); 363 364 delKeyButton = new JButton(delKeyLabel); 365 delKeyButton.addActionListener(this); 366 delKeyButton.setMargin(new Insets(2,2,2,2)); 367 keyButtonPanel.add(delKeyButton); 368 369 keyPanel.add(keyButtonPanel, BorderLayout.SOUTH); 370 371 controlPanel.add(keyPanel, BorderLayout.SOUTH); 372 373 mainPanel.add(controlPanel, BorderLayout.EAST); 374 375 377 JPanel funcPanel = new JPanel(new BorderLayout()); 378 funcPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,10)); 379 380 functionList = new JList(); 381 functionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 382 functionList.addListSelectionListener(this); 383 functionList.setVisibleRowCount(12); 384 scrollPane = new JScrollPane(functionList); 385 386 funcPanel.add(scrollPane, BorderLayout.CENTER); 387 388 JPanel categoryPanel = new JPanel(); 389 390 JLabel label = new JLabel(categoriesLabel); 391 categoryPanel.add(label); 392 categoryMenu = new JComboBox(); 393 categoryMenu.addItemListener(this); 394 for(int i=0; i<categories.length; i++) 395 categoryMenu.addItem(categories[i]); 396 categoryPanel.add(categoryMenu); 397 398 funcPanel.add(categoryPanel, BorderLayout.NORTH); 399 400 mainPanel.add(funcPanel, BorderLayout.CENTER); 401 getRootPane().setDefaultButton(closeButton); 402 403 addWindowListener(new WindowAdapter() { 404 public void windowClosing(WindowEvent E) { 405 setVisible(false); 406 } 407 }); 408 409 pack(); 410 DialogManager.centreDialog(this); 411 } 412 413 414 class KeyCatcher extends FocusManager { 415 416 public void processKeyEvent(Component focusedComponent, 417 KeyEvent e) 418 { 419 if(e.getID() != KeyEvent.KEY_PRESSED) 420 return; 421 422 int keyCode = e.getKeyCode(); 423 424 if(keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_SHIFT || 426 keyCode == KeyEvent.VK_CONTROL || 427 keyCode == KeyEvent.VK_META || 428 keyCode == KeyEvent.VK_ALT || 429 keyCode == KeyEvent.VK_ALT_GRAPH || 430 keyCode == KeyEvent.VK_COMPOSE || 431 keyCode == KeyEvent.VK_NUM_LOCK || 432 keyCode == KeyEvent.VK_SCROLL_LOCK || 433 keyCode == KeyEvent.VK_UNDEFINED 434 ) 435 return; 436 437 if(currentAction == null) 438 Debug.message("FunctionDialog: currentAction is null..."); 439 else { 440 KeyStroke key = KeyStroke.getKeyStrokeForEvent(e); 441 if(isPrintable(key, e)) 442 helpLabel.setText(getHelpText("cannot-redefine")); 443 else { 444 actions.addActionForKeyStroke(key, currentAction); 445 handleFuncListSelect(); 446 } 447 } 448 e.consume(); 449 removeKeyListener(); 450 } 451 452 private boolean isPrintable(KeyStroke key, KeyEvent e) 453 { 454 int modifiers = key.getModifiers(); 456 if(modifiers != 0 && modifiers != Event.SHIFT_MASK) 457 return false; 458 459 if(e.isActionKey()) 461 return false; 462 463 int keyCode = e.getKeyCode(); 465 if(keyCode == KeyEvent.VK_BACK_SPACE || 466 keyCode == KeyEvent.VK_DELETE || 467 keyCode == KeyEvent.VK_ENTER || 468 keyCode == KeyEvent.VK_TAB || 469 keyCode == KeyEvent.VK_ESCAPE) 470 return false; 471 472 return true; 474 } 475 476 public void focusNextComponent(Component c) {} 477 public void focusPreviousComponent(Component c) {} 478 } 479 480 } | Popular Tags |