يصف المثال الموجود في هذه المقالة كيفية استخدام Java للسحب والإفلات بالماوس لتبادل بيانات البرنامج، وهو ما يسمى بوظيفة السحب والإفلات بالماوس. تُستخدم وظيفة السحب والإفلات الخاصة بالماوس بشكل شائع جدًا في الأنظمة الرسومية. توفر Java الحزمتين java.awt.dnd وjava.awt.datatransfer لدعم هذه الوظيفة. يوضح هذا المثال كيفية تنفيذ السحب والإفلات في البرنامج. عند النقر بالماوس على الملصق "Hello World!" في الجزء العلوي من النافذة، ثم سحبه إلى مربع النص الموجود في الجزء السفلي من النافذة، "Hello العالم!" ستتم إضافته إلى مربع النص.!" استمر في العملية المذكورة أعلاه وستستمر إضافة النص.
أفكار وأساليب التنفيذ المحددة لوظيفة البرنامج هي كما يلي: في تنفيذ السحب والإسقاط بالماوس، فإن أهم مفهومين هما مصدر السحب وهدف الإسقاط، وهما مصدر السحب وهدف الإسقاط. يرتبط كل من مصدر السحب وهدف الإسقاط بالمكون المرئي (كيف يمكنك السحب إذا لم يكن مرئيًا؟!). يتمثل جوهر تقنية السحب والإفلات في نقل البيانات الموجودة على مكون مصدر السحب والإفلات إلى مكون هدف الموضع، لذلك، من منظور منخفض المستوى، يكون السحب والإفلات قريبًا جدًا من تقنية الحافظة في المثال أعلاه.
تنفيذ مصدر السحب: يجب أن تقوم فئة مصدر السحب أولاً بإنشاء مثيل DragGestureRecognizer، مما يشير إلى أن الفئة عبارة عن فئة مكون مصدر سحب أو تحتوي على مكون مصدر سحب. يمكن تحقيق ذلك عن طريق استدعاء الأسلوب createDefaultDragGestureRecognizer() للكائن DataSource. التنفيذ المحدد هو كما يلي:
int action = DnDConstants.ACTION_COPY_OR_MOVE // نوع السحب والإفلات ds.createDefaultDragGestureRecognizer(this,action,this);
يوضح البيان أعلاه أن مكون مصدر السحب هو كائن مثيل لهذه الفئة نفسها، ونوع السحب والإفلات المراد إكماله هو من النوع DnDConstants.ACTION_COPY_OR_MOVE، والفئة التي تنفذ واجهة DragGestureListener هي هذه الفئة. ينفذ مصدر السحب بشكل عام واجهة DragGestureListener، التي تحدد طريقة DragGestureRecognized() عند بدء السحب، يستمع DragGestureListener إلى الحدث، ثم ينقل إلى طريقة DragGestureRecognized() لمعالجة الحدث، مثل إرسال بيانات السحب. مصدر. كود محدد:
public void DragGestureRecognized(DragGestureEvent dge) {//throw new java.lang.UnsupportedOperationException("لم يتم تنفيذ طريقة السحبGestureRecognized() بعد."); النص كبيانات، قابلة للتحويل تغليف الكائنات // ابدأ السحب، اضبط المؤشر على شكل DragSource.DefaultCopyNoDrop، وبيانات السحب والإفلات هي كائن tr، وDragSourceListener هو هذه الفئة dge.startDrag(DragSource.DefaultCopyNoDrop,tr,this);}catch(Exception err) {يخطئ.printStackTrace();}}
يجب أن يقوم مصدر السحب أيضًا بتنفيذ واجهة DragSourceListener، التي تحدد طرق معالجة الأحداث لكل حالة تتعلق بالسحب والإسقاط. مثل DragEnter، DragOver، DropActionChanged، DragExit وغيرها من الطرق. في هذا المثال، سيتم تنفيذ طريقة السحب () لتعيين شكل المؤشر أثناء السحب، وستكون الطرق الأخرى طرقًا فارغة. رمز التنفيذ المحدد هو كما يلي:
public void DragEnter(DragSourceDragEvent dsde) {//throw new java.lang.UnsupportedOperationException("لم يتم تنفيذ طريقة DragEnter() بعد.");DragSourceContext dsc = dsde.getDragSourceContext(); / اضبط شكل المؤشر عند السحب int action = dsde.getDropAction();if ((action&DnDConstants.ACTION_COPY)!=0)dsc.setCursor(DragSource.DefaultCopyDrop);elsedsc.setCursor(DragSource.DefaultCopyNoDrop);}
تنفيذ هدف الإسقاط: يجب إنشاء مثيل DragTarget أولاً في فئة هدف الإسقاط للإشارة إلى أن هذه الفئة هي فئة مكون هدف الإسقاط أو تحتوي على مكون هدف الإسقاط.
new DropTarget(this.jTextField1,DnDConstants.ACTION_COPY_OR_MOVE,this);
يوضح البيان أعلاه أن هدف الإسقاط هو هذا الكائن.jTextField1، وأن عملية السحب والإفلات هي من النوع DnDConstants.ACTION_COPY_OR_MOVE، والفئة التي تنفذ واجهة DropTargetListener هي هذه الفئة. وفقًا لـ DrafSourceListener، يقوم هدف الإسقاط أو فئته عمومًا بتنفيذ واجهة DropTargetListener. تحدد هذه الواجهة أيضًا العديد من الأساليب، مثل السحب والإفلات، وما إلى ذلك، للتعامل مع الأحداث عندما تدخل عملية السحب والإفلات مراحل مختلفة. يهتم هذا المثال فقط بطريقة drop()، وهي معالجة الحدث عند تحرير الماوس على مكون هدف الموضع، ويتم استخدامها بشكل عام لمعالجة البيانات التي تم تمريرها يتم عرضها على مكون JTextField. الطريقة الأخرى هي طريقة فارغة، والرمز المحدد هو كما يلي:
public void drop(DropTargetDropEvent dtde) {//throw new java.lang.UnsupportedOperationException("Method drop() لم يتم تنفيذه بعد.");try{Transferable tr = dtde.getTransferable(); معالجة كائن البيانات والحصول على المعلومات النصية إذا (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)){dtde.acceptDrop(dtde.getDropAction());String s = (String) tr.getTransferData(DataFlavor.stringFlavor);this.jTextField1.setText(this.jTextField1.getText() +ق)؛ // عرض المعلومات النصية التي تم تمريرها من مصدر السحب على هدف الإسقاط dtde.dropComplete(true);}else{dtde.rejectDrop();}}catch(Exception err){err.printStackTrace();}}
رمز البرنامج:
1. قم بإنشاء مشروع جديد وقم بتسميته JDragAndDropDemo.
2. قم بإنشاء تطبيق جديد وقم بتسميته JDragAndDropDemo؛ وقم بتسمية النافذة الرئيسية MainFrame وقم بتسميتها JDragAndDropDemo.
3. قم بإنشاء فئة جديدة، وقم بتسميتها DragJLabel، وارث فئة JLabel.
4. استخدم واجهة المعالجات|التنفيذات لجعل فئة DragJLabel تنفذ واجهات DragGestureListener وDragSourceListener.
5. أضف سمة جديدة DragSource ds في فئة DragJLabel، ويكون الكود كما يلي:
يمتد فئة DragJLabel إلى JLabel بتنفيذ DragGestureListener, DragSourceListener {DragSource ds = DragSource.getDefaultDragSource(); // إنشاء مثيل DragSource...}
6. اكتب طريقة البناء لفئة DragJLabel.
public DragJLabel(String title,intAlignment){super(title,alignment); // استخدم طريقة الفئة الأصلية int action = DnDConstants.ACTION_COPY_OR_MOVE;ds.createDefaultDragGestureRecognizer(this,action,this);
7. قم بتنفيذ طريقة DragGestureRecognized () في فئة DragJLabel، وقم بلف البيانات وإرسالها.
public void DragGestureRecognized(DragGestureEvent dge) {//throw new java.lang.UnsupportedOperationException("لم يتم تنفيذ طريقة السحبGestureRecognized() بعد.");try{Transferable tr = new StringSelection(this.getText());dge.startDrag(DragSource) .DefaultCopyNoDrop,tr,this);}catch(Exception يخطئ) {يخطئ.printStackTrace()؛}}
8. قم بتطبيق طريقة DragEnter () في فئة DragJLabel لتعيين شكل المؤشر.
public void DragEnter(DragSourceDragEvent dsde) {//throw new java.lang.UnsupportedOperationException("لم يتم تنفيذ طريقة DragEnter() بعد.");DragSourceContext dsc = dsde.getDragSourceContext();int action = dsde.getDropAction();if ((action&DnDConstants.ACTION_COPY)!=0)dsc.setCursor(DragSource.DefaultCopyDrop);elsedsc.setCursor(DragSource.DefaultCopyNoDrop);}
9. أضف مكون JTextField في الجزء السفلي من نافذة التصميم لفئة MainFrame، وقم بإنشاء مثيل DragJLabel في الفصل، الكود المحدد هو كما يلي:
الطبقة العامة MainFrame تمتد JFrame تنفذ DropTargetListener {private JPanel contentPane;private BorderLayout borderLayout1 = new BorderLayout();private JTextField jTextField1 = new JTextField();DragJLabel label = new DragJLabel("Hello World!",SwingConstants.CENTER);……}
10. اكتب طريقة التهيئة jbInit() لفئة MainFrame، وقم بتعيين الخصائص الأولية للمكون، وقم بإنشاء مثيل DropTarget جديد، ويكون الرمز كما يلي:
استثناء jbInit () باطل خاص {//setIconImage(Toolkit.getDefaultToolkit().createImage(MainFrame.class.getResource("[أيقونتك]")));contentPane = (JPanel) this.getContentPane();contentPane.setLayout (borderLayout1);this.setSize(new Dimension(410, 114));this.setTitle("JDragAndDropDemo");jTextField1.setFont(new java.awt.Font("Dialog", 0, 14));contentPane.add(jTextField1, BorderLayout.SOUTH);contentPane.add(this .label,BorderLayout.NORTH);new DropTarget(this.jTextField1,DnDConstants.ACTION_COPY_OR_MOVE,this);}
11. استخدم واجهة المعالجات|التنفيذات لجعل فئة MainFrame تنفذ واجهة DropTargetListener.
12. قم بتنفيذ طريقة drop() الموروثة من واجهة DropTargetListener لمعالجة البيانات التي تم تمريرها، والرمز المحدد هو كما يلي:
إسقاط الفراغ العام (DropTargetDropEvent dtde) {// رمي java.lang.UnsupportedOperationException الجديد ("Method drop () لم يتم تنفيذه بعد.")؛try{Transferable tr = dtde.getTransferable();if (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)){dtde.acceptDrop(dtde.getDropAction());String s = (String) tr.getTransferData(DataFlavor.stringFlavor);this.jTextField1.setText(this.jTextField1.getText()+s);dtde.dropComplete(true);}else{dtde.rejectDrop();}}catch(Exception err){ err.printStackTrace();}}