Swing-实现拖拽支持
程序员文章站
2022-06-17 10:22:26
...
目录
一、创建拖拽源
DragSource : 拖放操作的源窗口
DropTarget : 拖放操作的目标窗口
Transferable : 传递物,传递的数据
创建拖放源,仅窗口支持拖放操作
1、创建DragSource
2、创建Transferable
3、开始拖拽操作startDrag
核心代码:
拖放源-用来提供数据
package my;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MyFrame extends JFrame
{
public MyFrame(String title)
{
super(title);
JPanel root = new JPanel();
this.setContentPane(root);
root.setLayout(new FlowLayout());
JLabel label = new JLabel("久森呀");
label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
label.setOpaque(true);
label.setBackground(Color.CYAN);
root.add(label);
//创建拖放源
DragSource dragSource = DragSource.getDefaultDragSource();
//第一个参数:源窗口
//第二个参数:允许的操作类型ACTION_COPY / ACTION_MOVE
//第三个参数:监听器
dragSource.createDefaultDragGestureRecognizer
(label, DnDConstants.ACTION_COPY, new MyDragGestureListener());
}
private class MyDragGestureListener implements DragGestureListener
{
@Override
public void dragGestureRecognized(DragGestureEvent dge)
{
//定义要拖放的数据,StringSelection表示文本数据
Transferable transfer = new StringSelection("haha.......");
dge.startDrag(DragSource.DefaultCopyDrop, transfer);
}
}
}
二、创建拖放目标
1、创建DropTarget
2、实现DropTargetListener
3、实现Transferable
核心代码:
package my;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
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 javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MyFrame extends JFrame
{
public MyFrame(String title)
{
super(title);
JPanel root = new JPanel();
this.setContentPane(root);
//创建拖放目标(目标窗口要大一点,因此把root设为目标窗口)
DropTarget dropTarget = new DropTarget(root,new MyDropTargetListener());
}
//dragEnter : 拖拽物进入
//dragExit : 拖拽物离开
//dragOver : 拖拽物进行中
//drop : 拖拽物被丢进来
private class MyDropTargetListener implements DropTargetListener
{
@Override
public void dragEnter(DropTargetDragEvent dtde)
{
//检测拖放进来的数据类型
//如果没有想要的类型,
Transferable transfer = dtde.getTransferable();
DataFlavor[] flavors = transfer.getTransferDataFlavors();
for(DataFlavor flav : flavors)
{
String mimeType = flav.getMimeType();
System.out.println("mimeType:"+mimeType);
}
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dragExit(DropTargetEvent dte) {
// TODO Auto-generated method stub
}
@Override
public void drop(DropTargetDropEvent dtde) {
// TODO Auto-generated method stub
}
}
}
三、处理拖拽数据
意思就是处理你所拖拽的信息,分类...
1、DataFlavor : 数据类型
一般也称为MIME Type
2、一次可以拖拽多组数据
3、此操作时将字符串拖拽到面板上
package my;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
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.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MyFrame extends JFrame
{
JLabel label = new JLabel();
public MyFrame(String title)
{
super(title);
JPanel root = new JPanel();
this.setContentPane(root);
root.add(label);
label.setFont(new Font("宋体",Font.PLAIN,24));
//创建拖放目标(目标窗口要大一点,因此把root设为目标窗口)
DropTarget dropTarget = new DropTarget(root,new MyDropTargetListener());
}
//dragEnter : 拖拽物进入
//dragExit : 拖拽物离开
//dragOver : 拖拽物进行中
//drop : 拖拽物被丢进来
private class MyDropTargetListener implements DropTargetListener
{
private DataFlavor check(Transferable transfer)
{
//检测拖放进来的数据类型
//如果没有想要的类型,
DataFlavor[] flavors = transfer.getTransferDataFlavors();
for(DataFlavor flav : flavors)
{
String mimeType = flav.getMimeType();
System.out.println("mimeType:"+mimeType);
if(mimeType.startsWith("text/plain; class=java.lang.String;"))
{
return flav;
}
}
return null;
}
@Override
public void dragEnter(DropTargetDragEvent dtde)
{
//检测拖放进来的数据类型
Transferable transfer = dtde.getTransferable();
DataFlavor flav = check(transfer);
if(flav==null)
{
dtde.rejectDrag(); //没有需要的类型,拒绝进入
}
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dragExit(DropTargetEvent dte) {
// TODO Auto-generated method stub
}
@Override
public void drop(DropTargetDropEvent dtde)
{
//检测拖放进来的数据类型
Transferable transfer = dtde.getTransferable();
DataFlavor flav = check(transfer);
if(flav!=null)
{
//必须先调用acceptDrop
dtde.acceptDrop(DnDConstants.ACTION_COPY);
//
String text;
try
{
text = (String) transfer.getTransferData(flav);
label.setText(text);
} catch (UnsupportedFlavorException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
四、图片的拖拽
1、把一张图片文件拖拽到窗口并且显示图片
2、文件File只是一个路径信息,图片的话比较大
3、本程序只能拖动一个图片
总代码:
为了效果还有设计的短消息错误提示 和 图片显示形式,就不上传了,需要的话来互相学习
package my;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
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.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import js.swing.JsToaster;
import js.swing.image.JsImageView;
public class MyFrame extends JFrame
{
JsImageView imageView = new JsImageView();
public MyFrame(String title)
{
super(title);
JPanel root = new JPanel();
this.setContentPane(root);
this.setLayout(new BorderLayout());
this.add(imageView, BorderLayout.CENTER);
imageView.setScaleType(JsImageView.FIT_CENTER_INSIDE);
//创建拖放目标(目标窗口要大一点,因此把root设为目标窗口)
DropTarget dropTarget = new DropTarget(root,new MyDropTargetListener());
}
//fileName : 不包含路径的文件名
//返回文件名里的后缀名,不带点号
public String getFileSuffix(String fileName)
{
int p = fileName.lastIndexOf(".");
if(p>=0)
return fileName.substring(p+1);
return "";
}
public void loadImageFile(File file)
{
// 获取文件的后缀名,并统一转成小写,以方便比较
String suffix = getFileSuffix( file.getName()).toLowerCase();
// 检查后缀
if(! suffix.equals("jpg") && !suffix.equals("jpeg") && !suffix.equals("png"))
{
JsToaster.show(this, JsToaster.ERROR, "不支持的文件格式:" + suffix);
return;
}
//加载文件并显示
try {
Image image = ImageIO.read(file);
imageView.setImage(image);
}catch(Exception e)
{
e.printStackTrace();
JsToaster.show(this, JsToaster.ERROR, e.getMessage());
}
}
//dragEnter : 拖拽物进入
//dragExit : 拖拽物离开
//dragOver : 拖拽物进行中
//drop : 拖拽物被丢进来
private class MyDropTargetListener implements DropTargetListener
{
// 拖放文件进来时,MIME类型: application/x-java-file-list; class=java.util.List
private DataFlavor check(Transferable transfer)
{
// 或者写成 flav = new DataFlavor("application/x-java-file-list; class=java.util.List")
DataFlavor flav = DataFlavor.javaFileListFlavor;
if(transfer.isDataFlavorSupported(flav))
{
return flav;
}
return null;
}
@Override
public void dragEnter(DropTargetDragEvent dtde)
{
//检测拖放进来的数据类型
Transferable transfer = dtde.getTransferable();
DataFlavor flav = check(transfer);
if(flav==null)
{
dtde.rejectDrag(); //没有需要的类型,拒绝进入
}
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
// TODO Auto-generated method stub
}
@Override
public void dragExit(DropTargetEvent dte) {
// TODO Auto-generated method stub
}
@Override
public void drop(DropTargetDropEvent dtde)
{
//检测拖放进来的数据类型
Transferable transfer = dtde.getTransferable();
DataFlavor flav = check(transfer);
if(flav!=null)
{
//必须先调用acceptDrop
dtde.acceptDrop(DnDConstants.ACTION_COPY);
//
String text;
try
{
// 调用 getTransferData() 来取得数据
List<File> files = (List)transfer.getTransferData(flav);
loadImageFile(files.get(0));
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
package my;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Swing2
{
private static void createGUI()
{
// JFrame指一个窗口,构造方法的参数为窗口标题
// 语法:因为MyFrame是JFrame的子类,所以可以这么写
JFrame frame = new MyFrame("Js拖拽");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口的其他参数,如窗口大小
frame.setSize(600, 500);
//显示位置
frame.setLocationRelativeTo(null);
// 显示窗口
frame.setVisible(true);
}
public static void main(String[] args)
{
//设置界面样式 Look And Feel
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e)
{
e.printStackTrace();
}
// 此段代码间接地调用了 createGUI()
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run()
{
createGUI();
}
});
}
}
上一篇: Java运算符以及流程控制语句