我尝试使用JavaFX实现从ListView拖放项目。除了onDragDrop之外,所有处理程序都可以工作,例如onDragDetected,onDragEnter。
有toolbax.fxml,它有listView,它包含在main.fxml中。
以下是我的代码部分:
toolbax.fxml:
<ListView fx:id="source" layoutX="-9.0" prefHeight="200.0" prefWidth="200.0">
<items>
<FXCollections fx:factory="observableArrayList" >
<HBox onDragDetected="#handleDragDetected" onDragDone="#handleDragDone" >
<children>
<ImageView>
<image>
<Image requestedHeight="40" requestedWidth="40" url="@/resources/computer.png" />
</image>
</ImageView>
<Text text="Host" />
</children>
</HBox>
<HBox>
<children>
<ImageView>
<image>
<Image requestedHeight="40" requestedWidth="40" url="@/resources/server.png" />
</image>
</ImageView>
<Text text="Server" />
</children>
</HBox>
</FXCollections>
</items>
</ListView>
toolbaxController:
public class ToolboxController {
@FXML
private ListView<FXCollections> source;
public static DataFormat dataFormat = new DataFormat("myCell");
@FXML
private void handleDragDetected(MouseEvent event)
{
System.out.println("onDragDetected");
Dragboard db=source.startDragAndDrop(TransferMode.MOVE);
int id=source.getSelectionModel().getSelectedIndex();
ClipboardContent content = new ClipboardContent();
content.put(dataFormat,id);
db.setContent(content);
event.consume();
}
@FXML
void handleDragDone(DragEvent event)
{
System.out.println("onDragDone");
if(event.getTransferMode()==TransferMode.MOVE)
{
// source
}
event.consume();
}
}
main.fxml:
<center>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ImageView onDragDropped="#handleDragDrop" onDragEntered="#handleDragEntered" onDragExited="#handleDragExited" onDragOver="#handleDragOver" fx:id="target" fitHeight="253.0" fitWidth="320.0" layoutX="42.0" layoutY="80.0" pickOnBounds="true" preserveRatio="true" />
</children></AnchorPane>
mainController:
public class MainController {
@FXML
private ImageView target;
@FXML
void handleDragOver(DragEvent event)
{
System.out.println("onDragOver");
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
target.setStyle("-fx-background-color: aqua");
/* allow for both copying and moving, whatever user chooses */
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
}
@FXML void handleDragEntered(DragEvent event)
{
System.out.println("onDragEntered");
if (event.getGestureSource() != target &&
event.getDragboard().hasString()) {
target.setStyle("-fx-background-color:brown");
}
event.consume();
}
@FXML
void handleDragExited(DragEvent event)
{
System.out.println("onDragExited");
target.setStyle("-fx-background-color:darkblue");
event.consume();
}
@FXML
public void handleDragDrop(DragEvent event)
{
System.out.println("onDragDrop");
Object obj;
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasContent(ToolboxController.dataFormat) ){
obj=db.getContent(ToolboxController.dataFormat);
success = true;
System.out.println("onDragDrop");
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
}
以及我在ImageView上从ListView拖动项目时的输出:
onDragDetected
onDragEntered
onDragOver
onDragOver
onDragOver
onDragOver
onDragExited
这意味着handleDragDrop不会执行。我想也许问题是目标,我的意思是目标不能是AnchorPane或ImageView。
答案 0 :(得分:0)
最后,我找到了Ansewer,它是如此愚蠢:),当你使用onDragExited处理程序时,你的OnDragDrop处理程序不会执行。所以你应该选择你想要使用的那个。