我在我的一个 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 中修复。
那我现在该怎么办?! (可能会再次考虑迁移到Qt或C# 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/