UIThreadpublic class UIThread extends Object implements com.android.ddmuilib.DevicePanel.IUiSelectionListenerThis acts as the UI builder. This cannot be its own thread since this prevent using AWT in an
SWT application. So this class mainly builds the ui, and manages communication between the panels
when {@link Device} / {@link Client} selection changes. |
Fields Summary |
---|
public static final int | PANEL_CLIENT_LIST | public static final int | PANEL_INFO | public static final int | PANEL_THREAD | public static final int | PANEL_HEAP | public static final int | PANEL_NATIVE_HEAP | private static final int | PANEL_ALLOCATIONS | private static final int | PANEL_SYSINFO | private static final int | PANEL_COUNT | private static com.android.ddmuilib.TablePanel[] | mPanelsContent is setup in the constructor | private static final String[] | mPanelNames | private static final String[] | mPanelTips | private static final String | PREFERENCE_LOGSASH | private static final String | PREFERENCE_SASH | private static final String | PREFS_COL_TIME | private static final String | PREFS_COL_LEVEL | private static final String | PREFS_COL_PID | private static final String | PREFS_COL_TAG | private static final String | PREFS_COL_MESSAGE | private static final String | PREFS_FILTERS | private static UIThread | mInstance | private org.eclipse.swt.widgets.Display | mDisplay | private com.android.ddmuilib.DevicePanel | mDevicePanel | private com.android.ddmlib.Device | mCurrentDevice | private com.android.ddmlib.Client | mCurrentClient | private org.eclipse.swt.widgets.Label | mStatusLine | private org.eclipse.swt.widgets.ToolItem | mTBShowThreadUpdates | private org.eclipse.swt.widgets.ToolItem | mTBShowHeapUpdates | private org.eclipse.swt.widgets.ToolItem | mTBHalt | private org.eclipse.swt.widgets.ToolItem | mTBCauseGc | private com.android.ddmuilib.ImageLoader | mDdmsImageLoader | private com.android.ddmuilib.ImageLoader | mDdmuiLibImageLoader | private com.android.ddmuilib.logcat.LogPanel | mLogPanel | private com.android.ddmuilib.actions.ToolItemAction | mCreateFilterAction | private com.android.ddmuilib.actions.ToolItemAction | mDeleteFilterAction | private com.android.ddmuilib.actions.ToolItemAction | mEditFilterAction | private com.android.ddmuilib.actions.ToolItemAction | mExportAction | private com.android.ddmuilib.actions.ToolItemAction | mClearAction | private com.android.ddmuilib.actions.ToolItemAction[] | mLogLevelActions | private String[] | mLogLevelIcons | protected org.eclipse.swt.dnd.Clipboard | mClipboard | private org.eclipse.swt.widgets.MenuItem | mCopyMenuItem | private org.eclipse.swt.widgets.MenuItem | mSelectAllMenuItem | private TableFocusListener | mTableListener | private com.android.ddmuilib.explorer.DeviceExplorer | mExplorer | private org.eclipse.swt.widgets.Shell | mExplorerShell | private com.android.ddmuilib.EmulatorControlPanel | mEmulatorPanel | private com.android.ddmuilib.log.event.EventLogPanel | mEventLogPanel |
Constructors Summary |
---|
private UIThread()Generic constructor.
mPanels[PANEL_INFO] = new InfoPanel();
mPanels[PANEL_THREAD] = new ThreadPanel();
mPanels[PANEL_HEAP] = new HeapPanel();
if (PrefsDialog.getStore().getBoolean(PrefsDialog.SHOW_NATIVE_HEAP)) {
mPanels[PANEL_NATIVE_HEAP] = new NativeHeapPanel();
} else {
mPanels[PANEL_NATIVE_HEAP] = null;
}
mPanels[PANEL_ALLOCATIONS] = new AllocationPanel();
mPanels[PANEL_SYSINFO] = new SysinfoPanel();
|
Methods Summary |
---|
public void | asyncExec(java.lang.Runnable r)
if (mDisplay != null && mDisplay.isDisposed() == false) {
mDisplay.asyncExec(r);
}
| private void | createBottomPanel(org.eclipse.swt.widgets.Composite comp)
final PreferenceStore prefs = PrefsDialog.getStore();
// create clipboard
Display display = comp.getDisplay();
mClipboard = new Clipboard(display);
LogColors colors = new LogColors();
colors.infoColor = new Color(display, 0, 127, 0);
colors.debugColor = new Color(display, 0, 0, 127);
colors.errorColor = new Color(display, 255, 0, 0);
colors.warningColor = new Color(display, 255, 127, 0);
colors.verboseColor = new Color(display, 0, 0, 0);
// set the preferences names
LogPanel.PREFS_TIME = PREFS_COL_TIME;
LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
LogPanel.PREFS_PID = PREFS_COL_PID;
LogPanel.PREFS_TAG = PREFS_COL_TAG;
LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
comp.setLayout(new GridLayout(1, false));
ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL);
mCreateFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
mCreateFilterAction.item.setToolTipText("Create Filter");
mCreateFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"add.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mCreateFilterAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mLogPanel.addFilter();
}
});
mEditFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
mEditFilterAction.item.setToolTipText("Edit Filter");
mEditFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"edit.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mEditFilterAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mLogPanel.editFilter();
}
});
mDeleteFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
mDeleteFilterAction.item.setToolTipText("Delete Filter");
mDeleteFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"delete.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mDeleteFilterAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mLogPanel.deleteFilter();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
LogLevel[] levels = LogLevel.values();
mLogLevelActions = new ToolItemAction[mLogLevelIcons.length];
for (int i = 0 ; i < mLogLevelActions.length; i++) {
String name = levels[i].getStringValue();
final ToolItemAction newAction = new ToolItemAction(toolBar, SWT.CHECK);
mLogLevelActions[i] = newAction;
//newAction.item.setText(name);
newAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// disable the other actions and record current index
for (int i = 0 ; i < mLogLevelActions.length; i++) {
ToolItemAction a = mLogLevelActions[i];
if (a == newAction) {
a.setChecked(true);
// set the log level
mLogPanel.setCurrentFilterLogLevel(i+2);
} else {
a.setChecked(false);
}
}
}
});
newAction.item.setToolTipText(name);
newAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
mLogLevelIcons[i],
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
}
new ToolItem(toolBar, SWT.SEPARATOR);
mClearAction = new ToolItemAction(toolBar, SWT.PUSH);
mClearAction.item.setToolTipText("Clear Log");
mClearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"clear.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mClearAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mLogPanel.clear();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
mExportAction = new ToolItemAction(toolBar, SWT.PUSH);
mExportAction.item.setToolTipText("Export Selection As Text...");
mExportAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"save.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mExportAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mLogPanel.save();
}
});
toolBar.pack();
// now create the log view
mLogPanel = new LogPanel(new ImageLoader(LogPanel.class), colors, new FilterStorage(),
LogPanel.FILTER_MANUAL);
mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
String colMode = prefs.getString(PrefsDialog.LOGCAT_COLUMN_MODE);
if (PrefsDialog.LOGCAT_COLUMN_MODE_AUTO.equals(colMode)) {
mLogPanel.setColumnMode(LogPanel.COLUMN_MODE_AUTO);
}
String fontStr = PrefsDialog.getStore().getString(PrefsDialog.LOGCAT_FONT);
if (fontStr != null) {
try {
FontData fdat = new FontData(fontStr);
mLogPanel.setFont(new Font(display, fdat));
} catch (IllegalArgumentException e) {
// Looks like fontStr isn't a valid font representation.
// We do nothing in this case, the logcat view will use the default font.
} catch (SWTError e2) {
// Looks like the Font() constructor failed.
// We do nothing in this case, the logcat view will use the default font.
}
}
mLogPanel.createPanel(comp);
// and start the logcat
mLogPanel.startLogCat(mCurrentDevice);
| private void | createDevicePanelToolBar(org.eclipse.swt.widgets.ToolBar toolBar)
Display display = toolBar.getDisplay();
// add "show thread updates" button
mTBShowThreadUpdates = new ToolItem(toolBar, SWT.CHECK);
mTBShowThreadUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
DevicePanel.ICON_THREAD, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mTBShowThreadUpdates.setToolTipText("Show thread updates");
mTBShowThreadUpdates.setEnabled(false);
mTBShowThreadUpdates.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mCurrentClient != null) {
// boolean status = ((ToolItem)e.item).getSelection();
// invert previous state
boolean enable = !mCurrentClient.isThreadUpdateEnabled();
mCurrentClient.setThreadUpdateEnabled(enable);
} else {
e.doit = false; // this has no effect?
}
}
});
// add "show heap updates" button
mTBShowHeapUpdates = new ToolItem(toolBar, SWT.CHECK);
mTBShowHeapUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
DevicePanel.ICON_HEAP, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mTBShowHeapUpdates.setToolTipText("Show heap updates");
mTBShowHeapUpdates.setEnabled(false);
mTBShowHeapUpdates.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mCurrentClient != null) {
// boolean status = ((ToolItem)e.item).getSelection();
// invert previous state
boolean enable = !mCurrentClient.isHeapUpdateEnabled();
mCurrentClient.setHeapUpdateEnabled(enable);
} else {
e.doit = false; // this has no effect?
}
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
// add "kill VM" button; need to make this visually distinct from
// the status update buttons
mTBHalt = new ToolItem(toolBar, SWT.PUSH);
mTBHalt.setToolTipText("Halt the target VM");
mTBHalt.setEnabled(false);
mTBHalt.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
DevicePanel.ICON_HALT, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mTBHalt.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mDevicePanel.killSelectedClient();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
// add "cause GC" button
mTBCauseGc = new ToolItem(toolBar, SWT.PUSH);
mTBCauseGc.setToolTipText("Cause an immediate GC in the target VM");
mTBCauseGc.setEnabled(false);
mTBCauseGc.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
DevicePanel.ICON_GC, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
mTBCauseGc.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mDevicePanel.forceGcOnSelectedClient();
}
});
toolBar.pack();
| private void | createFileExplorer()
if (mExplorer == null) {
mExplorerShell = new Shell(mDisplay);
// create the ui
mExplorerShell.setLayout(new GridLayout(1, false));
// toolbar + action
ToolBar toolBar = new ToolBar(mExplorerShell, SWT.HORIZONTAL);
toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
ToolItemAction pullAction = new ToolItemAction(toolBar, SWT.PUSH);
pullAction.item.setToolTipText("Pull File from Device");
pullAction.item.setImage(mDdmuiLibImageLoader.loadImage("pull.png", mDisplay)); //$NON-NLS-1$
ToolItemAction pushAction = new ToolItemAction(toolBar, SWT.PUSH);
pushAction.item.setToolTipText("Push file onto Device");
pushAction.item.setImage(mDdmuiLibImageLoader.loadImage("push.png", mDisplay)); //$NON-NLS-1$
ToolItemAction deleteAction = new ToolItemAction(toolBar, SWT.PUSH);
deleteAction.item.setToolTipText("Delete");
deleteAction.item.setImage(mDdmuiLibImageLoader.loadImage("delete.png", mDisplay)); //$NON-NLS-1$
// device explorer
mExplorer = new DeviceExplorer();
mExplorer.setImages(mDdmuiLibImageLoader.loadImage("file.png", mDisplay), //$NON-NLS-1$
mDdmuiLibImageLoader.loadImage("folder.png", mDisplay), //$NON-NLS-1$
mDdmuiLibImageLoader.loadImage("android.png", mDisplay), //$NON-NLS-1$
null);
mExplorer.setActions(pushAction, pullAction, deleteAction);
pullAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mExplorer.pullSelection();
}
});
pullAction.setEnabled(false);
pushAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mExplorer.pushIntoSelection();
}
});
pushAction.setEnabled(false);
deleteAction.item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mExplorer.deleteSelection();
}
});
deleteAction.setEnabled(false);
Composite parent = new Composite(mExplorerShell, SWT.NONE);
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
mExplorer.createPanel(parent);
mExplorer.switchDevice(mCurrentDevice);
mExplorerShell.addShellListener(new ShellListener() {
public void shellActivated(ShellEvent e) {
// pass
}
public void shellClosed(ShellEvent e) {
mExplorer = null;
mExplorerShell = null;
}
public void shellDeactivated(ShellEvent e) {
// pass
}
public void shellDeiconified(ShellEvent e) {
// pass
}
public void shellIconified(ShellEvent e) {
// pass
}
});
mExplorerShell.pack();
setExplorerSizeAndPosition(mExplorerShell);
mExplorerShell.open();
} else {
if (mExplorerShell != null) {
mExplorerShell.forceActive();
}
}
| private void | createLeftPanel(org.eclipse.swt.widgets.Composite comp)
comp.setLayout(new GridLayout(1, false));
ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL | SWT.RIGHT | SWT.WRAP);
toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
createDevicePanelToolBar(toolBar);
Composite c = new Composite(comp, SWT.NONE);
c.setLayoutData(new GridData(GridData.FILL_BOTH));
mDevicePanel = new DevicePanel(new ImageLoader(DevicePanel.class), true /* showPorts */);
mDevicePanel.createPanel(c);
// add ourselves to the device panel selection listener
mDevicePanel.addSelectionListener(this);
| private void | createMenus(org.eclipse.swt.widgets.Shell shell)
// create menu bar
Menu menuBar = new Menu(shell, SWT.BAR);
// create top-level items
MenuItem fileItem = new MenuItem(menuBar, SWT.CASCADE);
fileItem.setText("&File");
MenuItem editItem = new MenuItem(menuBar, SWT.CASCADE);
editItem.setText("&Edit");
MenuItem actionItem = new MenuItem(menuBar, SWT.CASCADE);
actionItem.setText("&Actions");
MenuItem deviceItem = new MenuItem(menuBar, SWT.CASCADE);
deviceItem.setText("&Device");
MenuItem helpItem = new MenuItem(menuBar, SWT.CASCADE);
helpItem.setText("&Help");
// create top-level menus
Menu fileMenu = new Menu(menuBar);
fileItem.setMenu(fileMenu);
Menu editMenu = new Menu(menuBar);
editItem.setMenu(editMenu);
Menu actionMenu = new Menu(menuBar);
actionItem.setMenu(actionMenu);
Menu deviceMenu = new Menu(menuBar);
deviceItem.setMenu(deviceMenu);
Menu helpMenu = new Menu(menuBar);
helpItem.setMenu(helpMenu);
MenuItem item;
// create File menu items
item = new MenuItem(fileMenu, SWT.NONE);
item.setText("&Preferences...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
PrefsDialog.run(shell);
}
});
item = new MenuItem(fileMenu, SWT.NONE);
item.setText("&Static Port Configuration...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
StaticPortConfigDialog dlg = new StaticPortConfigDialog(shell);
dlg.open();
}
});
new MenuItem(fileMenu, SWT.SEPARATOR);
item = new MenuItem(fileMenu, SWT.NONE);
item.setText("E&xit\tCtrl-Q");
item.setAccelerator('Q" | SWT.CONTROL);
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
shell.close();
}
});
// create edit menu items
mCopyMenuItem = new MenuItem(editMenu, SWT.NONE);
mCopyMenuItem.setText("&Copy\tCtrl-C");
mCopyMenuItem.setAccelerator('C" | SWT.COMMAND);
mCopyMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mTableListener.copy(mClipboard);
}
});
new MenuItem(editMenu, SWT.SEPARATOR);
mSelectAllMenuItem = new MenuItem(editMenu, SWT.NONE);
mSelectAllMenuItem.setText("Select &All\tCtrl-A");
mSelectAllMenuItem.setAccelerator('A" | SWT.COMMAND);
mSelectAllMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mTableListener.selectAll();
}
});
// create Action menu items
// TODO: this should come with a confirmation dialog
final MenuItem actionHaltItem = new MenuItem(actionMenu, SWT.NONE);
actionHaltItem.setText("&Halt VM");
actionHaltItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mDevicePanel.killSelectedClient();
}
});
final MenuItem actionCauseGcItem = new MenuItem(actionMenu, SWT.NONE);
actionCauseGcItem.setText("Cause &GC");
actionCauseGcItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mDevicePanel.forceGcOnSelectedClient();
}
});
// configure Action items based on current state
actionMenu.addMenuListener(new MenuAdapter() {
@Override
public void menuShown(MenuEvent e) {
actionHaltItem.setEnabled(mTBHalt.getEnabled());
actionCauseGcItem.setEnabled(mTBCauseGc.getEnabled());
}
});
// create Device menu items
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("&Screen capture...\tCTrl-S");
item.setAccelerator('S" | SWT.CONTROL);
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mCurrentDevice != null) {
ScreenShotDialog dlg = new ScreenShotDialog(shell);
dlg.open(mCurrentDevice);
}
}
});
new MenuItem(deviceMenu, SWT.SEPARATOR);
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("File Explorer...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
createFileExplorer();
}
});
new MenuItem(deviceMenu, SWT.SEPARATOR);
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("Show &process status...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DeviceCommandDialog dlg;
dlg = new DeviceCommandDialog("ps -x", "ps-x.txt", shell);
dlg.open(mCurrentDevice);
}
});
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("Dump &device state...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DeviceCommandDialog dlg;
dlg = new DeviceCommandDialog("/system/bin/dumpstate /proc/self/fd/0",
"device-state.txt", shell);
dlg.open(mCurrentDevice);
}
});
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("Dump &app state...");
item.setEnabled(false);
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DeviceCommandDialog dlg;
dlg = new DeviceCommandDialog("dumpsys", "app-state.txt", shell);
dlg.open(mCurrentDevice);
}
});
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("Dump &radio state...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DeviceCommandDialog dlg;
dlg = new DeviceCommandDialog(
"cat /data/logs/radio.4 /data/logs/radio.3"
+ " /data/logs/radio.2 /data/logs/radio.1"
+ " /data/logs/radio",
"radio-state.txt", shell);
dlg.open(mCurrentDevice);
}
});
item = new MenuItem(deviceMenu, SWT.NONE);
item.setText("Run &logcat...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DeviceCommandDialog dlg;
dlg = new DeviceCommandDialog("logcat '*:d jdwp:w'", "log.txt",
shell);
dlg.open(mCurrentDevice);
}
});
// create Help menu items
item = new MenuItem(helpMenu, SWT.NONE);
item.setText("&Contents...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int style = SWT.APPLICATION_MODAL | SWT.OK;
MessageBox msgBox = new MessageBox(shell, style);
msgBox.setText("Help!");
msgBox.setMessage("Help wanted.");
msgBox.open();
}
});
new MenuItem(helpMenu, SWT.SEPARATOR);
item = new MenuItem(helpMenu, SWT.NONE);
item.setText("&About...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
AboutDialog dlg = new AboutDialog(shell);
dlg.open();
}
});
// tell the shell to use this menu
shell.setMenuBar(menuBar);
| private void | createRightPanel(org.eclipse.swt.widgets.Composite comp)
TabItem item;
TabFolder tabFolder;
comp.setLayout(new FillLayout());
tabFolder = new TabFolder(comp, SWT.NONE);
for (int i = 0; i < mPanels.length; i++) {
if (mPanels[i] != null) {
item = new TabItem(tabFolder, SWT.NONE);
item.setText(mPanelNames[i]);
item.setToolTipText(mPanelTips[i]);
item.setControl(mPanels[i].createPanel(tabFolder));
}
}
// add the emulator control panel to the folders.
item = new TabItem(tabFolder, SWT.NONE);
item.setText("Emulator Control");
item.setToolTipText("Emulator Control Panel");
mEmulatorPanel = new EmulatorControlPanel(mDdmuiLibImageLoader);
item.setControl(mEmulatorPanel.createPanel(tabFolder));
// add the event log panel to the folders.
item = new TabItem(tabFolder, SWT.NONE);
item.setText("Event Log");
item.setToolTipText("Event Log");
// create the composite that will hold the toolbar and the event log panel.
Composite eventLogTopComposite = new Composite(tabFolder, SWT.NONE);
item.setControl(eventLogTopComposite);
eventLogTopComposite.setLayout(new GridLayout(1, false));
// create the toolbar and the actions
ToolBar toolbar = new ToolBar(eventLogTopComposite, SWT.HORIZONTAL);
toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
ToolItemAction optionsAction = new ToolItemAction(toolbar, SWT.PUSH);
optionsAction.item.setToolTipText("Opens the options panel");
optionsAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"edit.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
ToolItemAction clearAction = new ToolItemAction(toolbar, SWT.PUSH);
clearAction.item.setToolTipText("Clears the event log");
clearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"clear.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
new ToolItem(toolbar, SWT.SEPARATOR);
ToolItemAction saveAction = new ToolItemAction(toolbar, SWT.PUSH);
saveAction.item.setToolTipText("Saves the event log");
saveAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"save.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
ToolItemAction loadAction = new ToolItemAction(toolbar, SWT.PUSH);
loadAction.item.setToolTipText("Loads an event log");
loadAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"load.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
ToolItemAction importBugAction = new ToolItemAction(toolbar, SWT.PUSH);
importBugAction.item.setToolTipText("Imports a bug report");
importBugAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"importBug.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
// create the event log panel
mEventLogPanel = new EventLogPanel(mDdmuiLibImageLoader);
// set the external actions
mEventLogPanel.setActions(optionsAction, clearAction, saveAction, loadAction,
importBugAction);
// create the panel
mEventLogPanel.createPanel(eventLogTopComposite);
| private void | createTopPanel(org.eclipse.swt.widgets.Composite comp, org.eclipse.swt.graphics.Color darkGray)
final PreferenceStore prefs = PrefsDialog.getStore();
comp.setLayout(new FormLayout());
Composite leftPanel = new Composite(comp, SWT.NONE);
final Sash sash = new Sash(comp, SWT.VERTICAL);
sash.setBackground(darkGray);
Composite rightPanel = new Composite(comp, SWT.NONE);
createLeftPanel(leftPanel);
createRightPanel(rightPanel);
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(sash, 0);
leftPanel.setLayoutData(data);
final FormData sashData = new FormData();
sashData.top = new FormAttachment(0, 0);
sashData.bottom = new FormAttachment(100, 0);
if (prefs != null && prefs.contains(PREFERENCE_SASH)) {
sashData.left = new FormAttachment(0, prefs.getInt(
PREFERENCE_SASH));
} else {
// position the sash 380 from the right instead of x% (done by using
// FormAttachment(x, 0)) in order to keep the sash at the same
// position
// from the left when the window is resized.
// 380px is just enough to display the left table with no horizontal
// scrollbar with the default font.
sashData.left = new FormAttachment(0, 380);
}
sash.setLayoutData(sashData);
data = new FormData();
data.top = new FormAttachment(0, 0);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(sash, 0);
data.right = new FormAttachment(100, 0);
rightPanel.setLayoutData(data);
final int minPanelWidth = 60;
// allow resizes, but cap at minPanelWidth
sash.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
Rectangle sashRect = sash.getBounds();
Rectangle panelRect = comp.getClientArea();
int right = panelRect.width - sashRect.width - minPanelWidth;
e.x = Math.max(Math.min(e.x, right), minPanelWidth);
if (e.x != sashRect.x) {
sashData.left = new FormAttachment(0, e.x);
prefs.setValue(PREFERENCE_SASH, e.x);
comp.layout();
}
}
});
| private void | createWidgets(org.eclipse.swt.widgets.Shell shell)
Color darkGray = shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
/*
* Create three areas: tool bar, split panels, status line
*/
shell.setLayout(new GridLayout(1, false));
// 1. panel area
final Composite panelArea = new Composite(shell, SWT.BORDER);
// make the panel area absorb all space
panelArea.setLayoutData(new GridData(GridData.FILL_BOTH));
// 2. status line.
mStatusLine = new Label(shell, SWT.NONE);
// make status line extend all the way across
mStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mStatusLine.setText("Initializing...");
/*
* Configure the split-panel area.
*/
final PreferenceStore prefs = PrefsDialog.getStore();
Composite topPanel = new Composite(panelArea, SWT.NONE);
final Sash sash = new Sash(panelArea, SWT.HORIZONTAL);
sash.setBackground(darkGray);
Composite bottomPanel = new Composite(panelArea, SWT.NONE);
panelArea.setLayout(new FormLayout());
createTopPanel(topPanel, darkGray);
createBottomPanel(bottomPanel);
// form layout data
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.bottom = new FormAttachment(sash, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
topPanel.setLayoutData(data);
final FormData sashData = new FormData();
if (prefs != null && prefs.contains(PREFERENCE_LOGSASH)) {
sashData.top = new FormAttachment(0, prefs.getInt(
PREFERENCE_LOGSASH));
} else {
sashData.top = new FormAttachment(50,0); // 50% across
}
sashData.left = new FormAttachment(0, 0);
sashData.right = new FormAttachment(100, 0);
sash.setLayoutData(sashData);
data = new FormData();
data.top = new FormAttachment(sash, 0);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
bottomPanel.setLayoutData(data);
// allow resizes, but cap at minPanelWidth
sash.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
Rectangle sashRect = sash.getBounds();
Rectangle panelRect = panelArea.getClientArea();
int bottom = panelRect.height - sashRect.height - 100;
e.y = Math.max(Math.min(e.y, bottom), 100);
if (e.y != sashRect.y) {
sashData.top = new FormAttachment(0, e.y);
prefs.setValue(PREFERENCE_LOGSASH, e.y);
panelArea.layout();
}
}
});
// add a global focus listener for all the tables
mTableListener = new TableFocusListener();
// now set up the listener in the various panels
mLogPanel.setTableFocusListener(mTableListener);
mEventLogPanel.setTableFocusListener(mTableListener);
for (TablePanel p : mPanels) {
if (p != null) {
p.setTableFocusListener(mTableListener);
}
}
mStatusLine.setText("");
| public void | displayError(java.lang.String msg)
try {
mDisplay.syncExec(new Runnable() {
public void run() {
MessageDialog.openError(mDisplay.getActiveShell(), "Error",
msg);
}
});
} catch (SWTException swte) {
if (!mDisplay.isDisposed())
throw swte;
}
| private void | doSetStatusLine(java.lang.String str)
if (mStatusLine.isDisposed())
return;
if (!mStatusLine.getText().equals(str)) {
mStatusLine.setText(str);
// try { Thread.sleep(100); }
// catch (InterruptedException ie) {}
}
| private void | enableButtons()
if (mCurrentClient != null) {
mTBShowThreadUpdates.setSelection(mCurrentClient.isThreadUpdateEnabled());
mTBShowThreadUpdates.setEnabled(true);
mTBShowHeapUpdates.setSelection(mCurrentClient.isHeapUpdateEnabled());
mTBShowHeapUpdates.setEnabled(true);
mTBHalt.setEnabled(true);
mTBCauseGc.setEnabled(true);
} else {
// list is empty, disable these
mTBShowThreadUpdates.setSelection(false);
mTBShowThreadUpdates.setEnabled(false);
mTBShowHeapUpdates.setSelection(false);
mTBShowHeapUpdates.setEnabled(false);
mTBHalt.setEnabled(false);
mTBCauseGc.setEnabled(false);
}
| public org.eclipse.swt.widgets.Display | getDisplay()Return the Display. Don't try this unless you're in the UI thread.
return mDisplay;
| public static com.android.ddms.UIThread | getInstance()Get singleton instance of the UI thread.
return mInstance;
| public org.eclipse.jface.preference.IPreferenceStore | getStore()returns the IPreferenceStore
return PrefsDialog.getStore();
| public void | runUI()Create SWT objects and drive the user interface event loop.
Display.setAppName("ddms");
mDisplay = new Display();
Shell shell = new Shell(mDisplay);
// create the image loaders for DDMS and DDMUILIB
mDdmsImageLoader = new ImageLoader(this.getClass());
mDdmuiLibImageLoader = new ImageLoader(DevicePanel.class);
shell.setImage(ImageHelper.loadImage(mDdmsImageLoader, mDisplay,
"ddms-icon.png", //$NON-NLS-1$
100, 50, null));
Log.setLogOutput(new ILogOutput() {
public void printAndPromptLog(final LogLevel logLevel, final String tag,
final String message) {
Log.printLog(logLevel, tag, message);
// dialog box only run in UI thread..
mDisplay.asyncExec(new Runnable() {
public void run() {
Shell shell = mDisplay.getActiveShell();
if (logLevel == LogLevel.ERROR) {
MessageDialog.openError(shell, tag, message);
} else {
MessageDialog.openWarning(shell, tag, message);
}
}
});
}
public void printLog(LogLevel logLevel, String tag, String message) {
Log.printLog(logLevel, tag, message);
}
});
// [try to] ensure ADB is running
String adbLocation = System.getProperty("com.android.ddms.bindir"); //$NON-NLS-1$
if (adbLocation != null && adbLocation.length() != 0) {
adbLocation += File.separator + "adb"; //$NON-NLS-1$
} else {
adbLocation = "adb"; //$NON-NLS-1$
}
AndroidDebugBridge.init(true /* debugger support */);
AndroidDebugBridge.createBridge(adbLocation, true /* forceNewBridge */);
shell.setText("Dalvik Debug Monitor");
setConfirmClose(shell);
createMenus(shell);
createWidgets(shell);
shell.pack();
setSizeAndPosition(shell);
shell.open();
Log.d("ddms", "UI is up");
while (!shell.isDisposed()) {
if (!mDisplay.readAndDispatch())
mDisplay.sleep();
}
mLogPanel.stopLogCat(true);
mDevicePanel.dispose();
for (TablePanel panel : mPanels) {
if (panel != null) {
panel.dispose();
}
}
mDisplay.dispose();
Log.d("ddms", "UI is down");
| public void | selectionChanged(com.android.ddmlib.Device selectedDevice, com.android.ddmlib.Client selectedClient)Sent when a new {@link Device} and {@link Client} are selected.
if (mCurrentDevice != selectedDevice) {
mCurrentDevice = selectedDevice;
for (TablePanel panel : mPanels) {
if (panel != null) {
panel.deviceSelected(mCurrentDevice);
}
}
mEmulatorPanel.deviceSelected(mCurrentDevice);
mLogPanel.deviceSelected(mCurrentDevice);
if (mEventLogPanel != null) {
mEventLogPanel.deviceSelected(mCurrentDevice);
}
if (mExplorer != null) {
mExplorer.switchDevice(mCurrentDevice);
}
}
if (mCurrentClient != selectedClient) {
AndroidDebugBridge.getBridge().setSelectedClient(selectedClient);
mCurrentClient = selectedClient;
for (TablePanel panel : mPanels) {
if (panel != null) {
panel.clientSelected(mCurrentClient);
}
}
enableButtons();
}
| private void | setConfirmClose(org.eclipse.swt.widgets.Shell shell)
if (true)
return;
shell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event event) {
int style = SWT.APPLICATION_MODAL | SWT.YES | SWT.NO;
MessageBox msgBox = new MessageBox(shell, style);
msgBox.setText("Confirm...");
msgBox.setMessage("Close DDM?");
event.doit = (msgBox.open() == SWT.YES);
}
});
| private void | setExplorerSizeAndPosition(org.eclipse.swt.widgets.Shell shell)Set the size and position of the file explorer window from the
preference, and setup listeners for control events (resize/move of
the window)
shell.setMinimumSize(400, 200);
// get the x/y and w/h from the prefs
PreferenceStore prefs = PrefsDialog.getStore();
int x = prefs.getInt(PrefsDialog.EXPLORER_SHELL_X);
int y = prefs.getInt(PrefsDialog.EXPLORER_SHELL_Y);
int w = prefs.getInt(PrefsDialog.EXPLORER_SHELL_WIDTH);
int h = prefs.getInt(PrefsDialog.EXPLORER_SHELL_HEIGHT);
// check that we're not out of the display area
Rectangle rect = mDisplay.getClientArea();
// first check the width/height
if (w > rect.width) {
w = rect.width;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
}
if (h > rect.height) {
h = rect.height;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
}
// then check x. Make sure the left corner is in the screen
if (x < rect.x) {
x = rect.x;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
} else if (x >= rect.x + rect.width) {
x = rect.x + rect.width - w;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
}
// then check y. Make sure the left corner is in the screen
if (y < rect.y) {
y = rect.y;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
} else if (y >= rect.y + rect.height) {
y = rect.y + rect.height - h;
prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
}
// now we can set the location/size
shell.setBounds(x, y, w, h);
// add listener for resize/move
shell.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {
// get the new x/y
Rectangle rect = shell.getBounds();
// store in pref file
PreferenceStore prefs = PrefsDialog.getStore();
prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
}
public void controlResized(ControlEvent e) {
// get the new w/h
Rectangle rect = shell.getBounds();
// store in pref file
PreferenceStore prefs = PrefsDialog.getStore();
prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
}
});
| private void | setSizeAndPosition(org.eclipse.swt.widgets.Shell shell)Set the size and position of the main window from the preference, and
setup listeners for control events (resize/move of the window)
shell.setMinimumSize(400, 200);
// get the x/y and w/h from the prefs
PreferenceStore prefs = PrefsDialog.getStore();
int x = prefs.getInt(PrefsDialog.SHELL_X);
int y = prefs.getInt(PrefsDialog.SHELL_Y);
int w = prefs.getInt(PrefsDialog.SHELL_WIDTH);
int h = prefs.getInt(PrefsDialog.SHELL_HEIGHT);
// check that we're not out of the display area
Rectangle rect = mDisplay.getClientArea();
// first check the width/height
if (w > rect.width) {
w = rect.width;
prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
}
if (h > rect.height) {
h = rect.height;
prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
}
// then check x. Make sure the left corner is in the screen
if (x < rect.x) {
x = rect.x;
prefs.setValue(PrefsDialog.SHELL_X, rect.x);
} else if (x >= rect.x + rect.width) {
x = rect.x + rect.width - w;
prefs.setValue(PrefsDialog.SHELL_X, rect.x);
}
// then check y. Make sure the left corner is in the screen
if (y < rect.y) {
y = rect.y;
prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
} else if (y >= rect.y + rect.height) {
y = rect.y + rect.height - h;
prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
}
// now we can set the location/size
shell.setBounds(x, y, w, h);
// add listener for resize/move
shell.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {
// get the new x/y
Rectangle rect = shell.getBounds();
// store in pref file
PreferenceStore prefs = PrefsDialog.getStore();
prefs.setValue(PrefsDialog.SHELL_X, rect.x);
prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
}
public void controlResized(ControlEvent e) {
// get the new w/h
Rectangle rect = shell.getBounds();
// store in pref file
PreferenceStore prefs = PrefsDialog.getStore();
prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
}
});
| public void | setStatusLine(java.lang.String str)Set the status line. TODO: make this a stack, so we can safely have
multiple things trying to set it all at once. Also specify an expiration?
try {
mDisplay.asyncExec(new Runnable() {
public void run() {
doSetStatusLine(str);
}
});
} catch (SWTException swte) {
if (!mDisplay.isDisposed())
throw swte;
}
|
|