KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > ui > DebugPanel


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  *END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.ui;
35
36 import java.util.Vector JavaDoc;
37
38 import java.util.Enumeration JavaDoc;
39
40 import javax.swing.*;
41 import javax.swing.tree.*;
42 import javax.swing.table.*;
43 import java.awt.event.*;
44 import java.awt.*;
45
46 import edu.rice.cs.drjava.model.SingleDisplayModel;
47 import edu.rice.cs.drjava.model.debug.*;
48 import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
49 import edu.rice.cs.drjava.config.*;
50 import edu.rice.cs.util.swing.Utilities;
51 import edu.rice.cs.util.swing.RightClickMouseAdapter;
52
53 /**
54  * Panel for displaying the debugger input and output in MainFrame. This
55  * class is a swing view class and hence should only be accessed from the
56  * event-handling thread.
57  * @version $Id: DebugPanel.java 4027 2006-11-02 04:00:17Z rcartwright $
58  */

59 public class DebugPanel extends JPanel implements OptionConstants {
60
61   private JSplitPane _tabsPane;
62   private JTabbedPane _leftPane;
63   private JTabbedPane _rightPane;
64   private JPanel _tabsAndStatusPane;
65
66   private JTable _watchTable;
67   private JTable _stackTable;
68   private JTable _threadTable;
69   private long _currentThreadID;
70
71   // private JPopupMenu _threadRunningPopupMenu;
72
private JPopupMenu _threadSuspendedPopupMenu;
73   private JPopupMenu _stackPopupMenu;
74   private JPopupMenu _watchPopupMenu;
75   private DebugThreadData _threadInPopup;
76
77   private final SingleDisplayModel _model;
78   private final MainFrame _frame;
79   private final Debugger _debugger;
80
81   private JPanel _buttonPanel;
82   private JButton _closeButton;
83   private JButton _resumeButton;
84   private JButton _stepIntoButton;
85   private JButton _stepOverButton;
86   private JButton _stepOutButton;
87   private JLabel _statusBar;
88
89   private Vector JavaDoc<DebugWatchData> _watches;
90   private Vector JavaDoc<DebugThreadData> _threads;
91   private Vector JavaDoc<DebugStackData> _stackFrames;
92   
93   private DefaultTreeCellRenderer dtcr;
94
95   /** Constructs a new panel to display debugging information when the Debugger is active. This is swing view class and hence should only
96    * be accessed from the event-handling thread.
97    */

98   public DebugPanel(MainFrame frame) {
99
100     this.setLayout(new BorderLayout());
101
102     _frame = frame;
103     _model = frame.getModel();
104     _debugger = _model.getDebugger();
105
106     _watches = new Vector JavaDoc<DebugWatchData>();
107     _threads = new Vector JavaDoc<DebugThreadData>();
108     _stackFrames = new Vector JavaDoc<DebugStackData>();
109     _leftPane = new JTabbedPane();
110     _rightPane = new JTabbedPane();
111
112     _setupTabPanes();
113
114     _tabsPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, _leftPane, _rightPane);
115     _tabsPane.setOneTouchExpandable(true);
116     _tabsPane.setDividerLocation((int)(_frame.getWidth()/2.5));
117
118     _tabsAndStatusPane = new JPanel(new BorderLayout());
119     _tabsAndStatusPane.add(_tabsPane, BorderLayout.CENTER);
120
121     _statusBar = new JLabel("");
122     _statusBar.setForeground(Color.blue.darker());
123
124     _tabsAndStatusPane.add(_statusBar, BorderLayout.SOUTH);
125
126     this.add(_tabsAndStatusPane, BorderLayout.CENTER);
127
128     _buttonPanel = new JPanel(new BorderLayout());
129     _setupButtonPanel();
130     this.add(_buttonPanel, BorderLayout.EAST);
131
132     _debugger.addListener(new DebugPanelListener());
133
134     // Setup the color listeners.
135
_setColors(_watchTable);
136     _setColors(_stackTable);
137     _setColors(_threadTable);
138   }
139
140   /** Quick helper for setting up color listeners. */
141   private static void _setColors(Component c) {
142     new ForegroundColorListener(c);
143     new BackgroundColorListener(c);
144   }
145
146   /** Causes all display tables to update their information from the debug manager. */
147   public void updateData() {
148     assert EventQueue.isDispatchThread();
149     if (_debugger.isReady()) {
150       try {
151         _watches = _debugger.getWatches();
152         
153         if (_debugger.isCurrentThreadSuspended()) _stackFrames = _debugger.getCurrentStackFrameData();
154         else _stackFrames = new Vector JavaDoc<DebugStackData>();
155         
156         _threads = _debugger.getCurrentThreadData();
157       }
158       catch (DebugException de) {
159         // Thrown if
160
_frame._showDebugError(de);
161       }
162     }
163     else {
164       // Clean up if debugger dies
165
_watches = new Vector JavaDoc<DebugWatchData>();
166       _threads = new Vector JavaDoc<DebugThreadData>();
167       _stackFrames = new Vector JavaDoc<DebugStackData>();
168     }
169
170     ((AbstractTableModel)_watchTable.getModel()).fireTableDataChanged();
171     ((AbstractTableModel)_stackTable.getModel()).fireTableDataChanged();
172     ((AbstractTableModel)_threadTable.getModel()).fireTableDataChanged();
173   }
174
175
176   /** Creates the tabbed panes in the debug panel. */
177   private void _setupTabPanes() {
178
179     // Watches table
180
_initWatchTable();
181
182     // Stack table
183
_stackTable = new JTable( new StackTableModel());
184     _stackTable.addMouseListener(new StackMouseAdapter());
185
186     _rightPane.addTab("Stack", new JScrollPane(_stackTable));
187
188     // Thread table
189
_initThreadTable();
190
191     // Sets the method column to always be 7 times as wide as the line column
192
TableColumn methodColumn;
193     TableColumn lineColumn;
194     methodColumn = _stackTable.getColumnModel().getColumn(0);
195     lineColumn = _stackTable.getColumnModel().getColumn(1);
196     methodColumn.setPreferredWidth(7*lineColumn.getPreferredWidth());
197
198     _initPopup();
199   }
200
201   private void _initWatchTable() {
202     _watchTable = new JTable( new WatchTableModel());
203     _watchTable.setDefaultEditor(_watchTable.getColumnClass(0), new WatchEditor());
204     _watchTable.setDefaultRenderer(_watchTable.getColumnClass(0), new WatchRenderer());
205
206     _leftPane.addTab("Watches", new JScrollPane(_watchTable));
207   }
208
209   private void _initThreadTable() {
210     _threadTable = new JTable(new ThreadTableModel());
211     _threadTable.addMouseListener(new ThreadMouseAdapter());
212     _rightPane.addTab("Threads", new JScrollPane(_threadTable));
213
214     // Sets the name column to always be 2 times as wide as the status column
215
TableColumn nameColumn;
216     TableColumn statusColumn;
217     nameColumn = _threadTable.getColumnModel().getColumn(0);
218     statusColumn = _threadTable.getColumnModel().getColumn(1);
219     nameColumn.setPreferredWidth(2*statusColumn.getPreferredWidth());
220
221     // Adds a cell renderer to the threads table
222
_currentThreadID = 0;
223     TableCellRenderer threadTableRenderer = new DefaultTableCellRenderer() {
224       public Component getTableCellRendererComponent(JTable table, Object JavaDoc value, boolean isSelected,
225                                                      boolean hasFocus, int row, int column) {
226         Component renderer =
227           super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
228
229         _setThreadCellFont(row);
230
231         return renderer;
232       }
233
234       /**
235        * Sets the font for a cell in the thread table.
236        * @param row the current row
237        */

238       private void _setThreadCellFont(int row) {
239         DebugThreadData currThread = _threads.get(row);
240         if (currThread.getUniqueID() == _currentThreadID &&
241             currThread.isSuspended()) {
242           setFont(getFont().deriveFont(Font.BOLD));
243         }
244       }
245     };
246     _threadTable.getColumnModel().getColumn(0).setCellRenderer(threadTableRenderer);
247     _threadTable.getColumnModel().getColumn(1).setCellRenderer(threadTableRenderer);
248   }
249
250   /** Adds config color support to DefaultCellEditor. */
251   private static class WatchEditor extends DefaultCellEditor {
252
253     WatchEditor() { super(new JTextField()); }
254
255     /**
256      * Overrides the default editor component to use proper coloring.
257      */

258     public Component getTableCellEditorComponent
259         (JTable table, Object JavaDoc value, boolean isSelected, int row, int column) {
260       Component editor = super.getTableCellEditorComponent
261         (table, value, isSelected, row, column);
262       _setColors(editor);
263       return editor;
264     }
265   }
266
267   /** Adds config color support to DefaultTableCellRenderer. */
268   private class WatchRenderer extends DefaultTableCellRenderer {
269
270     /**
271      * Overrides the default rederer component to use proper coloring.
272      */

273     public Component getTableCellRendererComponent
274         (JTable table, Object JavaDoc value, boolean isSelected, boolean hasFocus,
275          int row, int column) {
276       Component renderer = super.getTableCellRendererComponent
277         (table, value, isSelected, hasFocus, row, column);
278       _setColors(renderer);
279       _setWatchCellFont(row);
280       return renderer;
281     }
282
283     /**
284      * Sets the font for a cell in the watch table.
285      * @param row the current row
286      */

287     private void _setWatchCellFont(int row) {
288       int numWatches = _watches.size();
289       if (row < numWatches) {
290         DebugWatchData currWatch = _watches.get(row);
291         if (currWatch.isChanged()) {
292           setFont(getFont().deriveFont(Font.BOLD));
293         }
294       }
295     }
296   }
297
298   /** A table for displaying the watched variables and fields. Where is the synchronization for this class? */
299   public class WatchTableModel extends AbstractTableModel {
300
301     private String JavaDoc[] _columnNames = {"Name", "Value", "Type"};
302
303     public String JavaDoc getColumnName(int col) { return _columnNames[col]; }
304     public int getRowCount() { return _watches.size() + 1; }
305     public int getColumnCount() { return _columnNames.length; }
306     public Object JavaDoc getValueAt(int row, int col) {
307       if (row < _watches.size()) {
308         DebugWatchData watch = _watches.get(row);
309         switch(col) {
310           case 0: return watch.getName();
311           case 1: return watch.getValue();
312           case 2: return watch.getType();
313         }
314         fireTableRowsUpdated(row, _watches.size()-1);
315         return null;
316       }
317       else {
318         fireTableRowsUpdated(row, _watches.size()-1);
319         // Last row blank
320
return "";
321       }
322     }
323     public boolean isCellEditable(int row, int col) {
324       // First col for entering new values
325
if (col == 0) return true;
326       return false;
327     }
328     public void setValueAt(Object JavaDoc value, int row, int col) {
329       try {
330         if ((value == null) || (value.equals(""))) {
331           // Remove value
332
_debugger.removeWatch(row);
333         }
334         else {
335           if (row < _watches.size())
336             _debugger.removeWatch(row);
337           // Add value
338
_debugger.addWatch(String.valueOf(value));
339         }
340         //fireTableCellUpdated(row, col);
341
fireTableRowsUpdated(row, _watches.size()-1);
342       }
343       catch (DebugException de) { _frame._showDebugError(de); }
344     }
345   }
346
347   /** A table for displaying the current stack trace. */
348   public class StackTableModel extends AbstractTableModel {
349
350     private String JavaDoc[] _columnNames = {"Method", "Line"}; // Do we need #?
351

352     public String JavaDoc getColumnName(int col) { return _columnNames[col]; }
353     
354     public int getRowCount() {
355       if (_stackFrames == null) return 0;
356       return _stackFrames.size();
357     }
358     public int getColumnCount() { return _columnNames.length; }
359
360     public Object JavaDoc getValueAt(int row, int col) {
361       DebugStackData frame = _stackFrames.get(row);
362       switch(col) {
363         case 0: return frame.getMethod();
364         case 1: return new Integer JavaDoc(frame.getLine());
365       }
366       return null;
367     }
368     public boolean isCellEditable(int row, int col) {
369       return false;
370     }
371   }
372
373   /** A table for displaying all current threads. Where is the synchronization for this class? */
374   public class ThreadTableModel extends AbstractTableModel {
375
376     private String JavaDoc[] _columnNames = {"Name", "Status"};
377
378     public String JavaDoc getColumnName(int col) { return _columnNames[col]; }
379
380     public int getRowCount() {
381       if (_threads == null) return 0;
382       return _threads.size();
383     }
384
385     public int getColumnCount() {
386       return _columnNames.length;
387     }
388
389     public Object JavaDoc getValueAt(int row, int col) {
390       DebugThreadData threadData = _threads.get(row);
391       switch(col) {
392         case 0: return threadData.getName();
393         case 1: return threadData.getStatus();
394         default: return null;
395       }
396
397     }
398
399     public boolean isCellEditable(int row, int col) { return false; }
400   }
401
402   /** Creates the buttons for controlling the debugger. */
403   private void _setupButtonPanel() {
404     JPanel mainButtons = new JPanel();
405     JPanel emptyPanel = new JPanel();
406     JPanel closeButtonPanel = new JPanel(new BorderLayout());
407     GridBagLayout gbLayout = new GridBagLayout();
408     GridBagConstraints c = new GridBagConstraints();
409     mainButtons.setLayout(gbLayout);
410     
411     Action resumeAction = new AbstractAction("Resume") {
412       public void actionPerformed(ActionEvent ae) {
413         try { _frame.debuggerResume(); }
414         catch (DebugException de) { _frame._showDebugError(de); }
415       }
416     };
417     _resumeButton = new JButton(resumeAction);
418     
419     Action stepIntoAction = new AbstractAction("Step Into") {
420       public void actionPerformed(ActionEvent ae) {
421         _frame.debuggerStep(Debugger.STEP_INTO);
422       }
423     };
424     _stepIntoButton = new JButton(stepIntoAction);
425
426     Action stepOverAction = new AbstractAction("Step Over") {
427       public void actionPerformed(ActionEvent ae) {
428         _frame.debuggerStep(Debugger.STEP_OVER);
429       }
430     };
431     _stepOverButton = new JButton(stepOverAction);
432
433     Action stepOutAction = new AbstractAction( "Step Out" ) {
434       public void actionPerformed(ActionEvent ae) {
435         _frame.debuggerStep(Debugger.STEP_OUT);
436       }
437     };
438     _stepOutButton = new JButton(stepOutAction);
439     
440     ActionListener closeListener =
441       new ActionListener() {
442       public void actionPerformed(ActionEvent ae) {
443         _frame.debuggerToggle();
444       }
445     };
446
447     _closeButton = new CommonCloseButton(closeListener);
448
449     closeButtonPanel.add(_closeButton, BorderLayout.NORTH);
450     mainButtons.add(_resumeButton);
451     mainButtons.add(_stepIntoButton);
452     mainButtons.add(_stepOverButton);
453     mainButtons.add(_stepOutButton);
454     mainButtons.add(emptyPanel);
455     
456     c.fill = GridBagConstraints.HORIZONTAL;
457     c.anchor = GridBagConstraints.NORTH;
458     c.gridwidth = GridBagConstraints.REMAINDER;
459     c.weightx = 1.0;
460     
461     gbLayout.setConstraints(_resumeButton, c);
462     gbLayout.setConstraints(_stepIntoButton, c);
463     gbLayout.setConstraints(_stepOverButton, c);
464     gbLayout.setConstraints(_stepOutButton, c);
465     
466     c.fill = GridBagConstraints.BOTH;
467     c.anchor = GridBagConstraints.SOUTH;
468     c.gridheight = GridBagConstraints.REMAINDER;
469     c.weighty = 1.0;
470     
471     gbLayout.setConstraints(emptyPanel, c);
472     
473     disableButtons();
474     _buttonPanel.add(mainButtons, BorderLayout.CENTER);
475     _buttonPanel.add(closeButtonPanel, BorderLayout.EAST);
476   }
477
478   /**
479    * Initializes the pop-up menu that is revealed when the user
480    * right-clicks on a row in the thread table or stack table.
481    */

