2009-05-26 4 views
3

Я в настоящее время борется со следующими Eclipse RCP команды:Eclipse RCP: как наблюдать состояния команд cut/copy/paste?

  • org.eclipse.ui.edit.cut
  • org.eclipse.ui.edit.copy
  • org.eclipse.ui.edit.paste

Я их, используя в качестве командных взносов на панели инструментов, но UIElements (элементы панели инструментов) не обновляются, когда изменяется состояние этих команд «handled».

Для тестирования я использовал механизм опроса для проверки того, что состояние этих команд действительно изменяется в зависимости от текущего сосредоточенного элемента, и я обнаружил, что обработчик остается тем же, но состояние обработанного обработчика изменяется правильно, команд "обработано", чтобы также правильно изменить.

Единственная проблема в том, что ни один из этих изменений состояния вызывает уведомление (ни на Командования ICommandListener, ни на хендлере IHandlerListener), поэтому UIElements не будет обновляться.

Вот некоторые тестирования кода для наблюдения состояния команды:

ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); 

final String commandId="org.eclipse.ui.edit.copy"; 
Command command = commandService.getCommand(commandId); 
command.addCommandListener(new ICommandListener() { 

    public void commandChanged (CommandEvent commandEvent) { 
     System.out.println(">> Command changed: " + commandId); 
    } 
}); 

Am я что-то отсутствует, или это ошибка в реализации вырезать/копировать/вставлять обработчик? Любые идеи?

EDIT: команд включены все время, и обработчик никогда не обменивается, только «handled» состояния обработчика (и, таким образом, также на вводе команды в «handled» состояния) меняется в зависимости от пользовательского интерфейса элемент имеет фокус , Однако при изменении этого состояния уведомления не поступают. Это приводит к тому, что кнопки панели инструментов всегда включаются, и при нажатии на них вызывается org.eclipse.core.commands.NotHandledException: There is no handler to execute for command.

ответ

-1

Ваша проблема заключается в том, что вам необходимо зарегистрировать обработчик для всего, что не является текстом, потому что Eclipse должен знать, как скопировать выбранное в данный момент «что-то» в буфер обмена. Это то, что делает обработчик. This article В вики Eclipse вы узнаете, как создать и зарегистрировать обработчик.

+0

Это состояние «обработано», которое меня интересует. Когда фокус не находится в текстовом поле, все три команды включены, но не обрабатываются (обработчик установлен, но не обрабатывается). Когда команда вызывается нажатием кнопки на панели инструментов, тогда это приведет к появлению «org.eclipse.core.commands.NotHandledException: обработчик не выполняется для команды» –

+0

Ах ... теперь это имеет смысл. Я обновил мою Ответ: –

+0

Я в порядке, когда команда временно не обрабатывается (например, когда фокус меняется с текстового поля на кнопку, тогда нет ничего, что можно было бы вырезать/скопировать/вставить), но в этом случае я бы хотел чтобы получить уведомление, чтобы я мог отключить элемент toobar до тех пор, пока команда не обрабатывается. Я мог бы, конечно, зарегистрировать макет h andler для указанных команд, поэтому по крайней мере исключение возникает при попытке выполнить их, но я бы предпочел отключить элементы панели инструментов/меню. –

-1

Я мог ошибаться, но источником проблемы является то, что обработчик всегда включен.

См. Platform Plug-in Developer Guide > Programmer's Guide > Plugging into the workbench > Basic workbench extension points using commands > Handlers.

В <activeWhen/> выражения в ядре plugin.xml и программной выражения используются для определения сферы действия активации обработчиков. Например, конкретное окно, специфическое Shell, активный тип детали или активная часть.

<extension 
     point="org.eclipse.ui.handlers"> 
     ... 
     <handler 
      class="org.eclipse.ui.examples.contributions.view.SwapInfoHandler" 
      commandId="org.eclipse.ui.examples.contributions.view.swap"> 
     <activeWhen> 
      <reference 
        definitionId="org.eclipse.ui.examples.contributions.view.inView"> 
      </reference> 
     </activeWhen> 
     <enabledWhen> 
      <count 
        value="2"> 
      </count> 
     </enabledWhen> 
     </handler> 
     ... 
+0

Это допустимо для того, чтобы обработчик был включен, но не «обработан». Условие «activeWhen» является необязательным, если не указано, обработчик будет активным все время. Проблема в том, что изменения в обработчике не сообщаются, а конкретный обработчик для cut/copy/paste не может быть обнаружен. –

1

Обработчик, который зарегистрирован для/копирования команд вырезать/вставить это org.eclipse.ui.internal.handlers.WidgetMethodHandler.Этот обработчик проверяет, объявлен ли данный метод в управлении фокусом текущего дисплея. При выполнении этот обработчик вызовет метод с использованием отражения.

Отрывок из WidgetMethodHandler:

public final boolean isHandled() { 
    return getMethodToExecute() != null; 
} 

getMethodToExecute() будет найти текущий контроль фокусировки с помощью Display.getCurrent().getFocusControl(), а затем проверить, если данный метод триггер объявлен на нем.

Widgets, такие как org.eclipse.swt.widgets.Text имеют cut(), copy() и paste() методы, поэтому, когда фокус находится на таком виджете, обработчик будет возвращать «истина» для isHandled().

Этот обработчик, однако, не знает, когда изменяется текущий контроль фокусировки (я думаю, что на дисплее нет даже способа наблюдать это), и поэтому он не может уведомлять об изменениях в динамическом состоянии isHandled.

Это приводит к тому, что команды вырезать/копировать/вставить отлично подходят для всплывающих меню, но они довольно проблематичны при использовании в панелях инструментов, так как их элементы пользовательского интерфейса не могут быть правильно обновлены, когда обработчик не делает никаких уведомлений.

Это оставляет меня либо без использования этих команд на панели инструментов, либо с помощью опроса mechansim для обновления элементов ui (что также плохо и подвержено ошибкам). :-(

Смежные вопросы