2017-02-25 128 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

相關問題