482   private void _initPopup() {
483     // this is commented out because we do not currently support manual
484
// suspension of a running thread.
485
// _threadRunningPopupMenu = new JPopupMenu("Thread Selection");
486
// JMenuItem threadRunningSuspend = new JMenuItem();
487
// Action suspendAction = new AbstractAction("Suspend Thread") {
488
// public void actionPerformed(ActionEvent e) {
489
// try{
490
// _debugger.suspend(getSelectedThread());
491
// }
492
// catch(DebugException exception) {
493
// JOptionPane.showMessageDialog(_frame, "Cannot suspend the thread.", "Debugger Error", JOptionPane.ERROR_MESSAGE);
494
// }
495
// }
496
// };
497
// threadRunningSuspend.setAction(suspendAction);
498
// _threadRunningPopupMenu.add(threadRunningSuspend);
499
// threadRunningSuspend.setText("Suspend and Select Thread");
500

501     Action selectAction = new AbstractAction("Select Thread") {
502       public void actionPerformed(ActionEvent e) { _selectCurrentThread(); }
503     };
504
505     _threadSuspendedPopupMenu = new JPopupMenu("Thread Selection");
506     _threadSuspendedPopupMenu.add(selectAction);
507     _threadSuspendedPopupMenu.add(new AbstractAction("Resume Thread") {
508       public void actionPerformed(ActionEvent e) {
509         try {
510           if (_threadInPopup.isSuspended()) _debugger.resume(_threadInPopup);
511         }
512         catch (DebugException dbe) { _frame._showDebugError(dbe); }
513       }
514     });
515
516     _stackPopupMenu = new JPopupMenu("Stack Selection");
517     _stackPopupMenu.add(new AbstractAction("Scroll to Source") {
518       public void actionPerformed(ActionEvent e) {
519         try {
520           _debugger.scrollToSource(getSelectedStackItem());
521         }
522         catch (DebugException de) { _frame._showDebugError(de); }
523       }
524     });
525
526     _watchPopupMenu = new JPopupMenu("Watches");
527     _watchPopupMenu.add(new AbstractAction("Remove Watch") {
528       public void actionPerformed(ActionEvent e) {
529         try {
530           _debugger.removeWatch(_watchTable.getSelectedRow());
531           _watchTable.revalidate();
532           _watchTable.repaint();
533         }
534         catch (DebugException de) { _frame._showDebugError(de); }
535       }
536     });
537     _watchTable.addMouseListener(new DebugTableMouseAdapter(_watchTable) {
538       protected void _showPopup(MouseEvent e) {
539         if (_watchTable.getSelectedRow() < _watchTable.getRowCount() - 1) {
540           _watchPopupMenu.show(e.getComponent(), e.getX(), e.getY());
541         }
542       }
543       protected void _action() {
544       }
545     });
546   }
547
548   /**
549    */

