gpt4 book ai didi

java - 如何通过其图形拖动选项卡?

转载 作者:行者123 更新时间:2023-12-04 14:50:23 24 4
gpt4 key购买 nike

在这个最小的例子中,我们可以拖动标签来重新排序:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;


public class MainApp extends Application {

@Override
public void start(Stage stage) throws Exception {
TabPane tabPane = new TabPane();
tabPane.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);

Tab tab = new Tab("Tab");
tab.setGraphic(new Button("button"));
Tab tab2 = new Tab("Tab");
tab2.setGraphic(new Button("button"));

tabPane.getTabs().addAll(tab, tab2);

Scene scene = new Scene(tabPane);
tabPane.setPrefWidth(600);
tabPane.setPrefHeight(400);
stage.setScene(scene);
stage.show();
}

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

}

enter image description here

当鼠标悬停在选项卡名称上时我们可以开始拖动,但当鼠标悬停在按钮(选项卡图形)上时则不能。在这种情况下,按钮会阻止选项卡看到拖动事件。

我不能简单地设置 isMouseTransparant,因为这会阻止按钮记录自己的鼠标点击。

如何允许用户通过选项卡图形拖动选项卡,同时仍然能够通过单击与图形进行交互?

最佳答案

基于示例模式的解决方案

我建议实现重新排序模式。

当重新排序模式打开时,选项卡标题图形中的节点都被禁用,用户可以单击选项卡标题中的任意位置来拖动和重新排序关联的选项卡。在此期间,用户无法与禁用的图形节点进行交互。

当重新排序模式关闭时,选项卡标题图形中的节点全部启用。用户无法拖动选项卡对其重新排序,但它们可以与图形中的节点交互以执行其功能。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.Objects;

public class MainApp extends Application {

@Override
public void start(Stage stage) throws Exception {
TabPane tabPane = new TabPane();

Tab tab = new Tab("Tab");
tab.setGraphic(new Button("button"));
Tab tab2 = new Tab("Tab");
tab2.setGraphic(new Button("button"));

tabPane.getTabs().addAll(tab, tab2);

ToggleButton reorderModeToggle = new ToggleButton("Reorder Mode");
reorderModeToggle.selectedProperty().addListener((observable, wasSelected, isSelected) -> {
tabPane.getTabs().stream()
.map(Tab::getGraphic)
.filter(Objects::nonNull)
.forEach(graphic -> graphic.setDisable(isSelected));

tabPane.setTabDragPolicy(
isSelected
? TabPane.TabDragPolicy.REORDER
: TabPane.TabDragPolicy.FIXED
);
});

VBox layout = new VBox(10, reorderModeToggle, tabPane);
layout.setPadding(new Insets(10));

Scene scene = new Scene(layout);
tabPane.setPrefWidth(600);
tabPane.setPrefHeight(400);
stage.setScene(scene);
stage.show();
}

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

如果用户可以动态添加新选项卡,那么您还可以根据重新排序模式适本地初始化它们的禁用状态(或者您可以在 TabPane 中选项卡的列表更改监听器中执行此操作)。我没有为这个额外的可选额外步骤提供逻辑。

讨论为什么提供这种方法

我知道这不是您最初要求的,但这可能是您问题的合理解决方案。

试图使图形控制工作和选项卡的拖动功能也同时可用(对我来说)是非常有问题的,无论是在如何实现这个方面还是在行为方面用户应该期望发生。例如,按下鼠标时会触发按钮,但按下鼠标时也会开始选项卡标题的拖动事件,因此,如果按下标题中的按钮,是否也应该开始拖动事件?目前尚不清楚。

按钮的输入处理由 ButtonSkin 引用的 ButtonBehavior 中的 InputMap 类处理。两者都是非公共(public) API,因此很难尝试覆盖默认行为。私有(private) InputMap 类中有一些方法可以帮助决定按钮的行为是否应该消耗它对其采取行动(鼠标按下或按键)的事件(默认情况下它会)。因此,这可以通过安装您自己的皮肤来完成,复制(大量)私有(private) API 中的功能,并进行一些修改以提供您想要的自定义功能(但我根本不推荐这样做)。

我曾认为使用事件过滤器您将能够提供您所请求的原始功能,并且您可能能够做到这一点,但根据我的调查,这并不容易。

交替讨论

sorifiend 在评论中建议的替代解决方案也可能对您有用:

... option is to not use a button. Try with a label instead (Labels don't capture any events by default), or you could use custom graphics to render the tab header to look however you want, and then it will behave exactly as you want without a button.

或者,您可以放置​​每个选项卡的所有交互式节点正文,而不是将交互式图形放在标题中,只在标题中保留文本或静态图像,使它们始终可以重新排序。

关于java - 如何通过其图形拖动选项卡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69169175/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com