1 19 20 package org.netbeans.modules.debugger.jpda.ui; 21 22 import java.awt.Component ; 23 import java.awt.Dialog ; 24 import java.awt.Dimension ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 import java.awt.event.FocusEvent ; 28 import java.awt.event.FocusListener ; 29 import java.awt.event.ItemEvent ; 30 import java.awt.event.ItemListener ; 31 import java.beans.PropertyChangeEvent ; 32 import java.lang.reflect.Method ; 33 import java.util.ArrayList ; 34 import java.util.Collections ; 35 import java.util.List ; 36 import javax.swing.ComboBoxEditor ; 37 import javax.swing.JComponent ; 38 import javax.swing.JEditorPane ; 39 import javax.swing.JScrollPane ; 40 import javax.swing.text.JTextComponent ; 41 import org.netbeans.api.debugger.DebuggerEngine; 42 import org.netbeans.api.debugger.DebuggerManager; 43 import org.netbeans.api.debugger.DebuggerManagerAdapter; 44 import org.netbeans.api.debugger.DebuggerManagerListener; 45 import org.netbeans.api.debugger.Session; 46 import org.netbeans.api.debugger.jpda.InvalidExpressionException; 47 import org.netbeans.api.debugger.jpda.JPDADebugger; 48 import org.netbeans.api.debugger.jpda.Variable; 49 import org.netbeans.modules.debugger.jpda.ui.models.WatchesNodeModel; 50 import org.netbeans.spi.viewmodel.ColumnModel; 51 import org.netbeans.spi.viewmodel.Model; 52 import org.netbeans.spi.viewmodel.ModelListener; 53 import org.netbeans.spi.viewmodel.Models; 54 import org.netbeans.spi.viewmodel.Models.CompoundModel; 55 import org.netbeans.spi.viewmodel.NodeActionsProvider; 56 import org.netbeans.spi.viewmodel.NodeActionsProviderFilter; 57 import org.netbeans.spi.viewmodel.NodeModel; 58 import org.netbeans.spi.viewmodel.NodeModelFilter; 59 import org.netbeans.spi.viewmodel.TableModel; 60 import org.netbeans.spi.viewmodel.TableModelFilter; 61 import org.netbeans.spi.viewmodel.TreeExpansionModel; 62 import org.netbeans.spi.viewmodel.TreeModel; 63 import org.netbeans.spi.viewmodel.TreeModelFilter; 64 import org.netbeans.spi.viewmodel.UnknownTypeException; 65 import org.openide.DialogDescriptor; 66 import org.openide.DialogDisplayer; 67 import org.openide.NotifyDescriptor; 68 import org.openide.awt.Mnemonics; 69 import org.openide.util.HelpCtx; 70 import org.openide.util.NbBundle; 71 import org.openide.util.RequestProcessor; 72 73 78 public class Evaluator extends javax.swing.JPanel { 79 80 81 private static final int MAX_ITEMS_TO_KEEP = 20; 82 83 private JPDADebugger debugger; 84 private EvaluatorModelListener viewModelListener; 85 private Variable result; 86 private RequestProcessor.Task evalTask = 87 new RequestProcessor("Debugger Evaluator", 1). create(new EvaluateTask()); 89 private boolean ignoreEvents = false; 90 private SessionListener sessionListener; 91 92 93 public Evaluator(JPDADebugger debugger) { 94 this.debugger = debugger; 95 initComponents(); 96 initCombo(); 97 initResult(); 98 expressionLabel.setLabelFor(expressionComboBox); 99 Mnemonics.setLocalizedText(expressionLabel, 100 NbBundle.getMessage(Evaluator.class, "Evaluator.Expression")); 101 resultLabel.setLabelFor(resultPanel); 102 Mnemonics.setLocalizedText(resultLabel, 103 NbBundle.getMessage(Evaluator.class, "Evaluator.Result")); 104 sessionListener = new SessionListener(); 105 DebuggerManager.getDebuggerManager().addDebuggerListener( 106 DebuggerManager.PROP_CURRENT_SESSION, sessionListener); 107 } 108 109 114 private void initComponents() { 116 java.awt.GridBagConstraints gridBagConstraints; 117 118 expressionLabel = new javax.swing.JLabel (); 119 expressionComboBox = new javax.swing.JComboBox (); 120 resultLabel = new javax.swing.JLabel (); 121 resultPanel = new javax.swing.JPanel (); 122 123 setLayout(new java.awt.GridBagLayout ()); 124 125 expressionLabel.setText(org.openide.util.NbBundle.getMessage(Evaluator.class, "Evaluator.Expression")); 126 gridBagConstraints = new java.awt.GridBagConstraints (); 127 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 128 gridBagConstraints.insets = new java.awt.Insets (11, 11, 0, 12); 129 add(expressionLabel, gridBagConstraints); 130 131 expressionComboBox.addItemListener(new java.awt.event.ItemListener () { 132 public void itemStateChanged(java.awt.event.ItemEvent evt) { 133 expressionComboBoxItemStateChanged(evt); 134 } 135 }); 136 expressionComboBox.addActionListener(new java.awt.event.ActionListener () { 137 public void actionPerformed(java.awt.event.ActionEvent evt) { 138 expressionComboBoxActionPerformed(evt); 139 } 140 }); 141 142 gridBagConstraints = new java.awt.GridBagConstraints (); 143 gridBagConstraints.gridy = 1; 144 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 145 gridBagConstraints.weightx = 1.0; 146 gridBagConstraints.insets = new java.awt.Insets (11, 11, 12, 12); 147 add(expressionComboBox, gridBagConstraints); 148 149 resultLabel.setText(org.openide.util.NbBundle.getMessage(Evaluator.class, "Evaluator.Result")); 150 gridBagConstraints = new java.awt.GridBagConstraints (); 151 gridBagConstraints.gridy = 2; 152 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 153 gridBagConstraints.insets = new java.awt.Insets (0, 11, 11, 12); 154 add(resultLabel, gridBagConstraints); 155 156 resultPanel.setLayout(new javax.swing.BoxLayout (resultPanel, javax.swing.BoxLayout.X_AXIS)); 157 158 gridBagConstraints = new java.awt.GridBagConstraints (); 159 gridBagConstraints.gridy = 3; 160 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 161 gridBagConstraints.weightx = 1.0; 162 gridBagConstraints.weighty = 1.0; 163 gridBagConstraints.insets = new java.awt.Insets (0, 11, 12, 12); 164 add(resultPanel, gridBagConstraints); 165 166 } 167 169 private void expressionComboBoxItemStateChanged(java.awt.event.ItemEvent evt) { if (ignoreEvents) return ; 173 evaluate(); 174 } 176 private void expressionComboBoxActionPerformed(java.awt.event.ActionEvent evt) { } 181 private void initCombo() { 182 expressionComboBox.setEditor(new CompletionedEditor()); 183 expressionComboBox.setEditable(true); 184 } 185 186 private void initResult() { 187 javax.swing.JComponent tree = Models.createView (Models.EMPTY_MODEL); 188 resultPanel.add (tree, "Center"); viewModelListener = new EvaluatorModelListener ( 190 tree 191 ); 192 Dimension tps = tree.getPreferredSize(); 193 tps.height = tps.width/2; 194 tree.setPreferredSize(tps); 195 } 196 197 private void destroy() { 198 viewModelListener.destroy(); 199 } 200 201 private javax.swing.JComboBox expressionComboBox; 203 private javax.swing.JLabel expressionLabel; 204 private javax.swing.JLabel resultLabel; 205 private javax.swing.JPanel resultPanel; 206 208 209 public String getExpression() { 210 String textInEditor = 211 (String ) expressionComboBox.getEditor().getItem(); 212 String exp = (String ) expressionComboBox.getSelectedItem(); 213 if (textInEditor != null && !textInEditor.equals(exp)) { 214 try { 215 ignoreEvents = true; 216 expressionComboBox.setSelectedItem(textInEditor); 217 exp = textInEditor; 218 } finally { 219 ignoreEvents = false; 220 } 221 } 222 return exp; 223 } 224 225 228 private void evaluate() { 229 evalTask.schedule(10); 232 } 233 234 private void addExpressionToHistory(String exp) { 235 try { 236 ignoreEvents = true; 237 int ic = expressionComboBox.getItemCount(); 238 int i; 239 for (i = 0; i < ic; i++) { 240 String item = (String ) expressionComboBox.getItemAt(i); 241 if (item.equals(exp)) { 242 expressionComboBox.removeItemAt(i); 243 break; 244 } 245 } 246 if (i >= MAX_ITEMS_TO_KEEP) { 247 expressionComboBox.removeItemAt(i-1); 248 } 249 if (ic > 0) { 250 expressionComboBox.insertItemAt(exp, 0); 251 } else { 252 expressionComboBox.addItem(exp); 253 } 254 expressionComboBox.setSelectedItem(exp); 258 } finally { 259 ignoreEvents = false; 260 } 261 } 262 263 private void displayResult(Variable var) { 264 this.result = var; 265 viewModelListener.updateModel(); 267 } 268 269 private static Dialog evalDialog; 270 271 private static volatile Evaluator currentEvaluator; 272 273 public static void open(JPDADebugger debugger) { 274 if (evalDialog != null) { 275 evalDialog.setVisible(true); 276 evalDialog.requestFocus(); 277 requestFocusForExpression(); 278 return ; 279 } 280 final Evaluator evaluatorPanel = new Evaluator(debugger); 281 final String evalStr = NbBundle.getMessage(Evaluator.class, "Evaluator.Evaluate"); 282 final String watchStr = NbBundle.getMessage(Evaluator.class, "Evaluator.Watch"); 283 final String closeStr = NbBundle.getMessage(Evaluator.class, "Evaluator.Close"); 284 DialogDescriptor dd = new DialogDescriptor(evaluatorPanel, 285 NbBundle.getMessage(Evaluator.class, "Evaluator.Title"), 286 false, new Object [] { evalStr, watchStr, closeStr }, 287 evalStr, DialogDescriptor.DEFAULT_ALIGN, 288 new HelpCtx(Evaluator.class.getName()), new ActionListener () { 289 public void actionPerformed(ActionEvent e) { 290 Object option = e.getSource(); 291 if (evalStr.equals(option)) { 292 evaluatorPanel.evaluate(); 293 } else if (watchStr.equals(option)) { 294 DebuggerManager.getDebuggerManager ().createWatch (evaluatorPanel.getExpression ()); 295 } else if (closeStr.equals(option)) { 296 close(); 297 } 298 } 299 }); 300 evalDialog = DialogDisplayer.getDefault().createDialog(dd); 301 evalDialog.getAccessibleContext().setAccessibleDescription( 302 NbBundle.getMessage(Evaluator.class, "Evaluator.A11YDescr")); 303 currentEvaluator = evaluatorPanel; 304 evalDialog.setVisible(true); 305 requestFocusForExpression(); 306 } 307 308 private static void requestFocusForExpression() { 309 Component c = currentEvaluator.expressionComboBox.getEditor().getEditorComponent(); 310 if (c instanceof JScrollPane ) { 311 c = ((JScrollPane ) c).getViewport().getView(); 312 } 313 c.requestFocusInWindow(); 314 } 315 316 private static void close() { 317 evalDialog.setVisible(false); 319 try { 320 currentEvaluator.ignoreEvents = true; 321 currentEvaluator.expressionComboBox.setSelectedItem(""); } finally { 324 currentEvaluator.ignoreEvents = false; 325 } 326 currentEvaluator.result = null; 328 currentEvaluator.viewModelListener.updateModel(); 329 334 } 335 336 private class SessionListener extends DebuggerManagerAdapter { 337 338 private boolean autoClosed = false; 339 340 public void propertyChange(PropertyChangeEvent evt) { 341 Session currentSession = DebuggerManager.getDebuggerManager().getCurrentSession(); 342 if (currentSession != null && "Java".equals(currentSession.getCurrentLanguage())) { 343 if (autoClosed) { 344 DebuggerEngine de = DebuggerManager.getDebuggerManager().getCurrentEngine(); 345 if (de == null) return ; 346 JPDADebugger debugger = (JPDADebugger) de.lookupFirst(null, JPDADebugger.class); 347 if (debugger == null) return ; 348 open(debugger); 349 autoClosed = false; 350 } 351 } else { 352 if (evalDialog.isVisible()) { 353 autoClosed = true; 354 close(); 355 } 356 } 357 } 358 359 } 360 361 private class EvaluateTask implements Runnable { 362 public void run() { 363 String exp = getExpression(); 364 if (exp == null || "".equals(exp)) { 365 return ; 367 } 368 try { 370 Variable var = debugger.evaluate(exp); 371 addExpressionToHistory(exp); 372 displayResult(var); 373 } catch (InvalidExpressionException ieex) { 374 DialogDisplayer.getDefault().notify( 375 new NotifyDescriptor.Message(ieex.getLocalizedMessage())); 376 } 377 } 378 } 379 380 private static final class CompletionedEditor implements ComboBoxEditor { 381 382 private JEditorPane editor; 383 private java.awt.Component component; 384 private Object oldValue; 385 386 public CompletionedEditor() { 387 editor = new JEditorPane ("text/x-java", ""); editor.setBorder(null); 389 editor.setKeymap(new FilteredKeymap(editor.getKeymap())); 390 component = new JScrollPane (editor, 391 JScrollPane.VERTICAL_SCROLLBAR_NEVER, 392 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 393 editor.addFocusListener(new FocusListener () { 394 public void focusGained(FocusEvent e) { 395 WatchPanel.setupContext(editor); 396 } 397 public void focusLost(FocusEvent e) { 398 } 399 }); 400 } 401 402 public void addActionListener(java.awt.event.ActionListener actionListener) { 403 } 404 405 public void removeActionListener(java.awt.event.ActionListener actionListener) { 406 } 407 408 public java.awt.Component getEditorComponent() { 409 return component; 410 } 411 412 public Object getItem() { 413 Object newValue = editor.getText(); 414 415 if (oldValue != null && !(oldValue instanceof String )) { 416 if (newValue.equals(oldValue.toString())) { 419 return oldValue; 420 } else { 421 Class cls = oldValue.getClass(); 423 try { 424 Method method = cls.getMethod("valueOf", new Class []{String .class}); 425 newValue = method.invoke(oldValue, new Object [] { editor.getText()}); 426 } catch (Exception ex) { 427 } 429 } 430 } 431 return newValue; 432 } 433 434 public void setItem(Object obj) { 435 if (obj != null) { 436 editor.setText(obj.toString()); 437 438 oldValue = obj; 439 } else { 440 editor.setText(""); 441 } 442 } 443 444 public void selectAll() { 445 editor.selectAll(); 446 editor.requestFocus(); 447 } 448 449 } 450 451 454 private static class EvaluatorModelListener extends DebuggerManagerAdapter { 455 456 private String viewType; 457 private JComponent view; 458 private List models = new ArrayList (11); 459 460 461 public EvaluatorModelListener(JComponent view) { 462 this.viewType = "LocalsView"; this.view = view; 464 DebuggerManager.getDebuggerManager ().addDebuggerListener ( 465 DebuggerManager.PROP_CURRENT_ENGINE, 466 this 467 ); 468 updateModel (); 469 } 470 471 public void destroy () { 472 DebuggerManager.getDebuggerManager ().removeDebuggerListener ( 473 DebuggerManager.PROP_CURRENT_ENGINE, 474 this 475 ); 476 Models.setModelsToView ( 477 view, 478 Models.EMPTY_MODEL 479 ); 480 } 481 482 public void propertyChange (PropertyChangeEvent e) { 483 Evaluator eval = currentEvaluator; 484 if (eval != null) { 485 DebuggerEngine de = DebuggerManager.getDebuggerManager().getCurrentEngine(); 486 if (de == null) return ; 487 JPDADebugger debugger = (JPDADebugger) de.lookupFirst(null, JPDADebugger.class); 488 eval.debugger = debugger; 489 } 490 updateModel (); 491 } 492 493 private List joinLookups(DebuggerEngine e, DebuggerManager dm, Class service) { 494 List es = e.lookup (viewType, service); 495 List ms = dm.lookup(viewType, service); 496 ms.removeAll(es); 497 es.addAll(ms); 498 return es; 499 } 500 501 public synchronized void updateModel () { 502 DebuggerManager dm = DebuggerManager.getDebuggerManager (); 503 DebuggerEngine e = dm.getCurrentEngine (); 504 505 List treeModels; 506 List treeModelFilters; 507 List treeExpansionModels; 508 List nodeModels; 509 List nodeModelFilters; 510 List tableModels; 511 List tableModelFilters; 512 List nodeActionsProviders; 513 List nodeActionsProviderFilters; 514 List columnModels; 515 List mm; 516 if (e != null) { 517 treeModels = joinLookups(e, dm, TreeModel.class); 518 treeModelFilters = joinLookups(e, dm, TreeModelFilter.class); 519 treeExpansionModels = joinLookups(e, dm, TreeExpansionModel.class); 520 nodeModels = joinLookups(e, dm, NodeModel.class); 521 nodeModelFilters = joinLookups(e, dm, NodeModelFilter.class); 522 tableModels = joinLookups(e, dm, TableModel.class); 523 tableModelFilters = joinLookups(e, dm, TableModelFilter.class); 524 nodeActionsProviders = joinLookups(e, dm, NodeActionsProvider.class); 525 nodeActionsProviderFilters = joinLookups(e, dm, NodeActionsProviderFilter.class); 526 columnModels = joinLookups(e, dm, ColumnModel.class); 527 mm = joinLookups(e, dm, Model.class); 528 } else { 529 treeModels = dm.lookup (viewType, TreeModel.class); 530 treeModelFilters = dm.lookup (viewType, TreeModelFilter.class); 531 treeExpansionModels = dm.lookup (viewType, TreeExpansionModel.class); 532 nodeModels = dm.lookup (viewType, NodeModel.class); 533 nodeModelFilters = dm.lookup (viewType, NodeModelFilter.class); 534 tableModels = dm.lookup (viewType, TableModel.class); 535 tableModelFilters = dm.lookup (viewType, TableModelFilter.class); 536 nodeActionsProviders = dm.lookup (viewType, NodeActionsProvider.class); 537 nodeActionsProviderFilters = dm.lookup (viewType, NodeActionsProviderFilter.class); 538 columnModels = dm.lookup (viewType, ColumnModel.class); 539 mm = dm.lookup (viewType, Model.class); 540 } 541 542 List treeNodeModelsCompound = new ArrayList (11); 543 treeNodeModelsCompound.add(treeModels); 544 for (int i = 0; i < 2; i++) { 545 treeNodeModelsCompound.add(Collections.EMPTY_LIST); 546 } 547 treeNodeModelsCompound.add(nodeModels); 548 for (int i = 0; i < 7; i++) { 549 treeNodeModelsCompound.add(Collections.EMPTY_LIST); 550 } 551 CompoundModel treeNodeModel = Models.createCompoundModel(treeNodeModelsCompound); 552 564 EvaluatorModel eTreeNodeModel = new EvaluatorModel(treeNodeModel, treeNodeModel); 565 566 models.clear(); 567 treeModels.clear(); 568 treeModels.add(eTreeNodeModel); 569 models.add(treeModels); 570 models.add(treeModelFilters); 571 models.add(treeExpansionModels); 572 nodeModels.clear(); 573 nodeModels.add(eTreeNodeModel); 574 models.add(nodeModels); 575 models.add(nodeModelFilters); 576 models.add(tableModels); 577 models.add(tableModelFilters); 578 models.add(nodeActionsProviders); 579 models.add(nodeActionsProviderFilters); 580 models.add(columnModels); 581 models.add(mm); 582 583 Models.setModelsToView ( 584 view, 585 Models.createCompoundModel (models) 586 ); 587 } 588 589 } 590 591 private static class EvaluatorModel implements TreeModel, NodeModel { 592 593 private CompoundModel treeModel; 594 private CompoundModel nodeModel; 595 596 public EvaluatorModel(CompoundModel treeModel, CompoundModel nodeModel) { 597 this.treeModel = treeModel; 598 this.nodeModel = nodeModel; 599 } 600 601 public void addModelListener(ModelListener l) { 602 treeModel.addModelListener(l); 603 } 604 605 public Object [] getChildren(Object parent, int from, int to) throws UnknownTypeException { 606 if (TreeModel.ROOT.equals(parent)) { 607 Evaluator eval = currentEvaluator; 608 if (eval == null || eval.result == null) { 609 return new Object [] {}; 610 } else { 611 return new Object [] { eval.result }; 612 } 613 } else { 614 return treeModel.getChildren(parent, from, to); 615 } 616 } 617 618 public int getChildrenCount(Object node) throws UnknownTypeException { 619 if (TreeModel.ROOT.equals(node)) { 620 return currentEvaluator == null ? 0 : 1; 621 } else { 622 return treeModel.getChildrenCount(node); 623 } 624 } 625 626 public Object getRoot() { 627 return TreeModel.ROOT; 628 } 629 630 public boolean isLeaf(Object node) throws UnknownTypeException { 631 if (TreeModel.ROOT.equals(node)) { 632 return false; 633 } else { 634 return treeModel.isLeaf(node); 635 } 636 } 637 638 public void removeModelListener(ModelListener l) { 639 treeModel.removeModelListener(l); 640 } 641 642 public String getDisplayName(Object node) throws UnknownTypeException { 643 Evaluator eval = currentEvaluator; 644 if (eval != null && eval.result != null) { 645 if (node == eval.result) { 646 return eval.getExpression(); 647 } 648 } 649 return nodeModel.getDisplayName(node); 650 } 651 652 public String getIconBase(Object node) throws UnknownTypeException { 653 Evaluator eval = currentEvaluator; 654 if (eval != null && eval.result != null) { 655 if (node == eval.result) { 656 return WatchesNodeModel.WATCH; 657 } 658 } 659 return nodeModel.getIconBase(node); 660 } 661 662 public String getShortDescription(Object node) throws UnknownTypeException { 663 Evaluator eval = currentEvaluator; 664 if (eval != null && eval.result != null) { 665 if (node == eval.result) { 666 return eval.getExpression(); 667 } 668 } 669 return nodeModel.getShortDescription(node); 670 } 671 } 672 673 } 674 | Popular Tags |