AI 146631: ADT #1793333: fix Widget disposed in SdkTargetSelector.
This happens when you open the Windows > Prefs > Android panel while an SDK is initially loading or when you change the SDK in the pref panel. The target change listener was not properly removed since the field was not properly disposed. This also removed the multiple selection handling in the SdkTargetSelector, which we never use. In the unlikely event we want to use it later, it would be trivial to add it back. BUG=1793333 Automated import of CL 146631
This commit is contained in:
committed by
The Android Open Source Project
parent
550c75344b
commit
a43533117c
@@ -43,14 +43,13 @@ import java.util.ArrayList;
|
||||
* <p/>
|
||||
* To use, create it using {@link #SdkTargetSelector(Composite, IAndroidTarget[], boolean)} then
|
||||
* call {@link #setSelection(IAndroidTarget)}, {@link #setSelectionListener(SelectionListener)}
|
||||
* and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the
|
||||
* and finally use {@link #getSelected()} to retrieve the
|
||||
* selection.
|
||||
*/
|
||||
public class SdkTargetSelector {
|
||||
|
||||
private IAndroidTarget[] mTargets;
|
||||
private final boolean mAllowSelection;
|
||||
private final boolean mAllowMultipleSelection;
|
||||
private SelectionListener mSelectionListener;
|
||||
private Table mTable;
|
||||
private Label mDescription;
|
||||
@@ -62,12 +61,9 @@ public class SdkTargetSelector {
|
||||
* @param parent The parent composite where the selector will be added.
|
||||
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
||||
* Targets can be null or an empty array, in which case the table is disabled.
|
||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
||||
* time.
|
||||
*/
|
||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
||||
boolean allowMultipleSelection) {
|
||||
this(parent, targets, true /*allowSelection*/, allowMultipleSelection);
|
||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets) {
|
||||
this(parent, targets, true /*allowSelection*/);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,12 +73,8 @@ public class SdkTargetSelector {
|
||||
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
||||
* Targets can be null or an empty array, in which case the table is disabled.
|
||||
* @param allowSelection True if selection is enabled.
|
||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
||||
* time. Used only if allowSelection is true.
|
||||
*/
|
||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
||||
boolean allowSelection,
|
||||
boolean allowMultipleSelection) {
|
||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, boolean allowSelection) {
|
||||
// Layout has 1 column
|
||||
mInnerGroup = new Composite(parent, SWT.NONE);
|
||||
mInnerGroup.setLayout(new GridLayout());
|
||||
@@ -90,13 +82,9 @@ public class SdkTargetSelector {
|
||||
mInnerGroup.setFont(parent.getFont());
|
||||
|
||||
mAllowSelection = allowSelection;
|
||||
mAllowMultipleSelection = allowMultipleSelection;
|
||||
int style = SWT.BORDER;
|
||||
int style = SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION;
|
||||
if (allowSelection) {
|
||||
style |= SWT.CHECK | SWT.FULL_SELECTION;
|
||||
}
|
||||
if (!mAllowMultipleSelection) {
|
||||
style |= SWT.SINGLE;
|
||||
style |= SWT.CHECK;
|
||||
}
|
||||
mTable = new Table(mInnerGroup, style);
|
||||
mTable.setHeaderVisible(true);
|
||||
@@ -127,7 +115,7 @@ public class SdkTargetSelector {
|
||||
setTargets(targets);
|
||||
setupTooltip(mTable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the layout data of the inner composite widget that contains the target selector.
|
||||
* By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH}
|
||||
@@ -166,8 +154,7 @@ public class SdkTargetSelector {
|
||||
* The event's item contains a {@link TableItem}.
|
||||
* The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
|
||||
* <p/>
|
||||
* It is recommended that the caller uses the {@link #getFirstSelected()} and
|
||||
* {@link #getAllSelected()} methods instead.
|
||||
* It is recommended that the caller uses the {@link #getSelected()} method instead.
|
||||
*
|
||||
* @param selectionListener The new listener or null to remove it.
|
||||
*/
|
||||
@@ -188,19 +175,22 @@ public class SdkTargetSelector {
|
||||
if (!mAllowSelection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
boolean found = false;
|
||||
boolean modified = false;
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if ((IAndroidTarget) i.getData() == target) {
|
||||
found = true;
|
||||
if (!i.getChecked()) {
|
||||
|
||||
if (mTable != null && !mTable.isDisposed()) {
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if ((IAndroidTarget) i.getData() == target) {
|
||||
found = true;
|
||||
if (!i.getChecked()) {
|
||||
modified = true;
|
||||
i.setChecked(true);
|
||||
}
|
||||
} else if (i.getChecked()) {
|
||||
modified = true;
|
||||
i.setChecked(true);
|
||||
i.setChecked(false);
|
||||
}
|
||||
} else if (i.getChecked()) {
|
||||
modified = true;
|
||||
i.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,30 +202,15 @@ public class SdkTargetSelector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all selected items.
|
||||
* This is useful when the table is in multiple-selection mode.
|
||||
* Returns the selected item.
|
||||
*
|
||||
* @see #getFirstSelected()
|
||||
* @return An array of selected items. The list can be empty but not null.
|
||||
* @return The selected item or null.
|
||||
*/
|
||||
public IAndroidTarget[] getAllSelected() {
|
||||
ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if (i.getChecked()) {
|
||||
list.add((IAndroidTarget) i.getData());
|
||||
}
|
||||
public IAndroidTarget getSelected() {
|
||||
if (mTable == null || mTable.isDisposed()) {
|
||||
return null;
|
||||
}
|
||||
return list.toArray(new IAndroidTarget[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first selected item.
|
||||
* This is useful when the table is in single-selection mode.
|
||||
*
|
||||
* @see #getAllSelected()
|
||||
* @return The first selected item or null.
|
||||
*/
|
||||
public IAndroidTarget getFirstSelected() {
|
||||
for (TableItem i : mTable.getItems()) {
|
||||
if (i.getChecked()) {
|
||||
return (IAndroidTarget) i.getData();
|
||||
@@ -311,7 +286,7 @@ public class SdkTargetSelector {
|
||||
* items when this one is selected.
|
||||
*/
|
||||
private void enforceSingleSelection(TableItem item) {
|
||||
if (!mAllowMultipleSelection && item.getChecked()) {
|
||||
if (item.getChecked()) {
|
||||
Table parentTable = item.getParent();
|
||||
for (TableItem i2 : parentTable.getItems()) {
|
||||
if (i2 != item && i2.getChecked()) {
|
||||
@@ -335,7 +310,11 @@ public class SdkTargetSelector {
|
||||
* </ul>
|
||||
*/
|
||||
private void fillTable(final Table table) {
|
||||
|
||||
|
||||
if (table == null || table.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
table.removeAll();
|
||||
|
||||
if (mTargets != null && mTargets.length > 0) {
|
||||
@@ -366,6 +345,11 @@ public class SdkTargetSelector {
|
||||
* display the description in a label under the table.
|
||||
*/
|
||||
private void setupTooltip(final Table table) {
|
||||
|
||||
if (table == null || table.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reference:
|
||||
* http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
|
||||
|
||||
Reference in New Issue
Block a user