550   private void _selectCurrentThread() {
551     if (_threadInPopup.isSuspended()) {
552       try {
553         _debugger.setCurrentThread(_threadInPopup);
554       }
555       catch(DebugException de) {
556         _frame._showDebugError(de);
557       }
558     }
559   }
560
561   /**
562    * gets the thread that is currently selected in the thread table
563    * @return the highlighted thread
564    */

565   public DebugThreadData getSelectedThread() {
566     int row = _threadTable.getSelectedRow();
567     if (row == -1) {
568       row = 0; // if there is no selected index, just return the first element
569
}
570     return _threads.get(row);
571   }
572
573   /** Gets the DebugStackData that is currently selected in the stack table
574    * @return the highlighted stack element
575    */

576   public DebugStackData getSelectedStackItem() {
577     return _stackFrames.get(_stackTable.getSelectedRow());
578   }
579
580   /** @return the selected watch */
581   public DebugWatchData getSelectedWatch() {
582     return _watches.get(_watchTable.getSelectedRow());
583   }
584
585   /** Listens to events from the debug manager to keep the panel updated. */
586   class DebugPanelListener implements DebugListener {
587     /** Called when the current thread is suspended. */
588     public void currThreadSuspended() {
589       // Only change GUI from event-dispatching thread
590
Utilities.invokeLater(new Runnable JavaDoc() { public void run() { updateData(); } });
591     }
592
593     /** Called when the current thread is resumed */
594     public void currThreadResumed() {
595       // Only change GUI from event-dispatching thread
596
Utilities.invokeLater(new Runnable JavaDoc() { public void run() { updateData(); } });
597     }
598
599     /** Called when a thread starts. Only runs in event thread. */
600     public void threadStarted() { updateData(); }
601
602     /** Called when the current thread dies. Only runs in event thread. */
603     public void currThreadDied() { updateData(); }
604
605     /** Called when any thread other than the current thread dies. Only runs in event thread. */
606     public void nonCurrThreadDied() { updateData(); }
607
608     /** Called when the current (selected) thread is set in the debugger.
609      * @param thread the thread that was set as current
610      */

611     public void currThreadSet(DebugThreadData thread) {
612       _currentThreadID = thread.getUniqueID();
613
614       // Only change GUI from event-dispatching thread
615
Utilities.invokeLater(new Runnable JavaDoc() { public void run() { updateData(); } });
616     }
617     
618     public void threadLocationUpdated(OpenDefinitionsDocument doc, int lineNumber, boolean shouldHighlight) { }
619     public void debuggerStarted() { }
620     public void debuggerShutdown() { }
621     public void breakpointReached(final Breakpoint bp) { }
622     public void watchSet(final DebugWatchData w) { }
623     public void watchRemoved(final DebugWatchData w) { }
624     public void stepRequested() { }
625     public void regionAdded(Breakpoint r, int index) { }
626     public void regionChanged(Breakpoint r, int index) { }
627     public void regionRemoved(Breakpoint r) { }
628   }
629
630
631   /**
632    * Enables and disables the appropriate buttons depending on if the current
633    * thread has been suspended or resumed
634    * @param isSuspended indicates if the current thread has been suspended
635    */

