Java中AWT拖放时出现奇怪错误
好的,这里是错误:Java中AWT拖放时出现奇怪错误,java,swing,drag-and-drop,awt,Java,Swing,Drag And Drop,Awt,好的,这里是错误:java.awt.dnd.InvalidDnDOperationException:请求的操作无法由dnd系统执行,因为它未处于适当的状态。当我将一些文件放入程序(从桌面抓取)时,会出现错误。我正在使用Ubuntu16.04和Nautilus import javax.swing.*; import java.awt.datatransfer.DataFlavor; import java.awt.dnd.*; import java.io.File; import java.
java.awt.dnd.InvalidDnDOperationException:请求的操作无法由dnd系统执行,因为它未处于适当的状态
。当我将一些文件放入程序(从桌面抓取)时,会出现错误。我正在使用Ubuntu16.04和Nautilus
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;
}
}
import javax.swing.*;
导入java.awt.datatransfer.DataFlavor;
导入java.awt.dnd.*;
导入java.io.File;
导入java.util.List;
类UI扩展了JFrame{
列出文件;
UI(){
超级(“我的程序”);
此.setDefaultCloseOperation(关闭时退出);
此.setLayout(null);
此.setVisible(true);
此参数为.setresizeable(true);
这个。设置大小(800500);
这个.setExtendedState(最大化两个);
JTextField dropArea=getDropArea();
添加(dropArea);
}
私有JTextField getDropArea(){
JTextField dropArea=新的JTextField(“在此处放置文件”);
下降面积.立根(50,50,200,200);
setDropTarget(createNewDropTarget(dropArea));
返回区;
}
私有DropTarget createNewDropTarget(JTextField dropArea){
DropTarget dt=新的DropTarget(){
@凌驾
公共同步作废删除(DropTargetDropEvent dtde){
超级下降(dtde);
试一试{
dtde.acceptDrop(DnDConstants.ACTION\u COPY);
droppedFiles=(列表)dtde.getTransferable()。
getTransferData(DataFlavor.javaFileListFlavor);
setText(droppedFiles.get(0.getName());
}捕获(例外e){
e、 printStackTrace();
}
}
};
返回dt;
}
}
错误出现在droppedFiles初始化的行上。(在try-catch块中)。通过设置
DropTarget
的方式,无需调用super.drop(dtde)代码>。这实际上就是例外的原因。下面是DropTarget.drop()的实现:
由于您没有使用侦听器初始化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();
}
});
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.datatransfer.DataFlavor;
导入java.awt.dnd.DnDConstants;
导入java.awt.dnd.DropTarget;
导入java.awt.dnd.DropTargetAdapter;
导入java.awt.dnd.DropTargetDropEvent;
导入java.io.File;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.SwingUtilities;
公共类DDTest扩展了JPanel{
公共测试(){
setLayout(新的BorderLayout());
最终JTextField dropArea=新的JTextField(“此处放置文件”);
添加(删除区域);
新的DropTarget(dropArea,新的DropTargetAdapter(){
@凌驾
公共作废删除(DropTargetDropEvent dtde){
试一试{
dtde.acceptDrop(DnDConstants.ACTION\u COPY);
List droppedFiles=(List)dtde
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
setText(droppedFiles.get(0.getName());
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
@凌驾
公共维度getPreferredSize(){
返回新维度(300200);
}
私有静态void createAndShowGUI(){
最终JFrame=新JFrame(“DDTest”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的DDTest());
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGUI();
}
});
}
}
PS:
请注意,使用可能很复杂,通常可以避免。请参阅以获取一些想法 通过设置DropTarget
的方式,无需调用super.drop(dtde)代码>。这实际上就是例外的原因。下面是DropTarget.drop()的实现:
由于您没有使用侦听器初始化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();
}
});
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.datatransfer.DataFlavor;
导入java.awt.dnd.DnDConstants;
导入java.awt.dnd.DropTarget;
导入java.awt.dnd.DropTargetAdapter;
导入java.awt.dnd.DropTargetDropEvent;
导入java.io.File;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.SwingUtilities;
公共类DDTest扩展了JPanel{
公共测试(){
setLayout(新的BorderLayout());
最终JTextField dropArea=新的JTextField(“此处放置文件”);
添加(删除区域);
新的DropTarget(dropArea,新的DropTargetAdapter(){
@凌驾
公共作废删除(DropTargetDropEvent dtde){
试一试{
dtde.acceptDrop(DnDConstants.ACTION\u COPY);
List droppedFiles=(List)dtde
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
dropArea.setText(已删除