[疯狂Java]AWT:拖放功能、拖放目标

1. 拖放操作:

    1) 是GUI界面提供的一种基本功能,即将一个GUI目标(一个图标、一段选中的文字等)通过鼠标拖动到另一个地方并释放来完成某种操作;

    2) 最常见的就是利用拖放来完成复制、剪切的工作,而通过将一个文件的图标拖动到一个程序的图标来打开该文件也是一种常见的拖放操作;

    3) 通过拖放操作实施的复制、剪切通常称为复制、移动(例如把一个文件拖到另一个文件夹中可以完成复制或移动);

    4) 拖放和剪切板的区别:拖放无需剪切板这样的中间缓冲区,而是直接从拖放源将数据传输到拖放目标上;

    5) 组合键:拿移动文件为例

         i. Ctrl:复制移动;

         ii. Shift:剪切移动;

         iii. Ctrl+Shift:创建快捷方式;

    6) 拖放操作中被传递的数据也必须用Transferable包装,并且也要使用DataFlavor标记数据格式;

    7) 拖放操作中最重要的两个对象就是拖放源和拖放目标,分别由DragSource和DropTraget两个类代表;


2. 拖放目标:

    1) 是拖放的目的地,有DropTarget类代表;

    2) 首先是创建拖放目标,构造器:DropTarget(Component c, int ops, DropTargetListener dtl);

         i. c表示要将组件c作为拖放目标;

         ii. ops表示该拖放目标可以接受的拖放操作,是由DnDConstants类定义的静态常量,该类的全称是Drag and Drop Opreation Constants,即和拖放有关的操作的常量,ops共有5中,对应前面讲过的组合键功能:

ACTION_NONE:无操作

ACTION_COPY:复制移动

ACTION_MOVE:剪切移动

ACTION_COPY_OR_MOVE:复制或剪切移动

ACTION_LINK:建立快捷方式

         iii. dtl是拖放目标监听器,监听并响应再拖放目标上发生的拖放事件

    3) 拖放目标上的拖放事件监听器:AWT提供的是DropTargetListener接口和DropTargetAdapter适配器,里面共有5个事件处理器,传进来的参数都是DropTargetDropEvent dtde

         i. dragEnter:光标进入拖放目标时触发;

         ii. dragExit:光标移出拖放目标是触发;

         iii. dragOver:光标在拖放目标上移动时触发;

         iv. drop:光标在拖放目标上释放鼠标键时触发;

         v. dropActionChanged:在拖放目标上改变了操作,比如放开了Ctrl,或者临时加上了Shift等时触发;


3. 示例:可以将多个图片文件拖入程序中并显示,为每个图片建立一个小的内部窗口进行显示

public class AwtTest {
	private JFrame jf = new JFrame("Drop Images Test");
	
	// 桌面面板
	final int DESKTOP_WIDTH = 480;
	final int DESKTOP_HEIGHT = 360;
	private JDesktopPane desktop = new JDesktopPane();
	
	// 内部小窗口,每个内部窗口用来显示一张拖动进来的图片(每张图片建立一个内部小窗口)
	// 每个窗口初始时按照斜对角线的方向排列
	private int nextFrameX = 0; // 下一个内部窗口的位置
	private int nextFrameY = 0;
	private int FRAME_DIFF = 30; // 斜向位移距离
	private int width = DESKTOP_WIDTH / 2;
	private int height = DESKTOP_HEIGHT / 2;
	
	public void init() {
		jf.add(desktop);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		desktop.setPreferredSize(new Dimension(DESKTOP_WIDTH, DESKTOP_HEIGHT));
		
		// 将框架作为拖放目标
		new DropTarget(jf, new DropTargetAdapter() {

			@Override
			public void drop(DropTargetDropEvent dtde) {
				// TODO Auto-generated method stub
				dtde.acceptDrop(DnDConstants.ACTION_COPY); // 表示接受复制移动的操作
				
				try {
					Transferable data = dtde.getTransferable(); // 获取传输的数据
					DataFlavor[] flavors = data.getTransferDataFlavors(); // 获取数据支持的格式
					for (DataFlavor fla: flavors) {
						if (fla.equals(DataFlavor.javaFileListFlavor)) {
							// 如果当前数据支持的格式是文件列表(可以是一个文件也可是多个文件)
							// 就意味着有可能拖进来的是若干图片(也可能不是)
							// 甚至可能连文件列表都不是(拖建立的可能都不是一个文件而是一段文本)
							// 因为这里检查的仅仅是数据支持哪些格式而已
							List fileList = (List)data.getTransferData(fla);
							// 正因为真实的数据格式可能不是文件列表,因此冒昧的获取可能会产生异常!
						
							for (Object f: fileList) {
								showImage((File)f, dtde);
							}
						}
					}
				}
				catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		});
		
		jf.pack();
		jf.setVisible(true);
	}
	
	private void showImage(File f, DropTargetDropEvent dtde) throws IOException {
		Image img = ImageIO.read(f);
		if (img == null) { // 如果读取的文件不是图像格式的会返回null
			dtde.dropComplete(true); // 此时要结束拖放操作并弹出消息框警告
			JOptionPane.showInternalMessageDialog(desktop, "File type unsupported!");
			return ;
		}
		
		ImageIcon icon = new ImageIcon(img);
		JLabel imgLabel = new JLabel(icon); // 将图像变成icon后包装进静态标签中
		JInternalFrame iframe = new JInternalFrame(f.getName(), true, true, true, true);
		iframe.add(new JScrollPane(imgLabel)); // 将图像标签用滚条窗口包装后封装进内部框架窗口中
		
		desktop.add(iframe); // 一定要先添加到桌面面板中再调整内部窗口的位置
		iframe.reshape(nextFrameX, nextFrameY, width, height); // 否则不知道坐标是以哪个为参考的
		iframe.show(); // 显示内部窗口
		
		nextFrameX += FRAME_DIFF;
		nextFrameY += FRAME_DIFF;
		
		// 到头了要另起
		if (nextFrameX + width > desktop.getWidth()) {
			nextFrameX = 0;
		}
		if (nextFrameY + height > desktop.getHeight()) {
			nextFrameY = 0;
		}
	}
	
	public static void main(String[] args)
	{
		new AwtTest().init();
	}

}
!Swing的代码先不管,就来看一下程序中用到的DropTargetDropEvent的三个方法:

    a. public void acceptDrop(int dropAction); // 可以接受那种DnDConstants代表的操作,表示不会屏蔽指定的组合键

    b. public Transferable getTransferable(); // 得到传输的数据,传输的数据是保存在拖放目标事件中的!!!

    c. public void dropComplete(boolean success); // 通知拖放源本次拖放操作已经完成,true表示完成,false表示未完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值