636   public void setThreadDependentButtons(boolean isSuspended) {
637     _resumeButton.setEnabled(isSuspended);
638     _stepIntoButton.setEnabled(isSuspended);
639     _stepOverButton.setEnabled(isSuspended);
640     _stepOutButton.setEnabled(isSuspended);
641   }
642   public void disableButtons() {
643     setThreadDependentButtons(false);
644   }
645
646   public void setStatusText(String JavaDoc text) { _statusBar.setText(text); }
647
648   public String JavaDoc getStatusText() { return _statusBar.getText(); }
649
650   /**
651    * Updates the UI to a new look and feel.
652    * Need to update the contained popup menus as well.
653    *
654    * Currently, we don't support changing the look and feel
655    * on the fly, so this is disabled.
656    *
657   public void updateUI() {
658     super.updateUI();
659     if (_threadSuspendedPopupMenu != null) {
660       SwingUtilities.updateComponentTreeUI(_threadSuspendedPopupMenu);
661     }
662     if (_stackPopupMenu != null) {
663       SwingUtilities.updateComponentTreeUI(_stackPopupMenu);
664     }
665     if (_watchPopupMenu != null) {
666       SwingUtilities.updateComponentTreeUI(_watchPopupMenu);
667     }
668   }*/

669
670   /**
671    * Concrete DebugTableMouseAdapter for the thread table.
672    */

