常用鏈接

          統(tǒng)計

          最新評論

          Java中的Drag and Drop詳解與代碼示例 (轉)

          通過兩種方法實現(xiàn)Drag and Drop:
           1.比較初級的D&D:只利用java.awt.datatransfer.*中的類實現(xiàn).
           2.高級D&D: 利用javax.awt.dnd.*中的類實現(xiàn).

          比較初級D&D:只利用java.awt.datatransfer.*中的類實現(xiàn).
           這種方法只支持對JComponent的拖拽.
           Drag and Drop的問題簡單的說要涉及到兩個部分: Drag Source, Drop target和Transferable 即從哪里drag來的, 以及drop到哪里去, 以及傳輸?shù)臄?shù)據(jù).
           
           Drag Source可以分為兩種:
           1.第一種是這樣的JComponent, 他們有dragEnabled屬性.這些JComponent包括:
          javax.swing.JColorChooser
          javax.swing.JFileChooser
          javax.swing.JList
          javax.swing.JTable
          javax.swing.JTree
          javax.swing.text.JTextComponent
           這些JComponent要想作為一個Drag Source只要調用setDragEnabled( true)即可, 不用多余的操作.
           2. 另一種Drag Source沒有dragEnabled屬性, 也就沒有setDragEnabled方法, 要想作為Drag Source, 那就要給Component添加MouseMotionListener, 并實現(xiàn)mouseDragged方法, 后面會舉例介紹.
           
           Drop Target, 任何JComponent都可以作為Drop Target, 但是也只有JComponent以及它的子類可以作為Drop Target, 其它的不行.
           
           Transferable
           所有的Transferable都是javax.swing.Transferable的子類, 但是細分還是可以分為兩種情況:
           第一種是利用javax.swing.Transferable, 因為javax.swing.Transferable 是一個具體類我們可以直接調用new TransferHandler( String property )生成的transfer handler 作為Component的Transfer Handler, 這樣的transfer handler可以將 Java Bean 屬性從一個組件傳輸?shù)搅硪粋€組件的傳輸處理程序。
           第二種則是自定義一個TransferHandler的子類, 你可以在這個類中實現(xiàn)復雜的拖拽操作.
          下面有兩個例子.
          第一個例子用簡單的javax.swing.Transferable, 第二個例子定義一個javax.swing.Transferable的子類.
          例一

          import java.awt.*;
          import java.awt.event.*;
          import javax.swing.*;
          import javax.swing.event.*;

          public class LabelDnd  {
              
          private JFrame mainFrame;
              
          private JPanel mainPanel;
              
          private JLabel label;
              
          private JTextField textField;
              
          private JColorChooser colorChooser;
              
              
          private JMenuBar menuBar = new JMenuBar();
              
          private JMenu  menu = new JMenu( "Menu" );
              
          private JMenuItem menuItem = new JMenuItem( "Handle Foregound" );
              
          private TransferHandler t1 = new TransferHandler( "text" ) ;
              
          private TransferHandler t2 = new TransferHandler( "foreground" );
              
          public LabelDnd() {
                  mainFrame 
          = new JFrame();
                  mainPanel 
          = new JPanel( new BorderLayout() );
                  label 
          = new JLabel( "label" );
                  label.setTransferHandler( t1 );
                  
                  menuItem.addActionListener( 
          new ActionListener() {
                      
          public void actionPerformed( ActionEvent e ) {
                          
          if( label.getTransferHandler().equals( t1 ) ) {
                              LabelDnd.
          this.menuItem.setText( "Handle Text" );
                              label.setTransferHandler( t2 );
                          }
           else {
                              LabelDnd.
          this.menuItem.setText( "Handle Foreground" );
                              label.setTransferHandler( t1 );
                          }

                      }

                  }
          );
                  menu.add( menuItem );
                  menu.setTransferHandler( t1 );
                  menuBar.add( menu );
                  mainFrame.setJMenuBar( menuBar );
                  label.addMouseListener( 
          new MouseAdapter() {
                      
          public void mousePressed( MouseEvent e ) {
                          JComponent c 
          = (JComponent)e.getSource();
                          TransferHandler handler 
          = c.getTransferHandler();
                          handler.exportAsDrag( c, e, TransferHandler.COPY );
                      }

                  }
          );
                  textField 
          = new JTextField( 20 );
                  textField.setDragEnabled( 
          true );
                  colorChooser 
          = new JColorChooser();
                  colorChooser.setDragEnabled( 
          true );
                  mainPanel.add( label, BorderLayout.PAGE_START );
                  mainPanel.add( textField, BorderLayout.PAGE_END );
                  mainPanel.add( colorChooser, BorderLayout.WEST );
                  mainFrame.getContentPane().add( mainPanel );
                  mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                  mainFrame.pack();
                  mainFrame.setLocationRelativeTo( 
          null );
                  mainFrame.setVisible( 
          true );
              }

              
          public static void main( String[] args ) {
                  
          new LabelDnd();
              }

          }


          效果如下:

          你可以試著拖拽下。

          例二
          PictureDnd.java

          package dt;
          import java.awt.*;
          import javax.swing.*;
          import java.awt.event.*;
          import javax.swing.event.*;

          import demo.gui.PictureComponent;

          import java.awt.datatransfer.*;
          import java.io.*;

          public class PictureDnd {
              JFrame mainFrame;
              JPanel mainPanel;
              PictureComponent[] pictures;
              
              
          public static void main( String[]  args ) {
                  
          new PictureDnd();
              }

              
          public PictureDnd() {
                  mainFrame 
          = new JFrame();
                  mainPanel 
          = new JPanel( new GridLayout( 22 ) );
                  pictures 
          =  new PictureComponent[ 4 ];
                  pictures[ 
          0 ] = new PictureComponent( new ImageIcon( "Sunset.jpg" ).getImage() );
                  pictures[ 
          1 ] = new PictureComponent( new ImageIcon( "Winter.jpg" ).getImage() );
                  pictures[ 
          2 ] = new PictureComponent( null );
                  pictures[ 
          3 ] = new PictureComponent( null );
                  
                  mainPanel.add( pictures[ 
          0 ] );
                  mainPanel.add( pictures[ 
          1 ] );
                  mainPanel.add( pictures[ 
          2 ] );
                  mainPanel.add( pictures[ 
          3 ] );
                  
                  mainPanel.setBorder( BorderFactory.createEmptyBorder( 
          20202020 ) );
                  mainFrame.getContentPane().add( mainPanel );
                  mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                  mainFrame.setSize( 
          350400 );
                  mainFrame.setLocationRelativeTo( 
          null );
                  mainFrame.setVisible( 
          true );
              }

          }

          PicrureComponent.java

          package demo.gui;
          import java.awt.Color;
          import java.awt.Dimension;
          import java.awt.Graphics;
          import java.awt.Image;
          import java.awt.event.FocusEvent;
          import java.awt.event.FocusListener;
          import java.awt.event.MouseEvent;
          import java.awt.event.MouseListener;
          import java.util.HashSet;

          import javax.swing.JComponent;

          public class PictureComponent extends JComponent 
          implements FocusListener, MouseListener {
              Image image;
              HashSet
          < PictureComponent > pcs = new HashSet< PictureComponent >();
              
          public PictureComponent( Image image ) {
                  
          this.image = image;
                  setPreferredSize( 
          new Dimension(125125 ) );
                  setFocusable( 
          true );
                  setTransferHandler( 
          new PictureTransferHandler() );
                  addFocusListener( 
          this );
                  addMouseListener( 
          this );
              }

              
          public HashSet< PictureComponent > getPcs() {
                  
          return this.pcs;
              }

              
          public void setPcs( HashSet< PictureComponent > pcs ) {
                  
          this.pcs = pcs;
              }

              
          public Image getImage() {
                  
          return this.image;
              }

              
              
          public void setImage( Image image ){
                  
          this.image = image;
                  repaint();
              }

              
          public void paintComponent( Graphics graphics ){
                  Graphics g 
          = graphics.create();
                  g.setColor( Color.white );
                  g.fillRect( 
          00,  125,125 );
                  
          if( image != null ) {
                      g.drawImage( image, 
          00125125, Color.BLACK, this );
                  }

                  
          if( isFocusOwner() ) {
                      g.setColor( Color.red );
                  }

                  
          else {
                      g.setColor( Color.black );
                  }

                  g.drawRect( 
          00125125 );
                  g.dispose();
              }

              
          public void focusGained( FocusEvent e ) {
                  repaint();
              }

              
          public void focusLost( FocusEvent e ) {
                  repaint();
              }

              
          public void mouseClicked( MouseEvent e ) {
                  requestFocusInWindow();
              }

              
          public void mouseEntered( MouseEvent e ) {}
              
          public void mousePressed( MouseEvent e ) {}
              
          public void mouseExited( MouseEvent e ) {}
              
          public void mouseReleased( MouseEvent e ) {}
          }

          TransferablePicture:

          package demo.gui;
          import java.awt.Image;
          import java.awt.datatransfer.DataFlavor;
          import java.awt.datatransfer.Transferable;

          /* Transferalbe */
          public class TransferablePicture implements Transferable {
              DataFlavor[] flavors 
          = { DataFlavor.imageFlavor };
              Image image;
              
          public TransferablePicture( Image image ) {
                  
          this.image = image;
              }

              
          public DataFlavor[] getTransferDataFlavors() {
                  
          return flavors;
              }

              
          public Object getTransferData( DataFlavor flavor ) {
                  
          if( flavor.equals( DataFlavor.imageFlavor ) ) {
                      
          return image;
                  }

                  
          return null;
              }

              
          public boolean isDataFlavorSupported( DataFlavor flavor ) {
                  
          return flavor.equals( DataFlavor.imageFlavor );
              }

          }

          PictureTransferHandler.java

          package demo.gui;
          import java.awt.Image;
          import java.awt.datatransfer.DataFlavor;
          import java.awt.datatransfer.Transferable;
          import java.awt.datatransfer.UnsupportedFlavorException;
          import java.io.IOException;

          import javax.swing.Icon;
          import javax.swing.ImageIcon;
          import javax.swing.JComponent;
          import javax.swing.TransferHandler;

          import dt.TransferablePicture;

          /* Transfer Handler */
          class PictureTransferHandler extends TransferHandler {
              
          public Transferable createTransferable( JComponent c ) {
                  PictureComponent pc 
          = (PictureComponent)c;
                  
          return new TransferablePicture( pc.getImage() );
              }

              
          public boolean canImport( JComponent c, DataFlavor[] flavors ) {
                  
          for( DataFlavor flavor : flavors ) {
                      
          if( flavor.equals( DataFlavor.imageFlavor ) ) {
                          
          return true;
                      }

                  }

                  
          return false;
              }

              
          public boolean importData( JComponent c, Transferable t ) {
                  
          if( canImport(c, t.getTransferDataFlavors() ) ) {
                      PictureComponent pc 
          = ( PictureComponent )c;
                      
          try {
                          Image image 
          = (Image)t.getTransferData( DataFlavor.imageFlavor );
                          pc.setImage( image );
                          System.out.println( 
          "它能接受" );
                          
          return true;
                      }
           catch( UnsupportedFlavorException e ) {
                          e.printStackTrace();
                      }
           catch( IOException e ) {
                          e.printStackTrace();
                      }

                  }

                  System.out.println( 
          "它不能接受" );
                  
          return false;
              }

              
          public void exportDone( JComponent c, Transferable data, int  action ) {
                  PictureComponent picture 
          = ( PictureComponent )c;
                  
          if( action == MOVE ) {
                      picture.setImage( 
          null );
                  }

              }

              
          public int getSourceActions( JComponent c ){
                  
          return COPY_OR_MOVE;
              }

              
          public Icon getVisualRepresentation( Transferable t ) {
                  Image image 
          = null;
                  
          try {
                      System.out.println( 
          "getVisualRepresentation" );
                      image 
          = (Image)t.getTransferData( DataFlavor.imageFlavor );
                      
                  }
           catch( Exception e ) {
                      e.printStackTrace();
                  }

                  
          return new ImageIcon( image );
              }

          }


          效果如下:

          2.高級D&D:利用javax.awt.dnd.*中的類實現(xiàn).
           第二種實現(xiàn)方法和第一種的區(qū)別主要是在Drag Source和Drop Target上.而且這第二種實現(xiàn)方法支持所有Component及其子類上實現(xiàn)拖拽,而不止是JComponent.
           
          Drag Target   一個對象那個如果想作為拖拽源的話,必須和五個對象建立聯(lián)系,這五個對象分別是:    * java.awt.dnd.DragSource    獲取DragSource的方法很簡單,直接調用DragSource.getDefaultDragSource();就可以得到DragSource對象    * java.awt.dnd.DragGestureRecognizer    DragGestureRecognizer類中實現(xiàn)了一些與平臺無關的方法,我們如果想在自己的組件上實現(xiàn)拖拽的話只要調用createDefaultDragGestureRecognizer()方法就可以了    該方法接收三個參數(shù),建立組件和拖拽動作之間的關系    * java.awt.dnd.DragGestureListener    當建立了組件和拖拽動作之間的聯(lián)系后,如果用戶執(zhí)行了拖拽操作,組件將發(fā)送一個消息給DragGestureListener監(jiān)聽器    DragGestureListener監(jiān)聽器接下來會發(fā)送一個startDrag()消息給拖拽源對象,告訴組件應該執(zhí)行拖拽的初始化操作了    拖拽源會產(chǎn)生一個DragSourceContext對象來監(jiān)聽動作的狀態(tài),這個監(jiān)聽過程是通過監(jiān)聽本地方法DragSourceContextPeer來實現(xiàn)的    * java.awt.datatransfer.Transferable    * java.awt.dnd.DragSourceListener     DragSourceListener接口負責當鼠標拖拽對象經(jīng)過組件時的可視化處理, DragSourceListener接口的顯示結果只是暫時改變組件的外觀    同時他提供一個feedback,當用戶的拖拽操作完成之后會收到一個dragDropEnd的消息,我們可以在這個函數(shù)中執(zhí)行相應的操作    再來回顧一下拖拽源的建立過程 1.DragGestureRecognizer 確認一個拖拽操作,同時告知 DragGestureListener. 2.假如actions and/or flavors are OK, DragGestureListener 讓 DragSource 調用 startDrag(). 3.DragSource建立一個 DragSourceContext和一個DragSourceContextPeer.  4.DragSourceContext 把它自己作為一個DragSourceListener,偵聽DragSourceContextPeer.DragSourceContextPeer會從本地系統(tǒng)得到Coponent的狀態(tài)改變的通知(component entered/exited/is over), 并把他們代理給DragSourceContext.5.DragSourceContext通知 DragSourceListener,而DragSourceListener提供 drag over 的反饋(如果DropTargetListener接受這個動作). 典型的反饋包括讓DrogSourceContext改變鼠標.   
          6.一旦drop完畢, DragSourceListener就得到一個dragDropEnd的通知消息.
           Drop Source   創(chuàng)建一個 droppable Component必須和下面兩個對象發(fā)生關聯(lián)       * java.awt.dnd.DropTarget    DropTarget構造函數(shù)使DropTarget 和 DropTargetListener objects發(fā)生關聯(lián)    Droptarget對象提供 setComponent 和addDropTargetListener 兩個方法        * java.awt.dnd.DropTargetListener
              DropTargetListener需要與一個Component聯(lián)系, 以讓DropTargetListener在Component操作的時候能夠顯示”drag under”效果.    
              下面的這個例子以第二種方式實現(xiàn)拖拽:
          DragAndDrop.java

          package dnd;
          import java.awt.*;
          import javax.swing.*;
          import java.awt.dnd.*;
          import java.awt.datatransfer.*;
          import java.io.*;
          import javax.swing.tree.*;

          public class DragAndDrop extends JFrame {
              JScrollPane jScrollPane1 
          = new JScrollPane();
              JTextArea jTextArea1 
          = new JTextArea();
              
              
          public DragAndDrop() {
                  
          this.getContentPane().setLayout( new BorderLayout() );
                  jScrollPane1.getViewport().setBackground( 
          new Color( 10538125 ) );
                  jTextArea1.setBackground( Color.orange );
                  jTextArea1.setToolTipText( 
          "" );
                  JTree jtr 
          = new JTree();
                  jtr.setBackground( Color.BLUE );
                  jScrollPane1.getViewport().add( jtr );
                  
          this.getContentPane().add( jTextArea1, BorderLayout.PAGE_END );
                  
          this.getContentPane().add( jScrollPane1,  BorderLayout.PAGE_START );
                  
                  
          // Drag And Drop Relative.
                  DragSource dragSource = DragSource.getDefaultDragSource();
                  dragSource.createDefaultDragGestureRecognizer( jtr, DnDConstants.ACTION_COPY_OR_MOVE, 
          new DragAndDropDragGestureListener() );
                  DropTarget dropTarget 
          = new DropTarget( jTextArea1, new DragAndDropDropTargetListener() );
                  
              }

              
          public static void main( String[] args ) {
                  DragAndDrop dad 
          = new DragAndDrop();
                  dad.setTitle( 
          "拖拽演示" );
                  dad.setSize( 
          400300 );
                  dad.setVisible( 
          true );
              }

          }

          DragAndDropDragGestureListener.java

           

          package dnd;

          import java.awt.dnd.DragGestureEvent;
          import java.awt.dnd.DragGestureListener;
          import java.awt.dnd.DragSource;

          import javax.swing.JTree;
          import javax.swing.tree.DefaultMutableTreeNode;
          import javax.swing.tree.TreePath;

          /* Drag Gesture Listener */
          public class DragAndDropDragGestureListener implements DragGestureListener {
              
          public void dragGestureRecognized( DragGestureEvent dge ) {
                  JTree tree 
          = (JTree)dge.getComponent();
                  TreePath path 
          = tree.getSelectionPath();
                  
          if( path != null ) {
                      DefaultMutableTreeNode selection 
          = ( DefaultMutableTreeNode )path.getLastPathComponent();
                      DragAndDropTransferable dragAndDropTransferable 
          = new DragAndDropTransferable( selection );
                      dge.startDrag( DragSource.DefaultCopyDrop, dragAndDropTransferable, 
          new DragAndDropDragSourceListener() );
                  }

              }

          }

          DragAndDropDragSourceListener.java

           

          package dnd;

          import java.awt.dnd.DnDConstants;
          import java.awt.dnd.DragSource;
          import java.awt.dnd.DragSourceContext;
          import java.awt.dnd.DragSourceDragEvent;
          import java.awt.dnd.DragSourceDropEvent;
          import java.awt.dnd.DragSourceEvent;
          import java.awt.dnd.DragSourceListener;

          import javax.swing.JTree;
          import javax.swing.tree.DefaultMutableTreeNode;
          import javax.swing.tree.TreePath;

          /* Drag Source Listener */
          public class DragAndDropDragSourceListener implements DragSourceListener {
              
          public void dragDropEnd( DragSourceDropEvent e ) {
                  
          if( e.getDropSuccess() ) {
                      
          int dropAction = e.getDropAction();
                      
          if( dropAction == DnDConstants.ACTION_MOVE ) {
                          
          //System.out.println( "MOVE: remove node" );
                          
                      }

                  }

              }

              
          public void dragEnter( DragSourceDragEvent e ) {
                  DragSourceContext context 
          = e.getDragSourceContext();
                  
          int dropAction = e.getDropAction();
                  
          if( ( dropAction & DnDConstants.ACTION_COPY ) != 0 ) {
                      context.setCursor( DragSource.DefaultCopyDrop );
                  }
           else if( ( dropAction & DnDConstants.ACTION_MOVE ) != 0 ) {
                      context.setCursor( DragSource.DefaultMoveDrop );
                  }
           else {
                      context.setCursor( DragSource.DefaultCopyNoDrop );
                  }

              }

              
          public void dragExit( DragSourceEvent e ) {}
              
          public void dragOver( DragSourceDragEvent e  ){}
              
          public void dropActionChanged( DragSourceDragEvent e ){}
          }

          DragAndDropDropTargetListener.java

           

          package dnd;
          import java.awt.datatransfer.DataFlavor;
          import java.awt.datatransfer.Transferable;
          import java.awt.datatransfer.UnsupportedFlavorException;
          import java.awt.dnd.DropTarget;
          import java.awt.dnd.DropTargetDragEvent;
          import java.awt.dnd.DropTargetDropEvent;
          import java.awt.dnd.DropTargetEvent;
          import java.awt.dnd.DropTargetListener;
          import java.io.IOException;

          import javax.swing.JTextArea;

          /* Drop Target Listener */
          public class DragAndDropDropTargetListener implements DropTargetListener {
              
          public void dragEnter( DropTargetDragEvent e ) {}
              
          public void dragOver( DropTargetDragEvent e ) {}
              
          public void dropActionChanged( DropTargetDragEvent e ) {}
              
          public void dragExit( DropTargetEvent e ) {}
              
          public void drop( DropTargetDropEvent e ) {
                  Transferable t 
          = e.getTransferable();
                  String s 
          = "";
                  
          try {
                      
          if( t.isDataFlavorSupported( DataFlavor.stringFlavor ) ) {
                          s 
          = t.getTransferData( DataFlavor.stringFlavor  ).toString();
                      }

                  }
           catch( IOException ioe ) {
                      ioe.printStackTrace();
                  }
           catch( UnsupportedFlavorException ufe ) {
                      ufe.printStackTrace();
                  }

                  System.out.println( s );
                  DropTarget dt 
          = (DropTarget)e.getSource();
                  JTextArea d 
          = ( JTextArea )dt.getComponent();
                  
          if( s != null && s.equals( "" ) == false ) {
                      d.append( s 
          + " ");
                  }

              }

          }

          DragAndDropTransferable.java

           

          package dnd;

          import java.awt.datatransfer.DataFlavor;
          import java.awt.datatransfer.Transferable;
          import java.awt.datatransfer.UnsupportedFlavorException;
          import java.io.IOException;

          import javax.swing.tree.DefaultMutableTreeNode;

          /* Drop Transferable */
          public class DragAndDropTransferable implements Transferable {
              
          private DefaultMutableTreeNode treeNode;
              
          public DragAndDropTransferable( DefaultMutableTreeNode treeNode ) {
                  
          this.treeNode = treeNode;
              }

              DataFlavor[] flavors 
          = { DataFlavor.stringFlavor };
              
          public DataFlavor[] getTransferDataFlavors() {
                  
          return flavors;
              }

              
          public boolean isDataFlavorSupported( DataFlavor flavor ) {
                  
          for( DataFlavor df : flavors ) {
                      
          if( df.equals( flavor ) ) {
                          
          return true;
                      }

                  }

                  
          return false;
              }

              
          public Object getTransferData( DataFlavor df ) throws UnsupportedFlavorException, IOException {
                  
          return treeNode;
              }

          }


          效果如下:

          posted on 2008-01-10 14:12 九寶 閱讀(870) 評論(0)  編輯  收藏 所屬分類: Java

          主站蜘蛛池模板: 昆山市| 开封县| 济源市| 临汾市| 南召县| 蕲春县| 孟村| 安顺市| 永安市| 铜山县| 桐梓县| 沧源| 巨鹿县| 宝山区| 荥阳市| 保康县| 肇庆市| 南开区| 娱乐| 文化| 仲巴县| 遂平县| 安阳市| 寿光市| 白山市| 五原县| 镇安县| 筠连县| 嵊州市| 静海县| 防城港市| 沅江市| 桦甸市| 安龙县| 象山县| 淮阳县| 昌平区| 东台市| 新丰县| 师宗县| 迭部县|