2009-04-03 20 views
11

OK, ten problem jest poza moją ligą. Próbuję zaimplementować widget GUI w ruchu obrotowym, który pozwala upuszczać pliki na JTable i umożliwia przeciąganie wierszy JTable w celu ponownego sortowania. Pomyśl o listach odtwarzania VLC lub w iTunes.JTable - przeciągnij i upuść

Mam upuszczanie plików z OS (Explorer, Finder, itp.) Działa dobrze, ale mam niemożliwy czas z ponownym rozmieszczeniem wierszy tabeli, gdy pliki są w. Problem jest kiedy dodam niestandardowy TransferHandler do tabeli, przeciągając z tabeli, natychmiast zginie. Oto przykładowy kod:

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); 
    } 
} 

uruchomić ten kod jak jest, a zobaczysz, że nie można zainicjować przeciągnij na table.If komentować na wezwanie do setTransferHandler() na stole, przeciągając utwory (Kiedy zaczynam przeciągać wiersz tabeli, otrzymuję X'owy kółko kursora mówiąc, że nie mogę tam wejść). Ale zaraz po ustawieniu TransferHandler dla tabeli nie mogę przeciągać żadnych wierszy. Problem musi być w TransferHandler, ale dokładnie go uszkodziłem i debugowałem, i ustaliłem, że przeciąganie nigdy się nie rozpoczyna, gdy na stole jest TransferHandler. Co ja robię źle?

+0

Jak dziwne. Mam ten sam problem. Próbuję sobie przypomnieć, czy wykonałem jakąś pracę, w której miałem stolik obsługujący zarówno przeciąganie, jak i pomijanie. – willcodejavaforfood

Odpowiedz

3

Wygląda na to, że nie używasz prawidłowo narzędzia TransferHandler. Spróbuj przeczytać samouczek: here.

Zobacz dokument TransferHandler doc here. Pusty konstruktor nie wygląda na przeznaczony do użytku poza podklasą TransferHandler.

Nie zaimplementowano żadnej funkcjonalności dostępnej w standardowym module TransferHandler dostępnym w komponentach Swing. Zobacz exerpt z samouczka DnD here (moja pogrubione):

Uwaga: W przypadku instalacji niestandardowej TransferHandler na składnik Swing, wsparcie domyślne otrzymuje. Na przykład, jeśli zastąpisz TransferHandler JTextField z takim, który obsługuje tylko kolory, wyłączysz jego obsługę importu i eksportu tekstu. Jeśli musisz wymienić domyślny TransferHandler - na przykład taki, który obsługuje tekst - będziesz musiał ponownie zaimplementować funkcję importowania i eksportowania tekstu. To nie musi być tak obszerne, jak zapewnia Swing - może to być tak proste, jak wspieranie smaku danych StringFlavor, w zależności od potrzeb aplikacji.

5

miałem ten sam problem, nie ma to nic wspólnego z niestandardowym realizacji TransferHandler. Po wymianie narzędzia TransferHandler należy także przytrzymać domyślny parametr DragSource i nakazać rozpoznanie gestu przeciągania. Może być również konieczne zaimplementowanie własnego Transferable, ponieważ musisz przekazać go do metody DragGestureEvent.startDrag().

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

pracował dla mnie, gdybym pominął pierwsze dwie linie - 'setTransferHandler' oraz' setDragEnabled'. W rzeczywistości ustawienie włączonego przeciągania spowodowało dla mnie 'InvalidDnDOperationException: Drag and drop in progress'. Zakładam też, że 'dm' odnosi się do' table.getModel() '. –

+0

pracował bez skazy. Ta sama uwaga, co plakat przede mną, pomiń pierwsze dwa wiersze. – user1052080

1

nie chciałem dostać się do śrub i nakrętek, co się dzieje, więc po prostu przekazać metod I nie był zainteresowany starego TransferHandler.

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

Rozpocznij od standardowej konfiguracji, ale przenieś stary TransferHandler do niestandardowego narzędzia 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); 
    } 
} 

Jeden haczyka jest createTransferable (JComponent) i exportDone (JComponent, zbywalne, int) metody są chronione tak trzeba zrobić odbicie aby przekazać do tych metod. Kiedy nie robiłem tej delegacji refleksyjnej, strategia nie działała. Kiedy już to zrobiłem, przeciąganie i upuszczanie działało zgodnie z oczekiwaniami bez zmiany DragSource lub konieczności napisania nowego Transferable.

+0

niechlujny przykładowy kod. boolean return type canImport nie zwraca nic i nie zwraca typu exit. –

+0

Dlaczego to jest niechlujstwo? W pytaniu wyraźnie stwierdza, że ​​próbuje dodać TransferHandler do tabeli w celu obsługi zrzutów. Jego cały problem polega na tym, że kiedy to robi, wsparcie przeciągania dla stołu przestaje działać. To, co dzieje się pod kołdrą, polega na tym, że kiedy dostarcza swój własny TransferHandler, przytłacza domyślnie zainstalowany na stole. Jest to przykład przekazywania delegacji do oryginalnego TransferHandler z tabeli, a sekret używa refleksji do implementacji funkcji createTransferable() i exportDone(). Inne metody można nadpisywać lub delegować do woli. – rancidfishbreath

Powiązane problemy