Статьи

Помни государство

Как правило, ваше приложение должно пытаться запомнить состояние между сеансами. Поэтому, когда пользователь нажимает кнопку закрытия, а затем открывает ее через несколько минут / дней, он должен отображаться точно так же, как он ушел. В этом совете я собираюсь объяснить несколько вещей о том, как этого можно достичь.

Прежде всего, это количество открытых окон, текущая перспектива и ее состояние в каждом окне. Если вы пишете плагин для IDE, вам не нужно беспокоиться об этом. Затмение делает это для вас. Если вы приложение RCP, вы должны сделать это самостоятельно. Вы должны сделать это в методе WorkbenchAdvisor.initialize ():

public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {

@Override
public void initialize(IWorkbenchConfigurer configurer) {

super.initialize(configurer);
configurer.setSaveAndRestore(true);
}

// other methods ...
}

Теперь это позаботится о многих вещах — о количестве открытых окон; расположение и размер этих окон; перспектива каждого окна; просматривать & редакторы в каждой перспективе; их местоположения, … все путем установки этой одной логической переменной!

Теперь, когда Eclipse восстановил наши взгляды и редакторы, нам необходимо обеспечить их состояние. Большинство представлений будет основано на дереве / таблице. В этих случаях текущий выбор является важным для восстановления.

Для хранения этих предметов и любых других вещей, которые вы хотите, Eclipse предоставляет IMemento. Экземпляр этого IMemento передается представлению при его инициализации и закрытии рабочей среды. Информация может храниться иерархически с помощью строковых ключей, и она будет сохранена в виде XML. Если вы задаетесь вопросом, почему это не может быть так просто, как передача объекта Serializable Java и инструментальные средства, сохраняющие его, ответ прост. Тот же класс может отсутствовать, когда Eclipse запускается в следующий раз, или даже если тот же класс доступен, он мог измениться. IMemento позволяет избежать этой проблемы, сохраняя stae в виде строки XML.

Так как мы это используем? В представлении вы должны переопределить методы init () и saveState ():

@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
this.memento = memento;
super.init(site, memento);
}

public void createPartControl(Composite parent) {
// create the viewer
restoreSelection();
}

private void restoreSelection() {
if (memento != null) {
IMemento storedSelection = memento.getChild("StoredSelection");
if (storedSelection != null) {
// create a structured selection from it
viewer.setSelection(selection);
}
}
}

@Override
public void saveState(IMemento memento) {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
if (!selection.isEmpty()) {
IMemento storedSelection = memento.createChild("StoredSelection");
// store the selection under storedSelection
}
}

Не только выбор, мы можем хранить любую другую информацию (какие из узлов дерева расширены, настройки сортировки и фильтра и т. Д.), Которые будут полезны для восстановления состояния.

Great. Now moving on from the views, the next item would be dialogs. Similar to the workbench windows, you can store the size, location and other elements of a dialog as well. The functionality for size and location is available by default, but you need to enable it by overriding the Dialog.getDialogBoundsSettings() method. The Dialog class stores & retrieves the size and location from IDialogSettings returned from that method. The original implementation returns null, so nothing is saved. We need to create an instanceof IDialogSettings and return it. Your plugin’s Activator simplifies that. When required, it creates a dialog_settings.xml under your plugin’s data area and store the dialog settings of all the dialogs. You have to create a separate section for each dialog.

private static final String MY_DIALOG_SETTINGS = "MY_DIALOG_SETTINGS";

@Override
protected IDialogSettings getDialogBoundsSettings() {
IDialogSettings settings = Activator.getDefault().getDialogSettings();
IDialogSettings section = settings.getSection(MY_DIALOG_SETTINGS);
if (section == null) {
section = settings.addNewSection(MY_DIALOG_SETTINGS);
}
return section;
}

Если вы хотите сохранить только местоположение или размер, вы можете указать его, переопределив метод getDialogBoundsStrategy ().

Как и IMemento, IDialogSettings в основном организует строки ключ-значение иерархическим способом. Таким образом, наряду с размером и местоположением, вы можете хранить любую другую информацию в этом IDialogSettings. Рекомендуется сохранять значения виджетов (какая кнопка радиона выбрана, состояние флажка и т. Д.) В диалоговом окне, поэтому это быстрее для пользователя, который часто повторяет операцию.

Говоря о виджетах, более сложным является Combo. Когда список опций предопределен и пользователь не может ввести новое значение, тогда это просто. Но в местах, где пользователь может вводить значения (например, выбор файла / каталога, поля поиска), запомнить их не просто.

Мы не должны хранить каждое значение, введенное пользователем, а только недавно использованные. Вероятно, с лимитом 5 или 10 предметов только. Это можно сделать с помощью LinkedHashSet. Это гарантирует порядок элементов, поэтому всякий раз, когда пользователь вводит новые значения, сначала помещают текущее значение в набор, а затем добавляют остальные элементы (даже если первый элемент повторяется, это не изменит позицию). Затем возьмите первые N элементов и сохраните их.

 

private static final String COMBO_STATE="COMBO_STATE";

private static final int HISTORY_SIZE = 5;

private String []comboState;

private void restoreComboState(IDialogSettings settings) {
comboState = settings.getArray(COMBO_STATE);
if(comboState ==null)
comboState = new String[0];
for (String value : comboState) {
myCombo.add(value);
}
}

private void saveComboState(IDialogSettings settings) {

// use LinkedHashSet to have the recently entered ones
LinkedHashSet<String> newState = new LinkedHashSet<String>();
newState.add(myCombo.getText());
newState.addAll(Arrays.asList(comboState));

// now convert it to the array of required size
int size = Math.min(HISTORY_SIZE, newState.size());
String[] newStateArray = new String[size];
newState.toArray(newStateArray);

// store
settings.put(COMBO_STATE, newStateArray);
}

Последний кусок Посмотрите на этот диалог:

Иногда только впервые вы хотите задать вопрос пользователю. После этого, если пользователь предпочитает, вы можете использовать тот же ответ. Чтобы упростить это, вы можете использовать MessageDialogWithToggle. Вам нужно передать хранилище предпочтений и ключ для значения предпочтения. Когда пользователь устанавливает флажок, значение будет сохранено. Со следующего раза вы можете проверить значение из предпочтения и использовать его.

 

MessageDialogWithToggle.openYesNoQuestion(shell, "Remember me", "Is this tip useful?", 
"Don't bug me with this question again", true,
Activator.getDefault().getPreferenceStore(), "BUG_USER_KEY");

Там вы идете:

С http://blog.eclipse-tips.com