چگونه می توان توسط جاوا محتویات متنی موجود در Clipboard را خواند؟

در ابن مقاله نحوه خواندن محتویات موجود در Clipboard مورد بررسی قرار می گیرد. البته محتویات متنی موجود در Clipboard ! قبل از شروع کار بهتر است با واژه Data Transfer آشنا شویم.

Data Transfer به قابلیتی در برنامه های کاربردی اشاره دارد که در آن برنامه قادر به انتقال داده های انتخاب شده – بدون توجه به روشهای مختلف انتخاب کردن – باشد. بطور مثال فرض کنید که می خواهید متنی را از یک Textbox به Textbox دیگر منتقل نمایید. یعنی عمل CUT را انجام دهید. انجام چنین کاری با استفاده از تکنیک Data Transfer امکان پذیر می باشد. موارد استفاده این تکنیک در cut-and-paste و drag-and-drop می باشد.

پس برای شروع لازم است تا بسته java.awt.datatransfer در برنامه import نمایید. این بسته شامل دو کلاس اصلی می باشد.

۱- کلاس DataFlavor : از این کلاس برای توصیف نوع و فرمت داده ای که قصد انتقال آن را داریم، استفاده می شود.

مکانیزم انتقال داده ها، به روشی دقیق، سریع، مفید و قابل حمل جهت شناسایی نوع داده ای که قصد حمل کردن آن را دارد، نیازمند می باشد. نکته مهم و ضروری در این میان آن است که هر دو طرف عمل انتقال، باید بصورت دقیق و واضح نوع داده را بدانند. نکته مهم دیگر آن است که ممکن است برنامه های کاربردی دو طرف عمل انتقال، از یک نوع نبوده و دارای ساختارهای متفاوتی باشند. مثلا برنامه کاربردی مبدا با جاوا تولید شده باشد و طرف مقصد با دلفی. حال توجه به این نکته بسیار ضروری به نظر می رسد که مکانیزم شناسایی نوع و فرمت داده باید انعطاف پذیر و عمومی و قابل فهم توسط هر دو طرف انتقال باشد.

کلاس DataFlavor وظایف فوق را بخوبی انجام می دهد. این کلاس برای مشخص کردن نوع و فرمت داده ها، از انواع استاندارد داده یعنی MIME TYPE اسفاده می کند. به عنوان نمونه می توان به فرمتهای “text/html” و “image/jpeg” اشاره نمود.

این کلاس برای راحتی کار در شناسایی نوع و فرمت داده ها یک سری ثوابت برای تعیین نوع‌، انواع معمول داده ها تعریف کرده است. مانند:

۱- DataFlavor.stringFlavor

۲- DataFlavor.plainTextFlavor

۳- DataFlavor.javaFileListFlavor

برای تعیین نوع سایر انواع داده ها، می توانید از ثوابت سفارشی که توسط برنامه نویس تعریف می شود استفاده نمایید. به عنوان نمونه، به عبارت زیر توجه نمایید:

DataFlavor jpegFlavor = new DataFlavor(“image/jpeg”, “JPEG Image Data”);

DataFlavor pointFlavor = new DataFlavor(java.awt.Point.class,”Java Point Object”);

۲- واسط Transferable : این واسط نیز متد های مورد نیاز برای انتقال داده ها را تعریف می کند.

در کلاس قبل فقط نوع و فرمت داده تعیین می شود و خبری از خود داده و یا انتقال داده وجود ندارد. در واقع عمل انتقال توسط واسط Transferable صورت می‌پذیرد. داده هایی که قرار است منتقل شوند توسط این واسط کپسوله شده و بعد منتقل می شوند.

همانطور که در مورد قبل اشاره شد، ممکن است عمل انتقال داده ها بین محیط های متفاوت صورت پذیرد. پس باید به گونه ای داده ها منتقل شوند تا هر محیطی قادر به استفاده از آنها باشد. راه حل پیشنهادی برای این مشکل آن است که داده های مورد نظر را در فرمت های مختلف ارسال نماییم. بطور مثال فرض کنید که قصد انتقال یک String را از محیط جاوا دارید. مقصد نیز ممکن است جاوایی باشد یا محیطی غیر از جاوا. پس برای ارسال داده ها باید از دو فرمت java String Object یا Stream of Unicode Characters استفاده نمایید. اگر مقصد محیط جاوا بود از نوع اول استفاده می کند و در غیر اینصورت از نوع دوم.

واسط transferable سه متد زیر را تعریف می کند:

۱- getTransferDataFlavors : این متد آرایه ای از اشیایی از نوع Dataflavor باز می گرداند که بیانگر نوع داده هایی است که قصد انتقال آنها را داریم.

۲ – isDataFlavorsSupported : همانطور که از نام متد مشخص است، این متد بررسی می کند که آیا نوع و فرمت داده توسط محیط پشتیبانی می شود؟

۳- getTransferData : این متد انجام عمل انتقال داده ها را بر عهده دارد. این متد یک آرگومان ورودی دارد که نوع داده ای که قرار است انتقال دهد را مشخص می کند. اگر نوع داده ارسالی به این متد، پشتیبانی نشود، خطای زیر صادر خواهد شد:

UnsupportedFlavorException

«نکته» به علت اینکه نوع داده text بسیار زیاد مورد استفاده قرار می گیرد، در بسته java.awt.datatransfer کلاسی با نام StringSelection تعبیه شده است که مختص انتقال داده های متنی می باشد. این کلاس از دو نوع داده DataFlavor.stringFlavor و DataFlavor.plainTextFlavor پشتیبانی می‌کند.

برنامه TextTransfer.java نشان می دهد که چگونه به Clipboard دسترسی یافته و داده های متنی موجود در آن را بدست آورده و نمایش دهیم.

import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.Toolkit;
import java.io.*;

public final class TextTransfer implements ClipboardOwner {
public static void main (String… aArguments ){
TextTransfer textTransfer = new TextTransfer();

//display what is currently on the clipboard
System.out.println(“Clipboard contains:” + textTransfer.getClipboardContents() );

//change the contents and then re-display
textTransfer.setClipboardContents(“WWW.IranjavaRef.ir”);
System.out.println(“Clipboard contains:” + textTransfer.getClipboardContents() );
}

/**
* Empty implementation of the ClipboardOwner interface.
*/
public void lostOwnership( Clipboard aClipboard, Transferable aContents) {
//do nothing
}

/**
* Place a String on the clipboard, and make this class the
* owner of the Clipboard’s contents.
*/
public void setClipboardContents( String aString ){
StringSelection stringSelection = new StringSelection( aString );
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents( stringSelection, this );
}

/**
* Get the String residing on the clipboard.
*
* @return any text found on the Clipboard; if none found, return an
* empty String.
*/
public String getClipboardContents() {
String result = “”;
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
//odd: the Object param of getContents is not currently used
Transferable contents = clipboard.getContents(null);
boolean hasTransferableText = (contents != null) &&contents.isDataFlavorSupported(DataFlavor.stringFlavor);
if ( hasTransferableText ) {
try {
result = (String)contents.getTransferData(DataFlavor.stringFlavor);
}catch (UnsupportedFlavorException ex){
//highly unlikely since we are using a standard DataFlavor
System.out.println(ex);
ex.printStackTrace();
} catch (IOException ex) {
System.out.println(ex);
ex.printStackTrace();
}
}
return result;
}
}

تصویر زیر خروجی این برنامه را در محیط NetBeans نمایش می دهد. دقت کنید که قبل از اجرای برنامه رشته زیر را در Clipboard قرار داده ایم.

Get the String residing on the clipboard.