3

JList から OS への DND アクションを作成したいと考えています。今のところ私の解決策は、TransferHandler を使用することです。メソッド createTransferable で、コピーしたいファイルで Transferable を作成します。
しかし、ここで問題があります。場合によっては、ファイルをコピーする前に FTP サーバーからファイルをダウンロードする必要があります。非常に負荷の高いダウンロード操作が JavaSwingWorker で実行されます (ステートメント d.download(tmpDir); の後ろに隠されています)。システムは、まだダウンロードされていないファイルをコピーしようとします。

ここで、ファイルをダウンロードしたに転送可能ファイルを作成できるメカニズムが必要です。私の問題の解決策はありますか? 私を助けてください!

ありがとう!

これが私の方法です:

public Transferable createTransferable(JComponent c) {
    JList list = (JList) c; // we know it's a JList
    List<PictureDecorator> selectedPictures = getSelectedValues(list.getModel());
    Vector cpFiles = new Vector();

    List<Picture> donePictures = new ArrayList<Picture>();
    List<Picture> notDonePictures = new ArrayList<Picture>();
    String tmpDir = System.getProperty("java.io.tmpdir");

    for(PictureDecorator pd : selectedPictures){
        if(pd.getPic().getStatus() == PictureStatus.DONE)
            donePictures.add(pd.getPic());
        else
            notDonePictures.add(pd.getPic());
    }

    Downloader d = new Downloader(parent, loginInformation, sced, donePictures, order);

    d.download(tmpDir);

    for(Picture p : donePictures){
        cpFiles.add(new File(tmpDir + File.separator + p.getPicture().getName()));
    }

    for(Picture p : notDonePictures) {
        cpFiles.add(p.getPicture());
    }

    TransferableFile tf = new TransferableFile(cpFiles);
    return tf;
}

ドラッグ手順を開始するものが必要です。次に、ドラッグ先のパスを取得し、写真をダウンロードして宛先パスにコピーできます。

編集:または別の定式化:オペレーティングシステムにドロップしたときにドロップ先を見つけるにはどうすればよいですか?

4

1 に答える 1

1

ドラッグを開始するTransferHandlerには、JListまたはDragSourceと の組み合わせが必要DragGestureListenerです。以下に、 でそれを行う例を示しますJTextField

final JTextField textField = new JTextField(50);
DragGestureListener dragListener = new DragGestureListener() {
    @Override
    public void dragGestureRecognized(DragGestureEvent dge) {
        // how the drag cursor should look like
        Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);

        // the component being dragged
        JTextField tf = (JTextField) dge.getComponent();

        // Here a Transferable is created directly for a single file name
        dge.startDrag(cursor, new TransferableFile(tf.getText()));
    }
};

final DragSource ds = new DragSource();
ds.createDefaultDragGestureRecognizer(textField, DnDConstants.ACTION_COPY, dragListener);

ウィンドウ作成手順内に上記のコードを入れることができます。

結果の転送可能 (TransferableFileあなたの場合) は をサポートする必要があり、メソッドからofDataFlavor.javaFileListFlavorを返す必要があります。ListFilegetTransferData(DataFlavor flavor)

これは、JVM-OS が引き継ぐ前に制御できる最後のポイントであるため、ダウンロードを行う方法でもあると思います。

問題に関してはSwingWorker、ダウンロードが完了するまでメソッド内で待つことができます。おそらくDownloader、ブール値フラグを公開するようにクラスを変更して、次のようなことができるようにしますwhile (!downloader.isDone()) { Thread.sleep(millisToSleep) };

[編集: EventDispath スレッドをビジー状態にしておくという考えが気に入らないことは認めざるを得ませんが、これで現在の問題が解決する場合は、後でより洗練された解決策を調査できます]

少し警告: ドロップ場所にアクセスできないため、 が何回getTransferData呼び出されるかわかりません。これを考慮して、Mapこれまでにダウンロードした一時ファイルで単純なキャッシュを作成することをお勧めします (合理的に聞こえます)。キャッシュ内にファイルが見つかった場合は、対応する一時ファイルを直接返し、再度ダウンロードしないでください。

それが役立つことを願っています

于 2013-07-20T19:51:24.733 に答える