2017-09-12 4 views
1

Je suis nouveau sur JavaFX et, par conséquent, aussi sur TornadoFX alors s'il vous plait, gardez-moi.TornadoFX Glisser-déposer sur un TreeView

J'ai une application simple en Java, mais je veux la déplacer vers Kotlin et je rencontre des problèmes pour trouver les mécanismes correspondants dans TornadoFX. J'ai un ListView tenant des implémentations de IStoryItem représentant des histoires et des chapitres. Je veux être capable de déplacer les chapitres et même d'une histoire à l'autre. Le TreeView en Java a la mise en œuvre suivante dans son setCellFactory appel:

tv.setCellFactory(new Callback<TreeView<IStoryItem>, TreeCell<IStoryItem>>() { 
     @Override 
     public TreeCell<IStoryItem> call(TreeView<IStoryItem> siTreeView) { 
      TreeCell<IStoryItem> cell = new TreeCellStoryEditor(); 

      cell.setOnDragDetected((MouseEvent event) -> { 
       // Don't drag Story nodes. 
       if (cell.getItem() instanceof Story) return; 

       Dragboard db = cell.startDragAndDrop(TransferMode.MOVE); 

       // Put the Part on the dragboard 
       // From: https://stackoverflow.com/a/30916660/780350 
       ClipboardContent content = new ClipboardContent(); 
       content.put(objectDataFormat, cell.getItem()); 
       db.setContent(content); 

       event.consume(); 
      }); 

      cell.setOnDragOver((DragEvent event) -> { 
       if (event.getGestureSource() != cell && event.getDragboard().hasContent(objectDataFormat)) { 
        /* allow for moving */ 
        event.acceptTransferModes(TransferMode.MOVE); 
       } 

       event.consume(); 
      }); 

      cell.setOnDragEntered((DragEvent event) -> { 
       IStoryItem item = cell.getItem(); 
       if (item instanceof Story && 
         event.getGestureSource() != cell && 
         event.getDragboard().hasContent(objectDataFormat)) { 
        cell.setUnderline(true); 
       } 

       event.consume(); 
      }); 

      cell.setOnDragExited((DragEvent event) -> { 
       cell.setUnderline(false); 
       event.consume(); 
      }); 

      cell.setOnDragDropped((DragEvent event) -> { 
       try { 
        Dragboard db = event.getDragboard(); 
        boolean success = false; 
        if (db.hasContent(objectDataFormat)) { 
         Part droppedPart = (Part)db.getContent(objectDataFormat); 
         IStoryItem targetStoryItem = cell.getItem(); 

         // Question: How to handle drops between leaf items or 
         // before the initial leaf or after the final leaf. 
         if (targetStoryItem instanceof Story) { 
          Story story = (Story) targetStoryItem; 

          updateStoryWith(droppedPart, story); 
          addPartTo(cell.getTreeItem(), droppedPart); 
          success = true; 
         } 
        } 

        event.setDropCompleted(success); 
        event.consume(); 
       } catch (Exception e) { 
        System.out.println(e.getMessage()); 
       } 
      }); 

      cell.setOnDragDone((DragEvent event) -> { 
       if (event.getTransferMode() == TransferMode.MOVE) { 
        IStoryItem item = cell.getItem(); 
        TreeItem<IStoryItem> ti = cell.getTreeItem(); 
        TreeItem<IStoryItem> pti = ti.getParent(); 
        pti.getChildren().remove(ti); 

        IStoryItem psi = pti.getValue(); 
        // Remove the Part/Chapter from its previous Story 
        boolean removed = removePartFrom(psi, item); 
       } 
       event.consume(); 
      }); 

      cell.setEditable(true); 

      return cell; 
     }; 
    }); 

J'ai cherché quelque chose de similaire dans TornadoFX mais ne trouve rien qui ressemble à cela fonctionnerait. J'utilise déjà le générateur cellFormat mais je n'arrive pas à comprendre comment ajouter les gestionnaires d'événements à l'intérieur. Je vois dans l'IntelliJ IntelliJ qu'il y a aussi un générateur cellFactory mais je ne sais pas comment l'utiliser ou comment y ajouter les gestionnaires d'événements.

Répondre

2

Vous pouvez utiliser exactement la même technique dans TornadoFX. Rappelez-vous, TornadoFX applique juste une API de haut niveau au-dessus de JavaFX. Vous pouvez toujours toujours accéder à l'API JavaFX sous-jacente sans problème.

tv.setCellFactory { 
    object : TreeCell<IStoryItem>() { 
     init { 
      setOnDragOver { event -> 

      } 
      setOnDragEntered { event -> 

      } 
      setOnDragExited { event -> 

      } 
      setOnDragDropped { event -> 

      } 
     } 
    } 
} 
+0

Ceci est une syntaxe étrange pour moi. La méthode 'setCellFactory' prend un objet Callback (avec une méthode' call'). Comment cela se traduit-il par ce que vous avez ici? – melston

+0

@melston C'est ce qu'on appelle la conversion SAM (SAM = Single Abstract Method). Plus d'informations peuvent être trouvées ici: https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions –

+0

@ RuckusT-Boom, de toutes les descriptions que j'ai vu des constructeurs de SAM, j'aurais pensé l'exemple aurait été 'object: Callback {...}' – melston