【发布时间】:2012-07-31 02:19:50
【问题描述】:
我正在寻找一种方法来从单元测试中将一个文件/多个文件拖放到我的应用程序中。例如,在 Windows 资源管理器中选择一些文件,将它们拖放到我的应用程序中。
我能够测试我的应用程序中两个组件之间的拖放行为(见下文 - 如果您知道更好的方法,请随时指出),但是当数据有来自我的应用程序之外。
当我手动执行拖放操作时,我曾想过使用调试器检查“文件”Transferable,但必须有更好的方法,然后硬编码完整的Transferable。
组件之间的拖放测试示例
import org.junit.Test;
import javax.swing.Action;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
import java.awt.event.ActionEvent;
import static org.junit.Assert.assertEquals;
public class DragAndDropTest {
@Test
public void dragAndDropBetweenTwoTextFields() {
JTextField firstField = new JTextField();
JTextField secondField = new JTextField();
String testText = "Test text";
firstField.setText( testText );
firstField.selectAll();
Action copyAction = TransferHandler.getCopyAction();
copyAction.actionPerformed( new ActionEvent( firstField, ActionEvent.ACTION_PERFORMED, "Copy" ) );
Action pasteAction = TransferHandler.getPasteAction();
pasteAction.actionPerformed( new ActionEvent( secondField, ActionEvent.ACTION_PERFORMED, "Paste" ) );
assertEquals( "Text is not copied", testText, secondField.getText() );
}
}
编辑
基于此问题下的 cmets,我已通过提供硬编码 Transferable 将我的代码 sn-p 更新为“假”拖放。该代码还包含一个小主程序,它只是创建一个可以放置文件的空框架。然后将在控制台上打印路径。
在我的 PC 上,文件的拖放不使用 javaFileListFlavor,而是使用 URI 风格。
以前的经验(请参阅this question)已经告诉我,当从 Java 应用程序外部拖动某些东西时,组件接收到的Transferable 可能会有细微的差别。
所以要完全清楚:我想测试从收到的Transferable 中提取信息的代码部分。 “信息处理”代码(例如,当应用程序接收到文件时会发生什么)可以很容易地进行测试,而无需打扰 D&D。我只需要确保从Transferable 中提取正确的信息,而用硬编码的Transferable 进行测试是愚蠢的。
import org.junit.Test;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class DragAndDropTest {
private static DataFlavor URI_LIST_FLAVOR = null;
static {
try {
URI_LIST_FLAVOR = new DataFlavor( "text/uri-list;class=java.lang.String" );
}
catch ( ClassNotFoundException ignore ) {
}
}
@Test
public void testFileDragAndDrop() throws IOException, UnsupportedFlavorException {
JComponent testComponent = new JPanel();
TestingTransferHandler transferHandler = new TestingTransferHandler();
testComponent.setTransferHandler( transferHandler );
Clipboard clipBoard = new JLabel( ).getToolkit().getSystemClipboard();
Transferable transferable = new Transferable() {
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{URI_LIST_FLAVOR};
}
@Override
public boolean isDataFlavorSupported( DataFlavor flavor ) {
return flavor == URI_LIST_FLAVOR;
}
@Override
public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException {
if ( flavor == URI_LIST_FLAVOR ) {
return new String( "file:///home/robins/Desktop/swingx-1.0-javadoc.jar" );
}
throw new UnsupportedFlavorException( flavor );
}
};
clipBoard.setContents( transferable, null );
Action pasteAction = TransferHandler.getPasteAction();
pasteAction.actionPerformed( new ActionEvent( testComponent, ActionEvent.ACTION_PERFORMED, "Paste" ) );
assertEquals( transferable.getTransferData( URI_LIST_FLAVOR ), transferHandler.transferable.getTransferData( URI_LIST_FLAVOR ) );
}
private static class TestingTransferHandler extends TransferHandler{
public Transferable transferable;
@Override
public boolean canImport( TransferSupport support ) {
return true;
}
@Override
public boolean importData( TransferSupport support ) {
transferable = support.getTransferable();
try{
if ( transferable.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) {
System.out.println("File list flavor");
List<File> fileList = ( List<File> ) transferable.getTransferData( DataFlavor.javaFileListFlavor );
System.out.println( "fileList = " + fileList );
}
if ( transferable.isDataFlavorSupported( URI_LIST_FLAVOR )){
System.out.println("URI list flavor");
String uriList = ( String ) transferable.getTransferData( URI_LIST_FLAVOR );
System.out.println( "uriList = " + uriList );
}
return true;
} catch ( UnsupportedFlavorException e ) {
return false;
} catch ( IOException e ) {
return false;
}
}
}
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame( "TestFrame" );
JPanel contentPane = new JPanel( new BorderLayout( ) );
contentPane.setTransferHandler( new TestingTransferHandler() );
frame.setContentPane( contentPane );
frame.setSize( 200,200 );
frame.setVisible( true );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} );
}
}
【问题讨论】:
-
+1 个棘手的问题 :-) 您可能已经检查过 FEST 是否/如何处理这个问题?没有更多的想法......
-
基本上,文件传输是作为
List的Files 提供的。您需要能够使用DataFlavor.javaFileListFlavor的DataFlavor创建Transferable。接下来,您需要了解如何将其注入 DnD API...这就是有趣的地方 -
@kleopatra 见Fest Wiki。听起来他们只是伪造鼠标事件(这是我在 Swing 组件之间进行 D&D 测试的第一个想法,但对我来说,测试
TransferHandler就足够了),因此似乎无法从外部拖放文件应用 -
hmm .. 不太确定我是否正确理解您:假设您想测试您的 TransferHandler 是否可以从任何地方处理 imports,@MadProgrammer 的方法应该会有所帮助。用文件列表填充剪贴板并触发 transferHandler 的粘贴动作进行测试。
-
@kleopatra 我的意思是没有必要测试完整的 Swing 拖放机制,我只需要确保我的拖放相关代码按预期工作(这下来测试我的
TransferHandler使用与用户使用鼠标执行拖放时相同的输入)
标签: java swing junit drag-and-drop junit4