673   private class ThreadMouseAdapter extends DebugTableMouseAdapter {
674     public ThreadMouseAdapter() {
675       super(_threadTable);
676     }
677
678     protected void _showPopup(MouseEvent e) {
679       _threadInPopup = _threads.get(_lastRow);
680       if (_threadInPopup.isSuspended()) {
681          _threadSuspendedPopupMenu.show(e.getComponent(), e.getX(), e.getY());
682       }
683 // else {
684
// _threadRunningPopupMenu.show(e.getComponent(), e.getX(), e.getY());
685
// }
686
}
687
688     protected void _action() {
689       _threadInPopup = _threads.get(_lastRow);
690       _selectCurrentThread();
691     }
692   }
693
694   /**
695    * Concrete DebugTableMouseAdapter for the stack table.
696    */

697   private class StackMouseAdapter extends DebugTableMouseAdapter {
698     public StackMouseAdapter() {
699       super(_stackTable);
700     }
701
702     protected void _showPopup(MouseEvent e) {
703       _stackPopupMenu.show(e.getComponent(), e.getX(), e.getY());
704     }
705
706     protected void _action() {
707       try {
708         _debugger.scrollToSource(_stackFrames.get(_lastRow));
709       }
710       catch (DebugException de) {
711         _frame._showDebugError(de);
712       }
713     }
714   }
715
716   /**
717    * A mouse adapter that allows for double-clicking and
718    * bringing up a right-click menu.
719    */

