2013-05-01 44 views
9

Tôi hiện đang thử nghiệm với chức năng kéo thả & sử dụng Java 7 Update 21.Java 7: Cách triển khai kéo và thả trong Java?

hệ điều hành mục tiêu của tôi là:

  • Windows 7
  • Ubuntu 12.04
  • Mac OSX 10,6/10,8

Yêu cầu là:

  • kéo tập tin từ hệ thống tập tin và thả nó vào ứng dụng Java của tôi (thực hiện một bản sao của tập tin vào một thư mục tạm thời) -> làm việc cho Linux & MacOSX & của Windows

  • kéo e-mail từ Thunderbird và thả chúng vào ứng dụng Java của tôi (tiết kiệm chúng như hoàn chỉnh * .eml trên hệ thống tập tin)

các mã sau đây làm việc với tập tin đơn giản giảm xuống ứng dụng của tôi dành cho Windows, MacOSX Ubuntu. Một yêu cầu nữa là để thả e-mail từ Thunderbird sang ứng dụng Java của tôi (thư được tự động chuyển thành tệp * .eml và được lưu trữ vào đĩa). Điều này cũng hoạt động tốt cho Windows nhưng tôi nhận được "Dữ liệu Hương vị không được hỗ trợ ngoại lệ" trong Ubuntu và MacOSX ...

EDIT: Tôi đã thử với OpenJDK 7 trên Ubuntu, nhưng với điều đó 't làm việc. Chỉ với phiên bản JDK của Oracle.

Có ai đó có ý tưởng cách khắc phục/đạt được điều đó không?

Rất cám ơn trước!

Đây là một mẫu executeable đơn giản:

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.DropTargetDropEvent; 
import java.io.File; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.nio.file.StandardCopyOption; 
import java.util.List; 


public class DragDropTest extends javax.swing.JFrame { 


    public DragDropTest() { 
     initComponents(); 
     initDragAndDrop(); 
    } 

    private void initDragAndDrop() { 
     this.setDropTarget(new DropTarget(){ 
      @Override 
      public synchronized void drop(DropTargetDropEvent dtde) { 
       try { 
        Transferable transfer = dtde.getTransferable(); 
        if(transfer.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 
         dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 
         List objects = (List)transfer.getTransferData(DataFlavor.javaFileListFlavor); 
         for(Object object : objects) { 
          if(object instanceof File) { 
           File source = (File)object; 
           File dest = new File(System.getProperty("user.home")+File.separator+source.getName()); 
           Files.copy(Paths.get(source.getAbsolutePath()), Paths.get(dest.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING); 
           System.out.println("File copied from "+source.getAbsolutePath()+" to "+dest.getAbsolutePath()); 
          } 
         } 
        } else if(transfer.isDataFlavorSupported(DataFlavor.stringFlavor)) { 
         dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 
         String type = (String)transfer.getTransferData(DataFlavor.stringFlavor); 
         System.err.println("Data flavor not supported: "+type); 
        } else { 
         System.err.println("Data flavor not supported."); 
        } 
       } catch(UnsupportedFlavorException ex) { 
        System.err.println(ex.getMessage()); 
       } catch(IOException ex) { 
        System.err.println(ex.getMessage()); 
       } catch(Exception ex) { 
        System.err.println(ex.getMessage()); 
       } finally { 
        dtde.dropComplete(true); 
       } 
      } 
     }); 
    } 

    @SuppressWarnings("unchecked")      
    private void initComponents() { 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     setTitle("Drag & Drop"); 
     setResizable(false); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 200, Short.MAX_VALUE) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 200, Short.MAX_VALUE) 
     ); 

     pack(); 
    }      

    public static void main(String args[]) { 
     new DragDropTest().setVisible(true); 
    } 

} 

Trả lời

0

