Статьи

Adobe AIR — Использование буфера обмена для передачи данных

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

В случае перетаскивания пользователь щелкает элемент пользовательского интерфейса (например, изображение или текстовый файл), перетаскивает его в новое место и отпускает кнопку мыши для завершения транзакции, перемещая или копируя таким образом данные (изображение или текстовый файл.)

Для копирования и вставки требуется, чтобы пользователь выбирал элемент пользовательского интерфейса с помощью параметра меню, сочетания клавиш или кнопки, а затем пользователь мог перемещаться или копировать в новое место с помощью параметра меню, сочетания клавиш или кнопка в новом месте. Однако в обеих операциях должен быть носитель передачи — место, где данные временно помещаются во время их перемещения или копирования. В AIR это средство передачи называется буфером обмена, и в следующих нескольких разделах мы узнаем больше о том, что такое буфер обмена и как с ним работать.

Эта статья основана на главе 4 из Adobe Air in Action Джозефа Лотта, Кэтрин Ротондо, Сэма Анна и Эшли Аткинс . Это воспроизводится здесь с разрешения Manning Publications . Книги раннего доступа Manning и электронные книги продаются исключительно через Manning. Посетите страницу книги для получения дополнительной информации

[img_assist | nid = 7614 | title = | desc = | link = url | url = http: //www.manning.com/lott/ | align = right | width = 150 | height = 198]
Что такое буфер обмена?

Буфер обмена — это метафора, которую компьютеры используют для перемещения или копирования данных. Скорее всего, вы уже знакомы с системным буфером обмена, используемым вашей операционной системой, который позволяет копировать и вставлять. Например, если вы хотите скопировать текст из вашей почтовой программы и вставить его в документ Word, вы используете системный буфер обмена за кулисами.

Мы будем работать с двумя разными видами буфера обмена. Одним из типов буфера обмена является системный буфер обмена, который мы только что упомянули. Вы увидите, как вы можете записывать данные в системный буфер обмена для использования в других приложениях. Мы также будем работать с буфером обмена, специфичным для AIR. В любом случае, AIR обрабатывает оба этих буфера обмена одинаково, и вы можете получить к ним доступ через экземпляры класса flash.desktop.Clipboard.

Что вы можете сделать с объектами буфера обмена? Оказывается, объекты буфера обмена относительно просты. Говоря простым языком, вы можете сделать с буфером обмена всего три вещи: добавить данные в буфер обмена, прочитать данные из буфера обмена, удалить данные из буфера обмена. Мы подробно рассмотрим различные способы выполнения этих задач, но в целом это то, что вы можете сделать с объектом Clipboard.

Если вы хотите работать с объектом Clipboard, первое, что вам нужно сделать, это создать ссылочный объект. Мы будем работать с обоими типами буфера обмена: для AIR и системного буфера обмена. Поэтому вам нужно знать, как ссылаться на оба типа. Получить ссылку на системный буфер обмена так же просто, как получить доступ к статическому свойству Clipboard.generalClipboard.

var systemClipboard:Clipboard = Clipboard.generalClipboard;

Мы также будем использовать множество специальных буферов обмена AIR. В этих случаях вам нужно использовать конструктор Clipboard, который не требует параметров. Следующее создает новый объект буфера обмена.

var clipboard:Clipboard = new Clipboard();

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

Понимание форматов данных

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

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

clipboard.setData(ClipboardFormats.TEXT_FORMAT, “example text”);

Как мы только что увидели в этом примере, вы можете использовать константы flash.desktop.ClipboardFormats для ссылки на наиболее распространенные форматы. Эти константы и их эквиваленты ActionScript показаны в таблице 1. Это форматы, которые наиболее универсально поняты другими приложениями. Это означает, что вы можете добавить в буфер обмена растровые или текстовые данные из приложения AIR и знать, что, вероятно, пользователь сможет скопировать их в другое приложение на своем компьютере (например, Word). Аналогично. обратное также верно: это форматы, которые большинство приложений будут записывать в буфер обмена, и поэтому они доступны для чтения в приложении AIR.

постоянная Эквивалент Actionscript
BITMAP_FORMAT BitmapData
FILE_LIST_FORMAT Массив объектов File
HTML_FORMAT Строка в формате HTML
TEXT_FORMAT строка
URL_FORMAT строка

In addition to the standard formats listed in Table 4.1 you can transfer objects by reference for use in the same application or in a serialized format that might be valid in other applications that know how to interpret the data.

Например, предположим, что у вас есть несколько элементов информации, таких как имя, почтовый адрес, город, штат / провинция и почтовый индекс, которые вы хотели бы объединить в одном устройстве в экземпляре пользовательского класса Address. Используя стандартные форматы, можно было бы записать любой из этих фрагментов данных в буфер обмена, но не все сгруппированные вместе. Вместо этого вы можете использовать свой собственный формат имени. В этом примере адрес имени формата может быть подходящим. В таком случае все, что необходимо, — это то, что приложение, которое читает из буфера обмена, знает как имя (адрес) формата данных, так и способ десериализации данных. Когда мы говорим о сериализации данных, которая может относиться к пользовательской сериализации (например, XML-строке) или использованию встроенной поддержки AIR AMF.В следующем примере предполагается, что userAddress является объектом Address (помните, что в нашем сценарии Address является пользовательским классом), и он автоматически сериализует объект с использованием AMF.

clipboard.setData(“address”, userAddress);

Теперь мы знаем, что такое буфера обмена, и знаем, какие форматы мы можем хранить или извлекать из буфера обмена. Следующий логический шаг — начать чтение и запись данных из буфера обмена и в него.

Чтение и запись данных

Буфер обмена — довольно пассивные объекты. Они не делают много. Скорее, это области хранения, где вы можете записывать данные и читать данные. Например, если вы хотите сделать снимок содержимого окна AIR и сделать его доступным для вставки в документ Word, вам нужно будет записать эти данные изображения в буфер обмена. С другой стороны, если вы скопировали файл со своего рабочего стола и хотите вставить его в приложение AIR, например, чтобы добавить его в список файлов, вам нужно будет прочитать информацию об этом файле из буфера обмена.

Вы можете записывать данные в буфер обмена с помощью метода setData (), как мы уже видели в предыдущем разделе. Метод setData () всегда требует, чтобы вы указали два параметра: формат и данные для записи в буфер обмена. В следующем примере записывается текущее значение элемента управления вводом текста в буфер обмена с использованием текстового формата.

clipboard.setData(ClipboardFormats.TEXT_FORMAT, textInput.text);

Вы можете добавить более одного формата в буфер обмена одновременно. Например, если пользователь копирует изображение из вашего приложения AIR, вы можете разрешить ему вставить его в программу для редактирования изображений или на рабочий стол в виде файла изображения. В этом случае вам необходимо добавить данные в двух форматах: BITMAP_FORMAT и FILE_LIST_FORMAT. Каждый формат требует различного типа данных, чтобы он имел смысл для получателя данных, в этом случае. Данные BITMAP_FORMAT должны быть объектом BitmapData, тогда как FILE_LIST_FORMAT должен быть массивом одного или нескольких объектов File.

Вы можете читать данные из буфера обмена, используя метод getData (). Метод getData () требует только один параметр: формат данных для извлечения. В следующем примере извлекаются данные из буфера обмена в текстовом формате.

var text:String = clipboard.getData(ClipboardFormats.TEXT_FORMAT) as String;

Вы заметите, что в этом примере возвращаемое значение getData () приводится к типу String. Это потому, что getData () обязательно имеет тип возврата универсального объекта. Если вы попытаетесь использовать значение таким способом, который требует более определенного типа (например, при присваивании значения типизированной переменной), вам придется привести его соответствующим образом. Конечно, вам нужно знать, какой должен быть правильный тип для приведения. В случае текстового формата, формата url и формата html вы знаете, что должны быть преобразованы как String. Для растрового формата вы должны использовать BitmapData. А для формата списка файлов вы должны преобразовать его в массив (зная, что каждый элемент массива является объектом File). Для пользовательских форматов вам необходимо знать исходный формат данных, прежде чем они будут записаны в буфер обмена.

Если вы не уверены, есть ли в буфере обмена данные в определенном формате, вы можете использовать метод hasFormat () для запроса этой информации. Метод требует, чтобы вы указали формат, и возвращает логическое значение: true, если в буфере обмена есть данные для этого формата, и false в противном случае.

Удаление данных из буфера обмена

Вы можете не только устанавливать и получать данные в буфер обмена, но и удалять данные из буфера обмена. Например, если вы записываете данные в системный буфер обмена в определенном формате, вы не обязательно гарантируете, что в этот буфер обмена уже не записаны другие фрагменты данных в разных форматах. Когда пользователь отправляет запрос данных из буфера обмена, результаты могут быть непредсказуемыми, потому что разные приложения могут иметь разные прецеденты формата. Например, если вы вставляете в Word, приложение всегда вставляет текст из буфера обмена, если он доступен, игнорируя другие форматы, которые могут быть в буфере обмена.Возможно, вы можете записать данные в формате растрового изображения в системный буфер обмена из приложения AIR, а затем, если пользователь вставит их в документ Word, он увидит только другой текст, который он ранее скопировал из другой программы. Поэтому вам нужны методы для удаления данных из буфера обмена.

ПРИМЕЧАНИЕ.
Именно по той причине, которая описана в предыдущем сценарии, вы всегда должны очищать системный буфер обмена перед записью данных в него.

Метод clearData () позволяет очистить данные из буфера обмена для определенного формата. Например, если вы хотите удалить данные формата URL из буфера обмена, вы можете использовать следующий код.

clipboard.clearData(ClipboardFormats.URL_FORMAT);

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

clipboard.clear();

Как видите, метод clear () не требует никаких параметров. Он просто удаляет все данные.
Теперь вы видели, как записывать данные, читать данные и удалять данные. Мы еще не говорили о том, как данные хранятся в буфере обмена и как это может повлиять на доступность данных как в приложении AIR, так и вне AIR. В следующем разделе мы поговорим о том, как вы можете использовать режимы передачи, чтобы влиять на способ хранения данных.

Понимание режимов передачи

Существует множество сценариев, в которых вы можете использовать буфер обмена. Основные три следующие.

  • Перенос данных в одном приложении AIR
  • Передача данных между приложениями AIR
  • Передача данных между приложением AIR и операционной системой или другим приложением, отличным от AIR

The second and third scenarios require that a copy of the data is made. For example, if you want to copy text from an AIR application to a Word document, Word is not capable of reading the text directly from the AIR application. Instead, an actual copy of the text must be made. This is true between AIR applications as well. If you have a custom Address type that is available in two AIR applications and you want to transfer an Address object from one AIR application to another, you must make a copy of the Address object. The second AIR application cannot access the original Address object in order to read from it.

However, the first scenario is different. When you want to transfer data within a single AIR application it is possible to access data by reference, not just by value. By default when you write data to a clipboard it is always serializable, meaning that both a copy and a reference are written to the clipboard. If you want to explicitly control whether or not the data you write is serializable you can specify a third Boolean parameter for the setData() method. A value of true (the default) means a copy and a reference are written and false means that only a reference is written. You only need to use this parameter if you want to make sure that data isn’t serialized and copied.

NOTE
Even if you set the third parameter of setData() to false, all standard formats are still available to non-AIR applications. Using a value of false only affects data in custom formats for use within AIR applications.

On the flip side, you can also specify how you want to retrieve data when calling getData(). You can do this by way of a second, optional parameter that indicates a transfer mode. There are four transfer modes, each with a constant in the flash.desktop.ClipboardTransferMode class. The constants are as follows.

  • ORIGINAL_PREFERRED – In this mode a reference to the original is returned if it is available. If no reference is available then a copy is returned. Remember that references are only available within the same AIR application from which the data originated. If you specify this transfer mode and the data originated from another application then it will always return the copy of the data. This transfer mode is the default.
  • ORIGINAL_ONLY – In this mode the reference to the original data is returned if it is available. Otherwise, if the original is unavailable null is returned.
  • CLONE_PREFERRED – In this mode a copy of the data is returned if available. Otherwise a reference is returned.
  • CLONE_ONLY – In this mode only a copy is returned if available. Otherwise null is returned.

У нас есть еще одна тема, которую мы рассмотрим, прежде чем мы сможем перейти к использованию буферов обмена. Далее мы обсудим, как вы можете быть умными с тем, как и когда вы записываете данные в буфер обмена.

Отложенный рендеринг

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

  • Данные велики, или для записи данных в буфер обмена потребовалось бы много вычислительных ресурсов.
  • The data might update between the time it is selected and the time it is requested, and you want to always get the most up-to-date data at the time it is requested

Admittedly both of these are edge-cases, but it’s good to know that should you have such a need AIR supports deferred rendering. If you want to enabled deferred rendering then you should not use setData(). Instead, you should use setDataHandler(). The setDataHandler() method also requires that you specify the format. However, instead of specifying the data, you instead pass the method a reference to a handler method. When the user requests the data of that format from the clipboard AIR will call the handler method and use the value returned by the handler method. That means you must make sure the return value of the handler method is the expected type for the format. Consider the following example.

clipboard.setDataHandler(ClipboardFormats.TEXT_FORMAT, getText);

In this example the format is set to text, which means that the handler method (getText()) must return a String as in the following.

private function getText():String {
return textArea.text;
}

If you want to defer rendering by using setDataHandler() then you must make sure you haven’t set data using setData() because setData() will always take precedence over setDataHandler(). If you’ve already written data to a clipboard using setData() and you want to use deferred rendering for the same format just call clearData() for that format before calling setDataFormat().

The handler method specified by setDataHandler() does not get called until the user requests the data (e.g. she pastes into a Word document.) However, AIR will only call the handler method that once. Subsequent requests for the data will retrieve the same data from the clipboard that was returned when the method was first called.

Now we’ve covered all the necessary preliminary topics related to clipboards, and we’re ready to start writing code that uses clipboards.