【发布时间】:2017-01-04 22:03:32
【问题描述】:
我已经看到很多关于如何将选项卡的选项卡拖到另一个选项卡的方法,顺便说一下,我没有明白这一点,我想它在某种程度上可能有用,但最自然的应用程序应该是重新排序同一选项卡的选项卡,似乎没有人在互联网上谈论这个问题。
我想要几乎所有浏览器都实现的行为。
我已经尝试了一些东西,但它并没有达到我想要的效果。主要问题来自Tab 不能与setOnDragDetected、setOnDragOver 等方法绑定(由于某种原因,顺便说一句……),这导致算法过于复杂,以弥补这一弱点图书馆。
所以这是我的代码,它没有做我想做的事情,因为(而且它只是一种解决方法)我只在放置后检测到“放置目标”,从而使其无用。是的,出于某种原因,在按住单击按钮的同时悬停对象不会导致mouseover 事件...
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class DragAndDrop extends Application
{
public void start(Stage primaryStage)
{
TabPane tabPane = new TabPane();
final int[] target = {0};
for(int i = 0 ; i < 2 ; i ++)
{
Tab tab = new Tab();
tab.setClosable(false);
int index[] = {i};
tabPane.getTabs().add(tab);
Label label = new Label("Tab " + (i + 1), new Rectangle(16, 16, Color.TRANSPARENT));
tab.setGraphic(label);
tab.getGraphic().setOnMouseEntered(event ->
{
target[0] = index[0];
System.out.println("target : " + target[0]);
});
}
tabPane.setOnDragDetected(event ->
{
Dragboard dragboard = tabPane.startDragAndDrop(TransferMode.ANY);
ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.putString(Integer.toString(tabPane.getSelectionModel().getSelectedIndex()));
System.out.println("source : " + tabPane.getSelectionModel().getSelectedIndex());
dragboard.setContent(clipboardContent);
event.consume();
});
tabPane.setOnDragOver(event ->
{
if(event.getDragboard().hasString())
{
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
});
tabPane.setOnDragDropped(event ->
{
Dragboard dragboard = event.getDragboard();
boolean success = false;
if(dragboard.hasString())
{
System.out.println("from " + dragboard.getString() + " to " + target[0]);
success = true;
}
event.setDropCompleted(success);
event.consume();
});
tabPane.setOnDragDone(event ->
{
if(event.getTransferMode() == TransferMode.MOVE)
{
// tabPane.setText("");
}
event.consume();
});
primaryStage.setScene(new Scene(tabPane, 300, 200));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
【问题讨论】:
-
您是否尝试过直接在选项卡图形上设置拖动处理程序?我认为这会使逻辑更清晰。在这种情况下,您不必依赖选择模型。
-
不幸的是,这在 javafx (see this post) 中尚不可用。虽然它很旧(请求链接适用于 javafx-2.x),但答案中的 webBlog 链接给出了一个很好的解释和一个关于如何实现目标的示例。
-
@James_D 我认为这不会改变任何问题,因为我仍然无法在第一个标签(来源)。
-
但目标选项卡将是图形(
dragDropped事件的源)所属的选项卡。您不需要任何额外的侦听器或逻辑来找到它。请参阅我发布的答案。 -
我建议先运行它,看看它是否提供了您正在寻找的功能。然后阅读代码,如果它符合您的要求。
标签: java events javafx tabs drag-and-drop