在Java中的AWT中拖放的奇怪错误
问题描述:
好的,这里是错误:java.awt.dnd.InvalidDnDOperationException: The operation requested cannot be performed by the DnD system since it is not in the appropriate state
。当我在程序中放置一些文件时(从桌面抓取),出现错误。我正在使用Ubuntu 16.04和Nautilus。在Java中的AWT中拖放的奇怪错误
import javax.swing.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.io.File;
import java.util.List;
class UI extends JFrame {
List<File> droppedFiles;
UI(){
super("My Program");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null);
this.setVisible(true);
this.setResizable(true);
this.setSize(800, 500);
this.setExtendedState(MAXIMIZED_BOTH);
JTextField dropArea = getDropArea();
this.add(dropArea);
}
private JTextField getDropArea(){
JTextField dropArea = new JTextField("Drop file here");
dropArea.setBounds(50, 50, 200, 200);
dropArea.setDropTarget(createNewDropTarget(dropArea));
return dropArea;
}
private DropTarget createNewDropTarget(JTextField dropArea) {
DropTarget dt = new DropTarget(){
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
super.drop(dtde);
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
droppedFiles = (List<File>) dtde.getTransferable().
getTransferData(DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
}catch (Exception e){
e.printStackTrace();
}
}
};
return dt;
}
}
ErrorFind在初始化droppedFiles的行上出现。 (在try catch块中)。
答
以某种方式设置DropTarget
无需拨打super.drop(dtde);
。这实际上是例外的原因。这里是DropTarget.drop()
实现:
public synchronized void drop(DropTargetDropEvent dtde) {
clearAutoscroll();
if (dtListener != null && active)
dtListener.drop(dtde);
else { // we should'nt get here ...
dtde.rejectDrop();
}
}
既然你不向监听器初始化DropTarget的下降被拒绝,随后呼叫getTransferable()
失败InvalidDnDOperationException
。如果您评论super.drop(dtde);
,问题应该消失。一个更清洁的替代方案是创建一个监听器并将其传递给DropTarget
。这里是一个小例子:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class DDTest extends JPanel {
public DDTest() {
setLayout(new BorderLayout());
final JTextField dropArea = new JTextField("Drop file here");
add(dropArea);
new DropTarget(dropArea, new DropTargetAdapter() {
@Override
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>) dtde
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
private static void createAndShowGUI() {
final JFrame frame = new JFrame("DDTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DDTest());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
PS:
注意,使用absolute layout可能是复杂的,并且通常可以被避免。有些想法见A Visual Guide to Layout Managers。