2016-05-15 89 views
0

我使用FXML和Scene Builder一起開發了一個非常簡單的界面。下面,第一個圖像表示佈局層次結構。第二個圖像在按下按鈕時顯示一個文本區域。JavaFX場景生成器 - 父節點之間的拖放

action事件方法實例化一個新的文本區域並將其分配給第一個流程窗格(從左到右)。我的目標是將每個文本區域拖放到任何其他流程窗格中。

我第一次嘗試是使用分配使用事件處理程序來檢測MOUSE_PRESSED:textArea.addEventHandler(MouseEvent.DRAG_DETECTED, e-> handle(e));

當我到設置在手柄的方法,事情變得撲朔迷離。例如,我應該包含其他各種MouseEvent,例如MOUSE_EXITED_TARGET,MOUSE_ENTERED_TARGET? MOUSE_RELEASED句柄是如何組成的?

我開始看着Dragboard和剪貼板,也沒有發現太多運氣。剪貼板似乎只能處理字符串值,或者以一種迂迴的方式處理圖像。我確信對我的困境有一個簡單的答案,因爲它清楚地表明我在未知的領域內四處探索。我已經閱讀了幾本「教科書」資源,但它們都涉及在運行時構建的對象的移動,並且大部分符合似乎是通用或直接示例的對象。

備註 我對圖像表示歉意,我意識到它並不十分清楚。在網格窗格中分佈有5個流程窗格。我會盡快編輯並更新它。

initial interface hierarchy after button is pressed

回答

1

所以我理解你想拖放TextAreas不同FlowPanes。您可以通過使用DragEvents而不是MouseEvents來實現此目的。這裏有一個例子:

考慮一個簡單的佈局像你這樣的,只取TextArea和兩個FlowPanes考慮,我們就會有以下字段:

@FXML 
private TextArea textArea; 

@FXML 
private FlowPane flowPane1; 

@FXML 
private FlowPane flowPane2; 

一開始,textArea位於flowPane1,在GridLayout的左側。

TextArea on left grid

我們想拖放'textArea'向右flowPane。所以首先,我們必須告訴textArea它應該是可拖動的。在這種情況下,移動。你可以用不同的方式實現它,但是在這裏我會告訴你只需將現有TextArea移動到另一個FlowPane。另一種方法是重新創建一個文本。

textArea.setOnDragDetected((MouseEvent event) -> { 
    //We want the textArea to be dragged. Could also be copied. 
    Dragboard db = textArea.startDragAndDrop(TransferMode.MOVE); 

    // Put a string on a dragboard as an identifier 
    ClipboardContent content = new ClipboardContent(); 
    content.putString(textArea.getId()); 
    db.setContent(content); 

    //Consume the event 
    event.consume(); 
}); 

然後,我們希望flowPane2接受textArea當它被拖到。所以首先,我們告訴它在被拖動時接受textArea。

flowPane2.addEventHandler(DragEvent.DRAG_OVER, (DragEvent event) -> { 
    if (event.getGestureSource() != flowPane2 
      && event.getDragboard().hasString()) { 
     event.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
    } 
    event.consume(); 
}); 

在我們允許它被拖拽之後,我們確實希望它實際上做了某些事情並在丟棄時接受它。所以我們添加另一個處理程序來接受掉落的textArea

flowPane2.addEventHandler(DragEvent.DRAG_DROPPED, (DragEvent event) -> { 
    //Get the dragboard back 
    Dragboard db = event.getDragboard(); 
    boolean success = false; 
    //Could have some more thorough checks of course. 
    if (db.hasString()) { 
     //Get the textarea and place it into flowPane2 instead 
     flowPane2.getChildren().add(textArea); 
     success = true; 
    } 
    //Complete and consume the event. 
    event.setDropCompleted(success); 
    event.consume(); 
}); 

的結果,textArea可以移動從flowPane1flowPane2。反之亦然,但這會讓你走!

Dragged textArea

+0

我想我對此有更清楚的瞭解你的閱讀響應後,所以謝謝!你能解釋方法/ eventHandlers需要位於何處嗎? – wellington

+0

這可能取決於你在哪裏創建它們。由於您通過按鈕創建了textArea,因此您可以在此處連接eventHandler。在這個例子中,我剛剛使用'initialize(URL,ResourceBundle)',它由'Controller'中的'Initializable'繼承。所以它在初始化時連線。 – Jaims