Dưới đây là một làm việc xung quanh cách cuối cùng tôi đã giải quyết vấn đề cho thời điểm này.

  1. nếu file-list-hương vị không được hỗ trợ, có được URL imap từ trình đơn thả sự kiện
  2. mở một kết nối imap với các thông tin được cung cấp từ các URL imap
  3. mở imap-store, imap thư mục, nhắn tìm kiếm bằng UID và cuối cùng lấy nhắn
  4. chuyển đổi sang định dạng * .eml

thư viện yêu cầu: Apache Commons I/OJava Mail API

Sau đây là việc thực hiện thả sự kiện:

scrDocuments.setDropTarget(new DropTarget() { 
     @Override 
     public synchronized void drop(DropTargetDropEvent evt) { 
      try { 
       Transferable transfer = evt.getTransferable(); 
       if(transfer.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 
        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 
        List objects = (List)transfer.getTransferData(DataFlavor.javaFileListFlavor); 
        for(Object object : objects) { 
         if(object instanceof File) { 
          File file = (File)object; 
          // store file ... 
         } 
        } 
       } else { 
        try { 
         String url = fetchURL(evt, transfer); 
         ImapMessage eml = new ImapMessage(url); 
         File file = eml.fetchMessage(); 
         // store file ... 
        } catch(Exception ex) { 
         System.err.println(ex.getMessage()); 
        } 
       } 
      } catch(Exception ex) { 
       System.err.println(ex.getMessage()); 
      } finally { 
       evt.dropComplete(true); 
      } 
     } 
    }); 

private String fetchURL(DropTargetDropEvent evt, Transferable transfer) throws IOException, UnsupportedEncodingException, UnsupportedFlavorException { 
    for(DataFlavor flavor : transfer.getTransferDataFlavors()) { 
     if(flavor.isRepresentationClassInputStream()) { 
      if(flavor.getHumanPresentableName().equals("application/x-moz-file-promise-url")) { 
       evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 
       BufferedReader reader = new BufferedReader(new InputStreamReader((InputStream)transfer.getTransferData(flavor), "ISO-8859-1")); 
       String fAddress = reader.readLine(); 
       reader.close(); 
       return fAddress; 
      } 
     } 
    } 
    throw new IOException("No transferable object or stream found."); 
} 

Và lớp sau trông lên máy chủ imap và lấy mail:

public class ImapMessage { 

    private String authority; 
    private String protocol; 
    private String host; 
    private int port; 
    private String username; 
    private String password; 
    private String foldername; 
    private long msgid; 
    private String filename; 
    private Message message; 

    public ImapMessage(String url) throws IOException, MessagingException { 
     parseURL(decodeURL(url)); 
    } 

    @Override 
    public String toString() { 
     return "protocol: "+protocol+"\n"+ 
       "host: "+host+"\n"+ 
       "port: "+port+"\n"+ 
       "username: "+username+"\n"+ 
       "password: "+password+"\n"+ 
       "folder: "+foldername+"\n"+ 
       "msgid: "+msgid+"\n"+ 
       "filename: "+filename; 
    } 

    private String decodeURL(String url) throws IOException { 
     if(url!=null && !url.isEmpty()) { 
      String newurl = ""; 
      for(int i=0; i<url.length(); i+=2) { 
       newurl+=url.substring(i, i+1); 
      } 
      newurl = StringUtils.replace(newurl, "%3E", ">"); 
      newurl = StringUtils.replace(newurl, "%20", " "); 
      return newurl; 
     } else { 
      throw new IOException("The given URL is empty or invalid."); 
     } 
    } 


