Java拖放JFrame上特定扩展名的文件 [英] Java Drag-n-Drop files of specific extension on JFrame

查看:186
本文介绍了Java拖放JFrame上特定扩展名的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的应用程序实现DnD,只接受某些扩展名的文件(例如wrl)。如果文件被接受,我想将光标更改为拖动光标,当拖放错误扩展名的文件时,将其恢复为普通光标。

I would like to implement DnD for my application to accept only files of certain extension (eg. wrl). I would like to change the cursor to a drag cursor if the file will be accepted and revert back to normal cursor when the file of wrong extension is drag and dropped.

I以下教程/示例来自 http://docs.oracle。 com / javase / tutorial / uiswing / dnd / toplevel.html

I have been following the following tutorial/example from http://docs.oracle.com/javase/tutorial/uiswing/dnd/toplevel.html

我所做的更改是在canImport函数中

The change that I make is in the canImport function

    public boolean canImport(TransferHandler.TransferSupport support) 
    {
        if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) 
        {
            return false;
        }

        Transferable t = support.getTransferable();

        try 
        {
          java.util.List<File> l = (java.util.List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
          if (l.size() != 1)
          {
            return false;
          }

          File f = l.get(0);

          String extension = f.getName().substring(f.getName().lastIndexOf("."));

          return extension.equalsIgnoreCase(".wrl");
        } 

        catch (UnsupportedFlavorException e) 
        {
            return false;
        } 
        catch (IOException e) 
        {
            return false;
        }
    }

当我在不同的文件中拖动时,这个行为正确。但是,当我删除文件时,我得到以下例外:

This behaves correctly when I drag over in different files. However, when I drop the file, I get the following exception

Exception in thread "AWT-EventQueue-0" java.awt.dnd.InvalidDnDOperationException: No drop current
    at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:227)
    at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:56)
    at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:359)
    at appl.TopLevelTransferHandlerDemo$1.canImport(TopLevelTransferHandlerDemo.java:207)
    at javax.swing.TransferHandler$DropHandler.drop(TransferHandler.java:1454)
    at java.awt.dnd.DropTarget.drop(DropTarget.java:434)
    at javax.swing.TransferHandler$SwingDropTarget.drop(TransferHandler.java:1193)
    at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:519)
    at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:832)
    at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:756)
    at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:30)
    at java.awt.Component.dispatchEventImpl(Component.java:4487)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
    at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4312)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4163)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

任何帮助非常感谢

推荐答案

最后一次我检查,这在Mac上没有工作,但是可能已经改变了Java 7 ...

The last time I checked, this didn't work on Mac's, but that might have changed with Java 7...

现在,请记住,当拖曳拖放时,没有任何简单的答案可以做所有事情。

Now, remember, when it comes to drag'n'drop, there is no easy answer that will do everything.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
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.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDragNDrop {

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

    public TestDragNDrop() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel implements DropTargetListener {

        public enum DragState {

            Waiting,
            Accept,
            Reject
        }
        private DragState state = DragState.Waiting;
        private BufferedImage happy;
        private BufferedImage wait;
        private BufferedImage sad;

        public TestPane() {
            DropTarget dt = new DropTarget(
                    this,
                    DnDConstants.ACTION_COPY_OR_MOVE,
                    this,
                    true);

            setBackground(Color.BLACK);
            try {
                happy = ImageIO.read(getClass().getResource("/Happy.png"));
                wait = ImageIO.read(getClass().getResource("/Wait.png"));
                sad = ImageIO.read(getClass().getResource("/Sad.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            BufferedImage bg = null;
            switch (state) {
                case Waiting:
                    bg = wait;
                    break;
                case Accept:
                    bg = happy;
                    break;
                case Reject:
                    bg = sad;
                    break;
            }
            if (bg != null) {
                int x = (getWidth() - bg.getWidth()) / 2;
                int y = (getHeight() - bg.getHeight()) / 2;
                g.drawImage(bg, x, y, this);
            }
        }

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {
            state = DragState.Reject;
            Transferable t = dtde.getTransferable();
            if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                try {
                    Object td = t.getTransferData(DataFlavor.javaFileListFlavor);
                    if (td instanceof List) {
                        state = DragState.Accept;
                        for (Object value : ((List) td)) {
                            if (value instanceof File) {
                                File file = (File) value;
                                String name = file.getName().toLowerCase();
                                if (!name.endsWith(".png")) {
                                    state = DragState.Reject;
                                    break;
                                }
                            }
                        }
                    }
                } catch (UnsupportedFlavorException | IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (state == DragState.Accept) {
                dtde.acceptDrag(DnDConstants.ACTION_COPY);
            } else {
                dtde.rejectDrag();
            }
            repaint();
        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {
        }

        @Override
        public void dropActionChanged(DropTargetDragEvent dtde) {
        }

        @Override
        public void dragExit(DropTargetEvent dte) {
            state = DragState.Waiting;
            repaint();
        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            state = DragState.Waiting;
            repaint();
        }
    }
}

这篇关于Java拖放JFrame上特定扩展名的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