Ошибка переупорядочения JavaFX TabPane, поиск обходного пути - PullRequest
1 голос
/ 12 января 2020

Я обнаружил небольшую ошибку в JavaFX TabPane и ищу обходной путь. Я использую JavaFX 13.0.1.

Как это происходит:

DragPolicy TabPane должен быть установлен на TabPane.TabDragPolicy.REORDER.

Вы можете перемещаться между вкладками с помощью сочетаний клавиш CTRL + TAB & CTRL + SHIFT + TAB.

Однако, если я перетащу, скажем, последнюю вкладку в крайнее левое положение и верну ее в положение, в котором она находилась (чтобы ничего не изменилось), эти сочетания клавиш испорчены - больше не указывают на правильные следующие / предыдущие вкладки.

Вы сможете воспроизвести его просто с помощью следующего кода:

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

public class Test extends Application {

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

        tabPane.getTabs().add(new Tab("First"));
        tabPane.getTabs().add(new Tab("Second"));
        tabPane.getTabs().add(new Tab("Third"));
        tabPane.getTabs().add(new Tab("Fourth"));
        tabPane.getTabs().add(new Tab("Fifth"));

        StackPane root = new StackPane();
        root.getChildren().add(tabPane);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("TabPane bug");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

1 Ответ

1 голос
/ 12 января 2020

интересный баг. Похоже, TabPane.getTabs () возвращает список, который может отражать или не отражать визуальный порядок вкладок. Но навигационные клавиши всегда полагаются на порядок getTabs (), а не на визуальный порядок.

Один из обходных путей - использовать метку в качестве графика c для каждой вкладки, оставляя текст вкладки равным нулю. Затем вы можете сами правильно отсортировать вкладки, проверив визуальное положение каждой такой метки.

import java.util.List;
import java.util.ArrayList;

import javafx.beans.Observable;
import javafx.geometry.Bounds;
import javafx.geometry.NodeOrientation;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TabDragTest2 extends Application {

    private static Tab createTab(String title) {
        Tab tab = new Tab();
        tab.setGraphic(new Label(title));
        return tab;
    }

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

        tabPane.getTabs().add(createTab("First"));
        tabPane.getTabs().add(createTab("Second"));
        tabPane.getTabs().add(createTab("Third"));
        tabPane.getTabs().add(createTab("Fourth"));
        tabPane.getTabs().add(createTab("Fifth"));

        tabPane.getTabs().addListener((Observable o) -> {
            List<Tab> tabs = new ArrayList<>(tabPane.getTabs());

            NodeOrientation orientation = tabPane.getEffectiveNodeOrientation();
            boolean ltr = orientation == NodeOrientation.LEFT_TO_RIGHT;

            tabs.sort((t1, t2) -> {
                Node title1 = t1.getGraphic();
                Node title2 = t2.getGraphic();
                Bounds title1Bounds =
                    title1.localToScene(title1.getLayoutBounds());
                Bounds title2Bounds =
                    title2.localToScene(title2.getLayoutBounds());

                if (tabPane.getSide().isHorizontal()) {
                    if (ltr) {
                        return Double.compare(
                            title1Bounds.getMinX(), title2Bounds.getMinX());
                    } else {
                        return Double.compare(
                            title2Bounds.getMaxX(), title1Bounds.getMaxX());
                    }
                } else {
                    return Double.compare(
                        title1Bounds.getMinY(), title2Bounds.getMinY());
                }
            });

            if (!tabPane.getTabs().equals(tabs)) {
                Platform.runLater(() -> tabPane.getTabs().setAll(tabs));
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(tabPane);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("TabPane bug");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...