2017-02-25 122 views
0

我有一个javafx应用程序,其中包含一个单独的窗格内的多个按钮。为了使按钮可拖动,我已将每个按钮放在单独的窗格中。用户可以从任何一个窗格中选择任何按钮,然后将其拖放到任何其他窗格上。例如,从窗格1获取按钮并将其拖放到窗格5内部。JavaFX从一个窗格拖动到另一个窗口

由于先前未知用户将选择哪个按钮,因此我认为它必须先以某种方式添加到拖动板,所以它可以从setOnDragDropped操作的拖拽板中检索。

我能拖,并通过使用拖放imageviews之间的图像:

Dragboard db = iv_1.startDragAndDrop(TransferMode.MOVE); 
    ClipboardContent content = new ClipboardContent(); 
    content.putImage(iv_1.getImage()); 

但我不能想出一个办法,以一个按钮添加到dragboard,因为没有具体的可供选择,只选项似乎并不适用,content.putText或content.putString()...

任何帮助,将不胜感激。这是我到目前为止有:

private void btn_1_setOnDragDetected(MouseEvent event) { 

    Dragboard db = btn_1.startDragAndDrop(TransferMode.MOVE); 
    ClipboardContent content = new ClipboardContent(); 
    // below seems to be wrong 
    content.put(dataFormat,btn_1.toString()); 
    db.setContent(content); 

    event.consume(); 
} 


private void btn_1_setOnDragOver(DragEvent event) { 

    if (event.getGestureSource() != btn_1 && 
      event.getDragboard().hasString()) { 
     event.acceptTransferModes(TransferMode.MOVE); 
    } 
    event.consume(); 
} 


private void pane_5_setOnDragDropped(DragEvent event) { 

    Dragboard db = event.getDragboard(); 
    boolean success = false; 
    if (db.hasString()) { 
     // below must be wrong 
     pane_5.setId(db.getString()); 
     success = true; 
    } 
    event.setDropCompleted(success); 
    event.consume(); 
    } 
+0

仅仅抛出的想法。你可以复制按钮的重要细节,并在该位置的拖动释放上创建一个新按钮。然后使用细节来确定按钮功能? – Sedrick

+0

'setId'不会将按钮添加到窗格。查看java [documentation](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#getId--)。 – theKidOfArcrania

+0

['startFullDrag'](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#startFullDrag--)+使用['MouseDragEvent.getGestureSource'](https:/ /docs.oracle.com/javase/8/javafx/api/javafx/scene/input/MouseDragEvent.html#getGestureSource--)。顺便说一句,用“Dragboard”转储这个想法。将'Button'拖到应用程序外的某处并不合适,但“Dragboard”用于独立于源应用程序拖动数据... – fabian

回答

2

有没有办法将一个按钮添加到剪贴板中的内容(即在dragboard)。你只能添加特定的类型(字符串,图像)和实现可序列化的对象(按钮没有,它不会做你想要的东西)。拖放API在这方面非常不足,即imho。您应该只在拖拽板上添加一些虚拟文本并保留对当前正在拖动的按钮的引用。

快速SSCCE:

import javafx.application.Application; 
import javafx.geometry.Orientation; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.SplitPane; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.DataFormat; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.TransferMode; 
import javafx.scene.layout.FlowPane; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class DragAndDropButton extends Application { 

    private final DataFormat buttonFormat = new DataFormat("com.example.myapp.formats.button"); 

    private Button draggingButton ; 

    @Override 
    public void start(Stage primaryStage) { 
     FlowPane pane1 = new FlowPane(); 
     FlowPane pane2 = new FlowPane(); 

     for (int i = 1 ; i <= 10; i++) { 
      pane1.getChildren().add(createButton("Button "+i)); 
     } 

     addDropHandling(pane1); 
     addDropHandling(pane2); 

     SplitPane splitPane = new SplitPane(pane1, pane2); 
     splitPane.setOrientation(Orientation.VERTICAL); 

     Scene scene = new Scene(splitPane, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private Button createButton(String text) { 
     Button button = new Button(text); 
     button.setOnDragDetected(e -> { 
      Dragboard db = button.startDragAndDrop(TransferMode.MOVE); 
      db.setDragView(button.snapshot(null, null)); 
      ClipboardContent cc = new ClipboardContent(); 
      cc.put(buttonFormat, "button"); 
      db.setContent(cc); 
      draggingButton = button ; 
     }); 
     button.setOnDragDone(e -> draggingButton = null); 
     return button ; 
    } 

    private void addDropHandling(Pane pane) { 
     pane.setOnDragOver(e -> { 
      Dragboard db = e.getDragboard(); 
      if (db.hasContent(buttonFormat) 
        && draggingButton != null 
        && draggingButton.getParent() != pane) { 
       e.acceptTransferModes(TransferMode.MOVE); 
      } 
     }); 

     pane.setOnDragDropped(e -> { 
      Dragboard db = e.getDragboard(); 
      if (db.hasContent(buttonFormat)) { 
       ((Pane)draggingButton.getParent()).getChildren().remove(draggingButton); 
       pane.getChildren().add(draggingButton); 
       e.setDropCompleted(true); 
      }   
     }); 
    } 

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

完美工作,许多谢谢 .... – rainer

相关问题