2014-09-05 49 views
0

如何一个列表视图中做拖放的Java FX FROP拖放问题

我只有一个列表视图(埃德。“玩家”)

我的要求是在上下移动同样的球员名单

请找我已经使用

代码(不是:我使用JDK 1.7默认的JavaFX)

例子:(玩家= ListView控件)

listView.setOnDragDetected(new EventHandler<MouseEvent>() { 

     @Override 
     public void handle(MouseEvent event) { 

      Dragboard dragBoard = listView.startDragAndDrop(TransferMode.MOVE); 

      ClipboardContent content = new ClipboardContent(); 

      content.putString(listView.getSelectionModel().getSelectedItem().getValue()); 

      dragBoard.setContent(content); 

     } 
    }); 

    listView.setOnDragDone(new EventHandler<DragEvent>() { 
     @Override 
     public void handle(DragEvent dragEvent) { 
      System.out.println("setOnDragDone left"); 

     } 
    }); 

    listView.setOnDragEntered(new EventHandler<DragEvent>() { 
     @Override 
     public void handle(DragEvent dragEvent) { 
      System.out.println("setOnDragEntered left"); 

     } 
    }); 

    listView.setOnDragExited(new EventHandler<DragEvent>() { 
     @Override 
     public void handle(DragEvent dragEvent) { 
      System.out.println("setOnDragExited left"); 

      listView.setBlendMode(null); 
     } 
    }); 

    listView.setOnDragOver(new EventHandler<DragEvent>() { 
     @Override 
     public void handle(DragEvent dragEvent) { 
      System.out.println("setOnDragOver left"); 

      dragEvent.acceptTransferModes(TransferMode.MOVE); 
     } 
    }); 

    listView.setOnDragDropped(new EventHandler<DragEvent>() { 
     @Override 
     public void handle(DragEvent dragEvent) { 

       String context = dragEvent.getDragboard().getString(); 


       dragEvent.setDropCompleted(true); 
      } 

     } 
    }); 

我是新来的JavaFX

请你在这方面提供帮助

回答

3

不注册在ListView拖动处理程序:你将无法知道拖动开始其细胞的方法并以此结束。相反,您需要在单元上注册处理程序。细节有点棘手,但基本的想法是创建一个细胞工厂,在其中创建自定义单元格;在这里您可以设置拖放处理程序。

下面是一个例子:

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import javafx.application.Application; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.DragEvent; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.input.TransferMode; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class DragAndDropListView extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     final ListView<String> listView = new ListView<>(); 
     for (int i=1; i<=20; i++) { 
      listView.getItems().add("Item "+i); 
     } 

     final IntegerProperty dragFromIndex = new SimpleIntegerProperty(-1); 

     listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 

      @Override 
      public ListCell<String> call(ListView<String> lv) { 
       final ListCell<String> cell = new ListCell<String>() { 
        @Override 
        public void updateItem(String item, boolean empty) { 
         super.updateItem(item, empty); 
         if (empty) { 
          setText(null); 
         } else { 
          setText(item); 
         } 
        } 
       }; 

       cell.setOnDragDetected(new EventHandler<MouseEvent>() { 
        @Override 
        public void handle(MouseEvent event) { 
         if (! cell.isEmpty()) { 
          dragFromIndex.set(cell.getIndex()); 
          Dragboard db = cell.startDragAndDrop(TransferMode.MOVE); 
          ClipboardContent cc = new ClipboardContent(); 
          cc.putString(cell.getItem()); 
          db.setContent(cc); 
          // Java 8 only: 
//       db.setDragView(cell.snapshot(null, null)); 
         } 
        } 
       }); 

       cell.setOnDragOver(new EventHandler<DragEvent>() { 
        @Override 
        public void handle(DragEvent event) { 
         if (dragFromIndex.get() >= 0 && dragFromIndex.get() != cell.getIndex()) { 
          event.acceptTransferModes(TransferMode.MOVE); 
         } 
        } 
       }); 


       // highlight drop target by changing background color: 
       cell.setOnDragEntered(new EventHandler<DragEvent>() { 
        @Override 
        public void handle(DragEvent event) { 
         if (dragFromIndex.get() >= 0 && dragFromIndex.get() != cell.getIndex()) { 
          // should really set a style class and use an external style sheet, 
          // but this works for demo purposes: 
          cell.setStyle("-fx-background-color: gold;"); 
         } 
        } 
       }); 

       // remove highlight: 
       cell.setOnDragExited(new EventHandler<DragEvent>() { 
        @Override 
        public void handle(DragEvent event) { 
         cell.setStyle(""); 
        } 
       }); 

       cell.setOnDragDropped(new EventHandler<DragEvent>() { 
        @Override 
        public void handle(DragEvent event) { 

         int dragItemsStartIndex ; 
         int dragItemsEndIndex ; 
         int direction ; 
         if (cell.isEmpty()) { 
          dragItemsStartIndex = dragFromIndex.get(); 
          dragItemsEndIndex = listView.getItems().size(); 
          direction = -1; 
         } else { 
          if (cell.getIndex() < dragFromIndex.get()) { 
           dragItemsStartIndex = cell.getIndex(); 
           dragItemsEndIndex = dragFromIndex.get() + 1 ; 
           direction = 1 ; 
          } else { 
           dragItemsStartIndex = dragFromIndex.get(); 
           dragItemsEndIndex = cell.getIndex() + 1 ; 
           direction = -1 ; 
          } 
         } 

         List<String> rotatingItems = listView.getItems().subList(dragItemsStartIndex, dragItemsEndIndex); 
         List<String> rotatingItemsCopy = new ArrayList<>(rotatingItems); 
         Collections.rotate(rotatingItemsCopy, direction); 
         rotatingItems.clear(); 
         rotatingItems.addAll(rotatingItemsCopy); 
         dragFromIndex.set(-1); 
        } 
       }); 

       cell.setOnDragDone(new EventHandler<DragEvent>() { 
        @Override 
        public void handle(DragEvent event) { 
         dragFromIndex.set(-1); 
         listView.getSelectionModel().select(event.getDragboard().getString()); 
        } 
       }); 


       return cell ; 
      } 


     }); 

     BorderPane root = new BorderPane(); 
     root.setCenter(listView); 
     Scene scene = new Scene(root, 250, 400); 
     scene.getStylesheets().add(getClass().getResource("drag-and-drop-list.css").toExternalForm()); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

这将使您能够将任何元素并将它放到任何其他。例如拖动中的第三项列表

enter image description here

,并在此放弃它的第一项成果:

enter image description here

在Java 8,你也可以添加一行

db.setDragView(cell.snapshot(null, null)); 

setOnDragDetected(...)方法,以获得更好的拖动视觉。

+0

嗨,詹姆斯,我试过你的代码拖放不工作。请你给我一个明确的例子 – 2014-09-09 12:04:59

+0

我直接从我的IDE复制这个:它对我来说工作得很好。 “不工作”不是很有帮助。出了什么问题? – 2014-09-09 14:43:02

+0

嗨,詹姆斯,谢谢你的回复。我的要求是拖动列表中的第三个项目并将其放到第一个位置。我可以拖动第三个项目,但无法将其放到确切的位置,即列表中的第一个项目 – 2014-09-10 05:35:29