2009-04-03 12 views
11

OK、この問題は私のリーグ外です。私はファイルをJTableにドロップすることができるスイングでGUIウィジェットを実装しようとしており、JTableの行を再ソートのためにドラッグできるようにしています。 VLCのプレイリストやiTunesのものを考えてみてください。JTable - ドラッグ&ドロップ

OS(Explorer、Finderなど)からファイルを削除しても問題ありませんが、ファイルが入っていればテーブルの行を並べ替えるのは不可能ですカスタムのTransferHandlerをテーブルに追加すると、からドラッグすると、テーブルが即座に削除されます。そのまま、あなたは、あなたが作品をドラッグし、テーブルの上にsetTransferHandler()の呼び出しをコメントアウトtable.Ifのドラッグを開始することはできませんことがわかります

import javax.swing.*; 

public class TableTest 
{ 
    public static void main (String [] argv) 
    { 
     // setup table data 
     String [] columns = new String [] {"Foo", "Bar", "Baz", "Quux"}; 
     String [][] data = new String [][] {{"A", "B", "C", "D"}, 
         {"1", "2", "3", "4"}, 
         {"i", "ii", "iii", "iv"}}; 
     // create table 
     JTable table = new JTable(data, columns); 

     // set up drag and drop 
     table.setDragEnabled(true); 
     table.setDropMode(DropMode.INSERT_ROWS); 
     table.setFillsViewportHeight(true); 
     TransferHandler dnd = new TransferHandler() { 
      // here be code to handle drops, and one would 
      // presume drag exporting, too 
     }; 
     table.setTransferHandler(dnd); 
     JScrollPane scroll = new JScrollPane(table); 

     // create and show window 
     JFrame window = new JFrame(); 
     window.getContentPane().add(scroll); 
     window.pack(); 
     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     window.setVisible(true); 
    } 
} 

を実行し、このコード:ここではいくつかのサンプルコードです(つまり、テーブルの行をドラッグし始めると、そこにドロップできないというX'dの円カーソルが表示されます)。しかし、TransferHandlerがテーブルに設定されるとすぐに、私は行をドラッグできません。問題はTransferHandler内にある必要がありますが、私は徹底的にトラブルシューティングとデバッグを行い、テーブルにTransferHandlerがあるとドラッグが開始されないと判断しました。私は間違って何をしていますか?

+0

私は同じ問題を抱えています。私はどこからでもドラッグすることをサポートするテーブルを持っていました。 – willcodejavaforfood

答えて

3

TransferHandlerを適切に使用しているように見えません。チュートリアルhereを読んでみてください。

TransferHandlerのドキュメントhereを参照してください。空のコンストラクタは、TransferHandlerのサブクラス外での使用のためのものではないように見えます。

また、Swingコンポーネントで提供される標準のTransferHandlerに用意されている機能は実装していません。

注:あなたがSwingコンポーネント上にカスタムのTransferHandlerをインストールする場合、デフォルトのサポートを交換したドラッグ&ドロップチュートリアルhere(私の太字)からの抜粋を参照してください。たとえば、JTextFieldのTransferHandlerを色のみを扱うものに置き換えた場合、テキストのインポートと書き出しをサポートする機能が無効になります。 テキストを処理するデフォルトのTransferHandlerを置き換える必要がある場合は、テキストのインポートとエクスポートの機能を再実装する必要があります。これは、Swingが提供するものほど広範囲である必要はありません。アプリケーションのニーズに応じて、StringFlavorデータの味をサポートするのと同じくらいシンプルにすることができます。

3

空のTransferHandlerが実際にDnDイベントが発生するのを防ぐことが問題だと思います。ここには関連性のあるサンプルがあります。

http://www.java2s.com/Code/Java/Swing-JFC/ExtendedDnDDragandDropDemo.htm

+0

ありがとうございました。この例は素晴らしかったです:)最初の2行、 'setTransferHandler'と' setDragEnabled'を省いた場合、 – Amarnath

5

私は同じ問題を抱えていた、それがTransferHandlerののカスタム実装とは何の関係も持っていないです。 TransferHandlerを置き換えるときは、デフォルトのDragSourceを保持し、ドラッグジェスチャを認識するように指示する必要もあります。また、DragGestureEvent.startDrag()メソッドに渡す必要があるため、独自のTransferableを実装する必要があります。

