gpt4 book ai didi

java - 在 JavaFx 8 TabPane 标题中显示所选选项卡前面的一些选项卡

转载 作者:搜寻专家 更新时间:2023-10-31 20:10:29 28 4
gpt4 key购买 nike

我正在尝试修改 JavaFx 8 中的 TabPage 控件,使其向视口(viewport)显示当前所选选项卡前面(右侧)的一些选项卡,或者所选选项卡是否位于标题的最左侧, 它会在当前选项卡之前显示附近的选项卡。

现在怎么样了:

Default behaviour

我是如何让它表现得像这样的:

When the user selects the tab of index X, the tab pane header reveals another 2 or 3 nearby tabs.

当用户选择索引 X 的选项卡时,选项卡 Pane 标题会显示另外 2 或 3 个附近的选项卡。

这是我到目前为止尝试的方法,但没有成功,显然下面的代码太快了,无法使界面线程按时同步选项卡选择(我的想法是先选择一个选项卡,然后回退到由用户,使标题显示所选选项卡之后的选项卡):

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;

public class TabSelectionListener implements ChangeListener<Tab> {

protected TabPane owner;
protected boolean lock;
protected int nextItems;

TabSelectionListener(TabPane listenTo){
owner = listenTo;
lock = false;
nextItems = 2;
}

TabSelectionListener(TabPane listenTo, int minimalInFront){
owner = listenTo;
lock = false;
nextItems = minimalInFront;
}

@Override
public void changed(ObservableValue<? extends Tab> list, Tab old, Tab newT) {
int maxTab;
int curTab;
int i;

// Locks this listener, because the selections owner.getSelectionModel().select(X)
// will call this listener again, and we are calling those from here.
if(!lock){
lock = true;
maxTab = owner.getTabs().size() - 1;
curTab = owner.getSelectionModel().getSelectedIndex();

for(i = 0; i < nextItems && curTab + i < maxTab; i++);
owner.getSelectionModel().select(i); // int overload
owner.getSelectionModel().select(newT);

lock = false;
}
}
}

tabPane 为每个选项卡选择调用它:

tabPane.getSelectionModel().selectedItemProperty().addListener(new TabSelectionListener(tabPane,3));

我在这里阅读了一些主题,在我看来,标题实际上是一个 StackPane,可以通过执行以下命令获得:

StackPane region = (StackPane) tabPane.lookup(".headers-region");

它有效,但在那之后我不知道如何访问实现默认行为的属性。

有什么建议吗?

感谢阅读。

最佳答案

我终于做到了。

发现我正在寻找的类是 com.sun.javafx.scene.control.skin.TabPaneSkin @ jfxrt.jar,它有一种方法可以使所选选项卡可见,每次在 TabPane 中选择一个选项卡时它都会运行不完全可见,我覆盖了它。

TabPaneSkin 是TabPane 的默认皮肤,它将一些行为应用于TabPane 控件。

/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*

希望甲骨文不要介意...

选择您的 TabPane,然后...

tabPane.setSkin(new TabPaneNewSkin(tabPane));

...用我写的显示附近选项卡的这个覆盖 Oracle 的默认 TabPaneSkin。

原始 Oracle 的代码,用于在选择一个选项卡以使其可见时重新定位选项卡:

    private void ensureSelectedTabIsVisible() {
// work out the visible width of the tab header
double tabPaneWidth = snapSize(isHorizontal() ? getSkinnable().getWidth() : getSkinnable().getHeight());
double controlTabWidth = snapSize(controlButtons.getWidth());
double visibleWidth = tabPaneWidth - controlTabWidth - firstTabIndent() - SPACER;

// and get where the selected tab is in the header area
double offset = 0.0;
double selectedTabOffset = 0.0;
double selectedTabWidth = 0.0;
for (Node node : headersRegion.getChildren()) {
TabHeaderSkin tabHeader = (TabHeaderSkin)node;

double tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));

