ตัวอย่างในบทความนี้อธิบายวิธีที่ Java ใช้การลากและวางเมาส์เพื่อแลกเปลี่ยนข้อมูลโปรแกรม ซึ่งเรียกว่าฟังก์ชันการลากและวางเมาส์ ฟังก์ชันลากและวางของเมาส์ใช้กันทั่วไปในระบบกราฟิก Java มีแพ็คเกจ java.awt.dnd และ java.awt.datatransfer เพื่อรองรับฟังก์ชันนี้ ตัวอย่างนี้สาธิตวิธีการลากและวางในโปรแกรม เมื่อคุณคลิกเมาส์บนป้ายกำกับ "Hello World!" ที่ส่วนบนของหน้าต่างแล้วลากไปยังกล่องข้อความในส่วนล่างของหน้าต่าง โลก!" จะถูกเพิ่มลงในกล่องข้อความ !" ข้อความ ดำเนินการต่อตามกระบวนการข้างต้นและข้อความจะถูกเพิ่มต่อไป
แนวคิดการใช้งานเฉพาะและวิธีการของฟังก์ชันโปรแกรมมีดังนี้: ในการใช้งานการลากและวางเมาส์ แนวคิดที่สำคัญที่สุดสองประการคือต้นทางการลากและเป้าหมายการปล่อย ได้แก่ ต้นทางการลากและวางเป้าหมาย แหล่งที่มาของการลากและเป้าหมายการวางนั้นเชื่อมโยงกับองค์ประกอบที่มองเห็นได้ (คุณจะลากได้อย่างไรหากมองไม่เห็น!) สาระสำคัญของเทคโนโลยีการลากและวางคือการถ่ายโอนข้อมูลในองค์ประกอบต้นทางแบบลากแล้วปล่อยไปยังองค์ประกอบเป้าหมายตำแหน่ง ดังนั้นจากมุมมองระดับต่ำ การลากแล้วปล่อยจึงใกล้เคียงกับเทคโนโลยีคลิปบอร์ดมาก ในตัวอย่างข้างต้น
การใช้งาน Drag Source: คลาส Drag Source จะต้องสร้างอินสแตนซ์ DragGestureRecognizer ก่อน โดยระบุว่าคลาสนั้นเป็นคลาสคอมโพเนนต์ของ Drag Source หรือมีส่วนประกอบของ Drag Source ซึ่งสามารถทำได้โดยการเรียกเมธอด createDefaultDragGestureRecognizer() ของออบเจ็กต์ DataSource การใช้งานเฉพาะมีดังนี้:
int action = DnDConstants.ACTION_COPY_OR_MOVE; //ลากและวางประเภท ds.createDefaultDragGestureRecognizer(นี่,การกระทำ,สิ่งนี้);
ข้อความข้างต้นแสดงให้เห็นว่าคอมโพเนนต์แหล่งที่มาของการลากเป็นออบเจ็กต์อินสแตนซ์ของคลาสนี้เอง ประเภทของการลากและวางที่จะเสร็จสมบูรณ์เป็นประเภท DnDConstants.ACTION_COPY_OR_MOVE และคลาสที่ใช้อินเทอร์เฟซ DragGestureListener คือคลาสนี้ โดยทั่วไปแหล่งที่มาของการลากจะใช้อินเทอร์เฟซ DragGestureListener ซึ่งกำหนดวิธีการลาก GestureRecognized() เมื่อการลากเริ่มต้น DragGestureListener จะรับฟังเหตุการณ์ จากนั้นจึงถ่ายโอนไปยังวิธีการลากGestureRecognized() เพื่อประมวลผลเหตุการณ์ เช่น การส่งข้อมูลของการลาก แหล่งที่มา. รหัสเฉพาะ:
โมฆะสาธารณะลากGestureRecognized(DragGestureEvent dge) {//throw new java.lang.UnsupportedOperationException("Method DragGestureRecognized() not allowance."); ลอง{Transferable tr = new StringSelection(this.getText()); //Transfer the label's ข้อความเป็นข้อมูลโดย Transferable บรรจุภัณฑ์ของวัตถุ //เริ่มการลาก ตั้งค่าเคอร์เซอร์เป็นรูป DragSource.DefaultCopyNoDrop ข้อมูลการลากและวางเป็นวัตถุ tr และ DragSourceListener คือคลาสนี้ dge.startDrag(DragSource.DefaultCopyNoDrop,tr,this);}catch(Exception err) {ผิดพลาด printStackTrace();}}
แหล่งที่มาของการลากต้องใช้อินเทอร์เฟซ DragSourceListener ซึ่งกำหนดวิธีการจัดการเหตุการณ์สำหรับแต่ละสถานะที่เกี่ยวข้องกับการลากและวาง เช่น DragEnter, DragOver, DropActionChanged, DragExit และวิธีการอื่นๆ ในตัวอย่างนี้ เมธอด DragEnter() จะถูกนำไปใช้เพื่อตั้งค่ารูปร่างเคอร์เซอร์ระหว่างการลาก และวิธีการอื่นๆ จะเป็นเมธอดว่างเปล่า รหัสการใช้งานเฉพาะมีดังนี้:
โมฆะสาธารณะ DragEnter(DragSourceDragEvent dsde) {//throw new java.lang.UnsupportedOperationException("Method DragEnter() ยังไม่ได้ใช้งาน");DragSourceContext dsc = dsde.getDragSourceContext(); //รับการอ้างอิงบริบทของแหล่งที่มาของการลาก/ / ตั้งค่ารูปร่างเคอร์เซอร์เมื่อลาก int action = dsde.getDropAction();if ((action&DnDConstants.ACTION_COPY)!=0)dsc.setCursor(DragSource.DefaultCopyDrop);elsedsc.setCursor(DragSource.DefaultCopyNoDrop);}
การใช้งาน drop target: ต้องสร้างอินสแตนซ์ DragTarget ก่อนในคลาส drop target เพื่อระบุว่าคลาสนี้เป็นคลาสคอมโพเนนต์ drop target หรือมีคอมโพเนนต์ drop target การใช้งานมีดังนี้:
ใหม่ DropTarget (this.jTextField1, DnDConstants.ACTION_COPY_OR_MOVE นี้);
ข้อความข้างต้นแสดงให้เห็นว่าเป้าหมายการวางคืออ็อบเจ็กต์ this.jTextField1 การดำเนินการลากแล้วปล่อยเป็นประเภท DnDConstants.ACTION_COPY_OR_MOVE และคลาสที่ใช้อินเทอร์เฟซ DropTargetListener คือคลาสนี้ สอดคล้องกับ DrafSourceListener โดยทั่วไปเป้าหมายการวางหรือคลาสจะใช้อินเทอร์เฟซ DropTargetListener อินเทอร์เฟซนี้ยังกำหนดวิธีการต่างๆ มากมาย เช่น DragEnter, DragOver ฯลฯ สำหรับจัดการเหตุการณ์เมื่อกระบวนการลากและวางเข้าสู่ขั้นตอนต่างๆ ตัวอย่างนี้สนใจเฉพาะเมธอด drop() ซึ่งเป็นการประมวลผลเหตุการณ์เมื่อมีการปล่อยเมาส์บนคอมโพเนนต์เป้าหมายตำแหน่ง โดยทั่วไปจะใช้เพื่อประมวลผลข้อมูลที่ส่งผ่าน ตัวอย่างเช่น ในตัวอย่างนี้ ข้อมูลข้อความที่ส่งจะเป็น ที่แสดงอยู่บนส่วนประกอบ JTextField อื่นๆ วิธีการนี้เป็นวิธีการว่าง รหัสเฉพาะมีดังนี้:
public void drop(DropTargetDropEvent dtde) {//throw new java.lang.UnsupportedOperationException("Method drop() ยังไม่ได้ใช้");ลอง{Transferable tr = dtde.getTransferable(); //รับวัตถุข้อมูลที่ส่งผ่าน/ / ประมวลผลวัตถุข้อมูลและรับข้อมูลข้อความหาก (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)){dtde.acceptDrop(dtde.getDropAction());String s = (สตริง) tr.getTransferData(DataFlavor.stringFlavor);this.jTextField1.setText(this.jTextField1.getText() +ส); //แสดงข้อมูลข้อความที่ส่งมาจากแหล่งการลากบนเป้าหมายการวาง dtde.dropComplete(true);}else{dtde.rejectDrop();}}catch(Exception err){err.printStackTrace();}}
รหัสโปรแกรม:
1. สร้างโปรเจ็กต์ใหม่และตั้งชื่อเป็น JDragAndDropDemo
2. สร้าง Application ใหม่และตั้งชื่อเป็น 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
DragJLabel สาธารณะ (ชื่อสตริง, การจัดตำแหน่ง int) {super (ชื่อ, การจัดตำแหน่ง); // ใช้วิธีคลาสพาเรนต์ int action = DnDConstants.ACTION_COPY_OR_MOVE; ds.createDefaultDragGestureRecognizer (นี่, การกระทำ, นี้);
7. ใช้เมธอด DragGestureRecognized() ในคลาส DragJLabel ตัดและส่งข้อมูล
โมฆะสาธารณะลากGestureRecognized(DragGestureEvent dge) {//โยน new java.lang.UnsupportedOperationException("Method DragGestureRecognized() not allowance.");ลอง{Transferable tr = new StringSelection(this.getText());dge.startDrag(DragSource .DefaultCopyNoDrop,tr,this);}catch(Exception ผิดพลาด){err.printStackTrace();}}
8. ใช้เมธอด DragEnter() ในคลาส DragJLabel เพื่อกำหนดรูปร่างของเคอร์เซอร์
โมฆะสาธารณะลากEnter(DragSourceDragEvent dsde) {//โยนใหม่ java.lang.UnsupportedOperationException("Method 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("[Your Icon]")));contentPane = (JPanel) this.getContentPane();contentPane.setLayout (borderLayout1);this.setSize(มิติใหม่ (410, 114));this.setTitle("JDragAndDropDemo");jTextField1.setFont(new java.awt.Font("Dialog", 0, 14));contentPane.add(jTextField1, BorderLayout.SOUTH);contentPane.add(สิ่งนี้ .label,BorderLayout.NORTH);ใหม่ DropTarget(this.jTextField1,DnDConstants.ACTION_COPY_OR_MOVE,นี้);}
11. ใช้ตัวช่วยสร้าง|ใช้อินเทอร์เฟซเพื่อทำให้คลาส MainFrame ใช้อินเทอร์เฟซ DropTargetListener
12. ใช้เมธอด drop() ที่สืบทอดมาจากอินเทอร์เฟซ DropTargetListener เพื่อประมวลผลข้อมูลที่ส่งผ่าน รหัสเฉพาะมีดังนี้:
โมฆะสาธารณะลดลง (DropTargetDropEvent dtde) {// โยน java.lang.UnsupportedOperationException ใหม่ ("Method drop() ยังไม่ได้ใช้งาน"); ลอง {Transferable tr = dtde.getTransferable (); ถ้า (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)){dtde.acceptDrop(dtde.getDropAction());สตริง s = (สตริง) tr.getTransferData(DataFlavor.stringFlavor);this.jTextField1.setText(this.jTextField1.getText()+s);dtde.dropComplete(true);}else{dtde.rejectDrop();}}catch(ข้อผิดพลาดข้อยกเว้น){ ผิดพลาด.printStackTrace();}}