table.setTransferHandler(new MyTransferHandler()); 
    table.setDragEnabled(true); 
    DragSource source = DragSource.getDefaultDragSource(); 
    source.createDefaultDragGestureRecognizer(table, DnDConstants.ACTION_COPY, new DragGestureListener() { 

     @Override 
     public void dragGestureRecognized(DragGestureEvent dge) { 
      //grab the selected files from the table model 
      ArrayList<File> files = new ArrayList<File>(); 
      for (int row : table.getSelectedRows()) { 
       files.add((File) dm.getValueAt(row, 1)); 
      } 

      //FileTransferable is a custom Transferable implementation 
      Transferable transferable = new FileTransferable(files); 

      //and this is the magic right here 
      dge.startDrag(null,transferable); 
     } 
    }); 
+1

が私に役立ちました。実際にドラッグを有効にすると、InvalidDnDOperationException:ドラッグアンドドロップが進行中です。同様に、 'dm'は' table.getModel() 'を参照すると仮定します。 –

+0

は完璧に機能しました。私の前のポスターと同じ発言で、最初の2行は除外します。 – user1052080

1

私はので、私はちょうど私が古いのTransferHandlerに興味がなかった方法を委任何が起こっていたかのナットとボルトに取得する必要はありませんでした。

tree.setDragEnabled(true); 
tree.setDropMode(DropMode.XXXX); 
tree.setTransferHandler(new MyTransferHandler(tree.getTransferHandler()); 

標準の設定から始めて、古いTransferHandlerをカスタムのTransferHandlerに渡します。

private class MyTransferHandler extends TransferHandler { 
    private TransferHandler delegate; 

    public MyTransferHandler(TransferHandler delegate) { 
    this.delegate = delegate; 
    } 

    public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 
    return delegate.canImport(comp, transferFlavors); 
    } 

    public boolean canImport(TransferSupport support) { 
    return true; 
    } 

    protected Transferable createTransferable(JComponent c) { 
    try { 
     Method method = delegate.getClass().getDeclaredMethod("createTransferable", JComponent.class); 
     method.setAccessible(true); 
     return (Transferable) method.invoke(delegate, c); 
    } catch (Exception e) { 
     return super.createTransferable(c); 
    } 
    } 

    public void exportAsDrag(JComponent comp, InputEvent event, int action) { 
    delegate.exportAsDrag(comp, event, action); 
    } 

    protected void exportDone(JComponent source, Transferable data, int action) { 
    try { 
     Method method = delegate.getClass().getDeclaredMethod("exportDone", JComponent.class, Transferable.class, 
      int.class); 
     method.setAccessible(true); 
     method.invoke(delegate, source, data, action); 
    } catch (Exception e) { 
     super.exportDone(source, data, action); 
    } 
    } 

    public int getSourceActions(JComponent c) { 
    return delegate.getSourceActions(c); 
    } 

    public Icon getVisualRepresentation(Transferable t) { 
    return delegate.getVisualRepresentation(t); 
    } 

    public boolean importData(JComponent comp, Transferable t) { 
    return delegate.importData(comp, t); 
    } 

    public boolean importData(TransferHandler.TransferSupport support) { 
    return delegate.importData(support); 
    } 
} 

一つの落とし穴は、あなたがそれらのメソッドに委譲するためにリフレクションを行う必要があるので、createTransferable(JComponentの)とexportDone(JComponentに、譲渡、INT)メソッドが保護されていることです。私がこの反射代表団をしなかったとき、戦略はうまくいかなかった。 DragSourceを変更したり、新しいTransferableを作成したりせずに、このデリゲーションをドラッグアンドドロップすると、期待通りに機能しました。

+0

サンプルコードが駄目です。 boolean戻り型canImportは何も返しません。戻り値の型はexportDoneです。 –

+0

これはなぜ乱暴なのですか?この質問では、ドロップをサポートするためにTransferHandlerをテーブルに追加しようとしていると具体的に述べています。彼の全面的な問題は、彼がそれをすると、テーブルのドラッグサポートが機能しなくなることです。カバーの下で何が起こるかは、彼が自分自身のTransferHandlerを提供するとき、彼はテーブルにインストールされたデフォルトのものをぶつけます。これは、テーブルから元のTransferHandlerに委譲する方法の例です。シークレットは、リフレクションを使用してcreateTransferable()およびexportDone()を実装しています。他の方法は自由に上書きまたは委任することができます。 – rancidfishbreath