if (selectedTab != null && selectedTab.equals(tabHeader.getTab())) {
selectedTabOffset = offset;
selectedTabWidth = tabHeaderPrefWidth;
}
offset += tabHeaderPrefWidth;
}

final double scrollOffset = getScrollOffset();
final double selectedTabStartX = selectedTabOffset;
final double selectedTabEndX = selectedTabOffset + selectedTabWidth;

final double visibleAreaEndX = visibleWidth;

if (selectedTabStartX < -scrollOffset) {
setScrollOffset(-selectedTabStartX);
} else if (selectedTabEndX > (visibleAreaEndX - scrollOffset)) {
setScrollOffset(visibleAreaEndX - selectedTabEndX);
}
}

我写入自定义 TabPane 皮肤的代码:

    // This function was overwritten
private void ensureSelectedTabIsVisible() {
// work out the visible width of the tab header
double tabPaneWidth = snapSize(isHorizontal() ? getSkinnable().getWidth() : getSkinnable().getHeight());
double controlTabWidth = snapSize(controlButtons.getWidth());
double visibleWidth = tabPaneWidth - controlTabWidth - firstTabIndent() - SPACER;


// and get where the selected tab is in the header area
double offset = 0.0;
double selectedTabOffset = 0.0;
double selectedTabWidth = 0.0;

// OVERWRITE
// Makes the nearby 3 tabs for each side of the selected tab visible.
ObservableList<Node> headersRegionChildren = headersRegion.getChildren();
boolean nextTabs = false;
int nextTabsCount = 0;
int current = 0;
int numOfTabsToShowNext = 3;
int numOfTabsToShowBefore = 3;
double tabHeaderPrefWidth;
TabHeaderSkin tabHeader;

for (Node node : headersRegionChildren) {
tabHeader = (TabHeaderSkin)node;

tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));

if (selectedTab != null && selectedTab.equals(tabHeader.getTab())) {
selectedTabWidth = tabHeaderPrefWidth;

// OVERWRITE: Finds the offset of the first tab in the limit numOfTabsToShowBefore before the selected one to be shown
for(int i = current - 1; i >= 0 && numOfTabsToShowBefore > 1; i--, numOfTabsToShowBefore--){
tabHeader = (TabHeaderSkin)headersRegionChildren.get(i);
tabHeaderPrefWidth = snapSize(tabHeader.prefWidth(-1));
offset -= tabHeaderPrefWidth;
selectedTabWidth += tabHeaderPrefWidth;
}

selectedTabOffset = offset;
// OVERWRITE: Sets the flag to start counting in the next 3 nearby tabs.
nextTabs = true;
}
// OVERWRITE: Sums the width of the next nearby tabs with the
// width of the selected tab, so it will scroll enough to show
// them too.
if(nextTabs && nextTabsCount < numOfTabsToShowNext){
selectedTabWidth += tabHeaderPrefWidth;
nextTabsCount++;
}else if(nextTabsCount == numOfTabsToShowNext){
break;
}

offset += tabHeaderPrefWidth;
current++;
}
// END OVERWRITE

final double scrollOffset = getScrollOffset();
final double selectedTabStartX = selectedTabOffset;
final double selectedTabEndX = selectedTabOffset + selectedTabWidth;

final double visibleAreaEndX = visibleWidth;

if (selectedTabStartX < -scrollOffset) {
setScrollOffset(-selectedTabStartX);
} else if (selectedTabEndX > (visibleAreaEndX - scrollOffset)) {
setScrollOffset(visibleAreaEndX - selectedTabEndX);
}
}

对于每个选项卡选择,上面的代码会在所选选项卡的每一侧显示 3 个最近的选项卡(如果其中一个在屏幕之外并且存在)。

原来如此。 com.sun.javafx.scene.control.skin.TabPaneSkin本来就不应该扩展的,几乎每个方法都是私有(private)的,所以我复制了一份,只改了上面提到的功能,改名为TabPaneNewSkin,就这样了在我的包裹里。

关于java - 在 JavaFx 8 TabPane 标题中显示所选选项卡前面的一些选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31734292/

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