Философия Java

Буфер обмена


JFC поддерживает ограниченное число операций с системным буфером обмена (в пакете java.awt.datatransfer). Вы можете скопировать объект String в буфер обмена как текст, и вы можете вставить текст из буфера обмена в объект String. Конечно, буфер обмена предназначен для хранения данных любого типа, но как представить эти данные в буфере обмена, если программа выполняет вырезание и вставку. Java API для буфера обмена обеспечивает расширяющуюся концепцию “особенностей”. Когда данные приходят из буфера обмена, они имеют множество особенностей, которыми они могут быть представлены (например, графика может быть представлена как строка чисел или как изображение) и вы можете видеть, поддерживает ли определенный буфер интересующие вас особенности.

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

//: c13:CutAndPaste.java

// Использование буфера обмена.

import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.awt.datatransfer.*; import com.bruceeckel.swing.*;

public class CutAndPaste extends JFrame { JMenuBar mb = new JMenuBar(); JMenu edit = new JMenu("Edit"); JMenuItem cut = new JMenuItem("Cut"), copy = new JMenuItem("Copy"), paste = new JMenuItem("Paste"); JTextArea text = new JTextArea(20, 20); Clipboard clipbd = getToolkit().getSystemClipboard(); public CutAndPaste() { cut.addActionListener(new CutL()); copy.addActionListener(new CopyL()); paste.addActionListener(new PasteL()); edit.add(cut); edit.add(copy); edit.add(paste); mb.add(edit); setJMenuBar(mb); getContentPane().add(text); } class CopyL implements ActionListener { public void actionPerformed(ActionEvent e) { String selection = text.getSelectedText(); if (selection == null) return; StringSelection clipString = new StringSelection(selection); clipbd.setContents(clipString,clipString); } } class CutL implements ActionListener { public void actionPerformed(ActionEvent e) { String selection = text.getSelectedText(); if (selection == null) return; StringSelection clipString = new StringSelection(selection); clipbd.setContents(clipString, clipString); text.replaceRange("", text.getSelectionStart(), text.getSelectionEnd()); } } class PasteL implements ActionListener { public void actionPerformed(ActionEvent e) { Transferable clipData = clipbd.getContents(CutAndPaste.this); try { String clipString = (String)clipData. getTransferData( DataFlavor.stringFlavor); text.replaceRange(clipString, text.getSelectionStart(), text.getSelectionEnd()); } catch(Exception ex) { System.err.println("Not String flavor"); } } } public static void main(String[] args) { Console.run(new CutAndPaste(), 300, 200); } } ///:~


Создание и добавление меню и JTextArea должно теперь выглядеть прозаическим действием. Что отличается, так это создание поля Clipboard clipbd, которое выполняется через Toolkit.

Все действия происходят в слушателях. Слушатели CopyL и CutL одинаковы, за исключением того, что последняя строка в CutL стирает скопированную строку. Специальные две строки создания объекта StringSelection из String вызывают setContents( ) с этим StringSelection. Это все, что нужно для помещения String в буфер обмена.

В PasteL данные вытягиваются из буфера обмена, используя getContents( ). Что приходит - это совершенно анонимный объект Transferable, который возвращает массив объектов DataFlavor, указывает, какие особенности поддерживаются определенным объектом. Вы можете так же спросить его напрямую с помощью isDataFlavorSupported( ), передав особенность, которая вас интересует. Однако здесь выбран самонадеянный подход: вызывается getTransferData( ) в надежде, что содержимое поддерживает особенности String, а если это не так, проблема выявляется в обработчике исключения.

В будущем вы можете ожидать поддержку большего числа особенностей.


Содержание раздела