720   private abstract class DebugTableMouseAdapter extends RightClickMouseAdapter {
721     protected JTable _table;
722     protected int _lastRow;
723
724     public DebugTableMouseAdapter(JTable table) {
725       _table = table;
726       _lastRow = -1;
727     }
728
729     protected abstract void _showPopup(MouseEvent e);
730     protected abstract void _action();
731
732     protected void _popupAction(MouseEvent e) {
733       _lastRow = _table.rowAtPoint(e.getPoint());
734       _table.setRowSelectionInterval(_lastRow, _lastRow);
735       _showPopup(e);
736     }
737
738     public void mousePressed(MouseEvent e) {
739       super.mousePressed(e);
740
741       if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
742         _lastRow = _table.rowAtPoint(e.getPoint());
743         _action();
744       }
745     }
746   }
747   
748   private class BPTree extends JTree {
749     public BPTree(DefaultTreeModel s) {
750       super(s);
751     }
752     
753     public void setForeground(Color c) {
754       super.setForeground(c);
755       if (dtcr != null) dtcr.setTextNonSelectionColor(c);
756     }
757     
758     public void setBackground(Color c) {
759       super.setBackground(c);
760       if (DebugPanel.this != null && dtcr != null) dtcr.setBackgroundNonSelectionColor(c);
761     }
762   }
763 }
764
Popular Tags