swing - 自 1.8.0_40 起,JavaFX swing 节点 D&D 失败

标签 swing drag-and-drop javafx-8

我在我的一个 JavaFX 应用程序中使用 Swing JTextArea。 该应用程序支持 D&D,迄今为止在 Java 1.8.0_20 中运行良好。 使用 Java 1.8.0_40 我收到错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: failed to parse:Shell IDList Array
    at java.awt.datatransfer.DataFlavor.<init>(DataFlavor.java:503)
    at javafx.embed.swing.DataFlavorUtils.getDataFlavors(DataFlavorUtils.java:64)
    at javafx.embed.swing.CachingTransferable.getTransferDataFlavors(CachingTransferable.java:62)
    at javafx.embed.swing.FXDnD$FXDropTargetContextPeer.getTransferDataFlavors(FXDnD.java:450)
    at java.awt.dnd.DropTargetContext.getCurrentDataFlavors(DropTargetContext.java:223)
    at java.awt.dnd.DropTargetDragEvent.getCurrentDataFlavors(DropTargetDragEvent.java:139)
    at javax.swing.TransferHandler$TransferSupport.getDataFlavors(TransferHandler.java:532)
    at javax.swing.TransferHandler.canImport(TransferHandler.java:926)
    at javax.swing.TransferHandler$DropHandler.handleDrag(TransferHandler.java:1467)
    at javax.swing.TransferHandler$DropHandler.dragEnter(TransferHandler.java:1486)
    at java.awt.dnd.DropTarget.dragEnter(DropTarget.java:358)
    at javax.swing.TransferHandler$SwingDropTarget.dragEnter(TransferHandler.java:1238)
    at javafx.embed.swing.FXDnD$FXDropTargetContextPeer.lambda$postDropTargetEvent$11(FXDnD.java:504)
    at javafx.embed.swing.FXDnD$FXDropTargetContextPeer$$Lambda$135/2110853554.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:749)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:702)
    at java.awt.EventQueue$3.run(EventQueue.java:696)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:719)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

一个简短的运行示例来显示问题:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingNode;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class TestDDWithSwing extends Application  {

    private boolean stop=false; 
    private Thread swingNodeRefresher=null;

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

    public void start(Stage stage) {
        Scene scene = new Scene(new StackPane());
        SwingNode swingNode= new SwingNode();
        final JTextArea ta=new JTextArea("drop a file..."); 
        final JPanel panel = new JPanel(new BorderLayout());
        panel.add(ta,BorderLayout.CENTER);
        final JScrollPane jsp = new JScrollPane(ta);
        ta.setMinimumSize(new Dimension(200,200));
        swingNode.setContent(jsp);

        swingNode.setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                Dragboard db = event.getDragboard();
                if (db.hasFiles()) {
                    event.acceptTransferModes(TransferMode.COPY);
                } 
                event.consume();
            }
        });
        swingNode.setOnDragDropped(new EventHandler <DragEvent>()  {
            @Override
            public void handle(DragEvent event) {
                Dragboard dragboard = event.getDragboard();
                event.consume();
                if(dragboard.hasFiles()){
                    try{
                        File file= dragboard.getFiles().get(0);
                        System.out.println(Platform.isFxApplicationThread());
                        if(file.isFile()) {
                                ta.setText(readFile(file.getCanonicalFile())); 
                        }
                    } catch (Exception e) {e.printStackTrace();}
                }
                dragboard.clear();
            }
        });

        ((StackPane) scene.getRoot()).getChildren().add(swingNode);
        stage.setOnCloseRequest(
                new EventHandler<WindowEvent>() {
                    @Override
                    public void handle(WindowEvent event) {
                        stop=true;
                        swingNodeRefresher.interrupt();
                        try {Thread.sleep(300);} catch (InterruptedException e) {   }
                        System.exit(0);
                    }
                });
        stage.setWidth(200);
        stage.setHeight(200);
        stage.setScene(scene);
        stage.show();

        Task<Integer> task = new Task<Integer>() {
            @Override protected Integer call() throws Exception {
                while (!stop){
                    ta.repaint();
                    try {Thread.sleep(300);} catch (InterruptedException e) {   }
                    }

                return 0;
            }
        };
        swingNodeRefresher=new Thread(task);
        swingNodeRefresher.start();
    }

    private static String readFile(File file) throws IOException{
        System.out.println("importing: " + file.getCanonicalPath() );
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        StringBuilder sb = new StringBuilder();
        String x=in.readLine();
        sb.append(x);
        while(x != null){
            x=in.readLine();
            if(x != null){
                sb.append("\n");
                sb.append(x);
            } 
        }
        in.close();
        return sb.toString();
    }

}

有什么提示吗?

最佳答案

希望回答还不算太晚。
在过去的几天里,我遇到了同样的异常,并在网上搜索了解决方案。经过一番谷歌搜索后,除了这个错误报告之外,什么也没找到:
https://bugs.openjdk.java.net/browse/JDK-8133329

这是什么……?!此错误已在等待接受时得到解决,并且可能会在下一个 JVM 中修复。
那我现在该怎么办?! (可能会再次考虑迁移到QtC# WPF!哈哈)

现在,我使用这个技巧只是为了避免异常:
‍‍‍‍

swingNode.addEventFilter(EventType.ROOT, event -> {
    final String type = event.getEventType().getName();
    if (type.contains("DRAG") || type.contains("drag")) {
        // Handle the drag event here if you want)
        ...

        // Avoid drag event reaching the underlying swing components
        event.consume();
    }
});

关于swing - 自 1.8.0_40 起,JavaFX swing 节点 D&D 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25576088/

相关文章:

java - JTable从第二行读取文本文件

android - 将回收器 View 数据中的 onMove() 更改更新到房间数据库

google-chrome - 从 Outlook 拖动到 Chrome 会将电子邮件移动到“已删除”文件夹

Java本地化数字格式

java - 为什么我的按钮没有显示?

java - 在不同类的 JTextArea (java) 中加载文本文件

javascript - 如何使用 jquery 向拖放中的拖放元素添加属性?

JavaFX 3D 深度渲染不正确

java - 更新到 java 8 后 ListView 出现问题

java - Fontawesome-fx jar 在场景生成器中没有 UI 组件