    private void parseURL(String url) throws IOException, MalformedURLException { 
     if(url!=null && !url.isEmpty()) { 
      //<editor-fold defaultstate="collapsed" desc="Parse Protocol"> 
      if(url.startsWith("imaps")) { 
       url = StringUtils.replace(url, "imaps", "http", 1); 
       protocol = "imaps"; 
      } else if(url.startsWith("imap")) { 
       url = StringUtils.replace(url, "imap", "http", 1); 
       protocol = "imap"; 
      } else { 
       throw new IOException("Unsupported protocol: "+url.substring(0, url.indexOf("://"))); 
      } 

      try { 
       URL newurl = new URL(url); 
       String path = newurl.getPath(); 
       String query = newurl.getQuery(); 
       authority = newurl.getAuthority(); 
       host = newurl.getHost(); 
       port = newurl.getPort(); 
       username = newurl.getUserInfo(); 
       password = "provide your password here"; 
       foldername = path.substring(path.indexOf(">/")+2, path.lastIndexOf(">")); 
       msgid = Long.parseLong(path.substring(path.lastIndexOf(">")+1, path.length())); 
       filename = query.substring(query.indexOf("=")+1, query.length()); 
      } catch (MalformedURLException ex) { 
       throw ex; 
      } 
     } else { 
      throw new IOException("The given URL is empty or invalid."); 
     } 
    } 

     public File fetchMessage() throws IOException, FileNotFoundException, MessagingException { 

      Store store = null; 
      Folder folder = null; 
      File filepath = new File("/destination/directory"); 
      try { 
       Properties props = System.getProperties(); 
       props.setProperty("mail.store.protocol", protocol); 
       Session session = Session.getDefaultInstance(props, null); 
       // session.setDebug(true); 
       store = session.getStore(protocol); 
       store.connect(host, port, username, password); 
       folder = store.getFolder(foldername); 
       folder.open(Folder.READ_ONLY); 
       UIDFolder ufolder = (UIDFolder)folder; 
       message = ufolder.getMessageByUID(msgid); 
       if(message!=null) { 
        File file = null; 
        if(filename.equals("null")) { 
         file = new File(filepath.getAbsolutePath()+File.separator+Long.toString(System.nanoTime())+".eml"); 
        } else { 
         file = new File(filepath.getAbsolutePath()+File.separator+filename); 
        } 
        message.writeTo(new FileOutputStream(file)); 
        return file; 
       } else { 
        throw new MessagingException("The requested e-mail could not be found on the mail server."); 
       } 
      } catch(Exception ex) { 
       throw ex; 
      } finally { 
       if(folder!=null) { 
        folder.close(true); 
       } 
       if(store!=null) { 
        store.close(); 
       } 
      } 
     } 

    } 
5

Thay vì ném, tại sao không in ra những gì hương vị dữ liệu bạn nhận được trên các chuyển nhượng, và xem nếu có một bạn có thể sử dụng. Một cái gì đó như,

else { 
     for(DataFlavor f : transfer.getTransferDataFlavors()) { 
      System.out.println("flavor f:" + f + " type:" + f.getMimeType() + " javaClas:" + f.getDefaultRepresentationClass()); 
     } 
} 

Cho đầu ra, bạn có thể xem cách lưu tệp vào một tệp.

+1

đi thêm một bước nữa in hương vị bạn nhận được và cố gắng để thao tác nó, có thể lưu tất cả để tập tin và sau đó xem những gì là .eml mặc dù tôi nghi ngờ chỉ có một sẽ được thiết lập. nếu bạn không nhận được bất cứ điều gì có thể sử dụng có thể là một vấn đề với thunderbird cho * nix – tgkprog

6

Thực tế vấn đề không nằm trong mã Java của bạn ... Đó là lỗi trong ubuntu trong khi Ubuntu Unity không hỗ trợ Kéo và Thả trên hai Windows (Trong ứng dụng của bạn giữa Mozilla Thunderbird và Java App). trong khi có thể kéo và thả tệp từ hệ thống tệp vào cửa sổ ..

Để xác nhận điều này, hãy thử kéo tệp thư từ Thunderbird đến cửa sổ trình duyệt dưới dạng Tệp đính kèm Gmail ,,, nó sẽ không hoạt động.

Để theo kịp với xem xét lỗi này cập nhật Bug trong Ubuntu Bugs Launchpad từ: https://bugs.launchpad.net/unity/+bug/995039

+0

Cảm ơn đề xuất của bạn. Tôi đã cố gắng để loại bỏ Mousetweaks với "sudo apt-get purge mousetweaks". Nhưng nó vẫn không hoạt động ... :-( – salocinx