【问题标题】:How to hide TabPane content on Tab clicked in JavaFX如何在 JavaFX 中单击的选项卡上隐藏 TabPane 内容
【发布时间】:2018-02-10 09:02:15
【问题描述】:

这是一个代码:

package tabpane;

import javafx.application.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;

public class HideShowTabContentOnClicked extends Application {

    public static void main(String[] args) {

        launch(args);
    }

    private BorderPane createContent() {

        BorderPane borderPane = new BorderPane();

        TabPane tabPane = new TabPane();
        tabPane.setSide(Side.LEFT);

        StackPane stackPane = new StackPane();
        stackPane.setStyle("-fx-background-color: lightblue");
        stackPane.setMinWidth(200);

        Tab firstTab = new Tab("First");
        firstTab.setClosable(false);
        firstTab.setContent(stackPane);
        firstTab.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue) {
                firstTab.setContent(null);
            } else {
                firstTab.setContent(stackPane);
            }
        });

        Tab secondTab = new Tab("Second");
        StackPane stackPane2 = new StackPane();
        stackPane2.setStyle("-fx-background-color: yellow");
        secondTab.setContent(stackPane2);
        secondTab.setClosable(false);

        secondTab.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue) {
                secondTab.setContent(null);
            } else {
                secondTab.setContent(stackPane2);
            }
        });

        StackPane center = new StackPane();
        center.setStyle("-fx-background-color: cyan");

        borderPane.setCenter(center);

        tabPane.getTabs().addAll(firstTab, secondTab);
        borderPane.setLeft(tabPane);
        return borderPane;
    }

    @Override
    public void start(Stage stage) throws Exception {

        stage.setScene(new Scene(createContent()));
        stage.setMaximized(true);
        stage.show();
    }
}

在这里,我尝试通过将内容设置为 null 来使用 selectedProperty() 来解决问题,但它不起作用,我想让 Tab 像切换按钮一样,这样当我单击它时会显示并隐藏 TabPanes 内容。

之前

点击时

例如,我想实现 TabPane,例如 Intellij IDEA 工具按钮(如“项目”、“结构”工具按钮等)。

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    如果您要将内容保存到StackPane,可以将stackPane.visibleProperty()toggleButton.selectedProperty() 绑定:

    stackPane.visibleProperty()
                 .bind(Bindings.when(toggleButton.selectedProperty())
                               .then(false)
                               .otherwise(true)
                 );
    

    在此示例中:toggleButton.isSelected() --> !stackPane.isVisible()!toggleButton.isSelected() --> stackPane.isVisible(), 或收听ToggleButton的events

    // toggleButton.setOnAction(e ->{                      //new .setOnAction() -> Override previous
    toggleButton.addEventHandler(ActionEvent.ACTION, e ->{ //can add any quantity for your needs
            if(toggleButton.isSelected())
                 stackPane.setVisible(false);
            else stackPane.setVisible(true);
        });
    

    但问题是我想使用 Tab 而不是切换按钮,因此它的行为类似于切换按钮。即,当在我的示例代码中单击“第一个选项卡”时,如果内容可见,它应该是不可见的,反之亦然。我的意思是应该只显示标签

    我找到了解决方案。Tab 没有 click-handler... 但是

    Tab tab = new Tab();
    tab.setContent(stackPane);
    Label lable = new Label("Label");    //create Label
    tab.setGraphic(lable);               //set Lable as Graphic to Tab
    lable.setOnMouseClicked(event ->{    //setOnMouseClicked, for example
            if(stackPane.isVisible()){
                stackPane.setVisible(false);
            }else{
                stackPane.setVisible(true);
            }
    });
    

    ,您可以使用Label(例如)作为Tab-text 并将setOnMouseClicked()-handler 添加到Label。您可以将任何NodeHandler/ActionListener 一起使用->由您决定。

    例如,您可以使用CheckBox 显示/隐藏StackPaneTab 文本(可以结合FXMLJava-code 生成图形):

    Tab tab = new Tab("Tab2");          //Tab with Text
    tab.setContent(stackPane);          
    CheckBox checkBox = new CheckBox(); //create CheckBox 
    tab.setGraphic(checkBox);           //set CheckBox as Graphic to Tab
    stackPane.visibleProperty()
                .bind(Bindings.when(checkBox.selectedProperty())
                        .then(false)
                        .otherwise(true)
                );
    

    @FXML
    private Tab tab;
    // ...
    tab.setGraphic(checkBox); 
    // ...
    

    【讨论】:

    • 但问题是我想使用 Tab 而不是切换按钮,因此它的行为类似于切换按钮。即,当在我的示例代码中单击“第一个选项卡”时,如果内容可见,它应该是不可见的,反之亦然。我的意思是应该只显示标签
    • 请更新。如果我的回答让你满意,请设置为the best))))
    • 我喜欢你的热情,但不幸的是这不是我想要的。我知道该选项卡具有设置图形的功能,并且我也知道如何使用绑定。如果我想在选项卡上设置一个图标怎么办?!此外,在我的情况下,这不是可见性问题。因为即使您使堆栈窗格不可见,TabPane 内容仍然可见。
    【解决方案2】:

    我想出了这个解决方案:

    AtomicReference<Tab> currentTab = new AtomicReference<>(tabPane.getSelectionModel().getSelectedItem());
    AtomicReference<Tab> lastTab = new AtomicReference<>(null);
    tabPane.setOnMouseReleased(event -> {
        // Check if current node is actually tab
        Node n = event.getPickResult().getIntersectedNode();
        while (n != null && !(n.getStyleClass().contains("headers-region"))) {
            n = n.getParent();
        }
        if (n == null)
            return;
    
        lastTab.set(currentTab.get());
        currentTab.set(tabPane.getSelectionModel().getSelectedItem());
    
        if (currentTab.get() == lastTab.get()) {
            // Hide
            tabPane.setPrefSize(28, 28);
            //tabPane.getSelectionModel().clearSelection(); // notify selection model
            currentTab.set(null);
        } else {
            // Show
            tabPane.setPrefSize(-1,-1);
            currentTab.set(tabPane.getSelectionModel().getSelectedItem());
        }
    });
    

    首先,我在 tabPane 中添加了鼠标事件。在此鼠标事件中,检查光标下的节点是否实际上是 Tab 节点。如果是,请执行一些逻辑来识别用户正在尝试执行的操作:隐藏或显示。隐藏有点棘手,所以我最终将 TabPane 的首选大小设置为 28 px 宽。

    我也尝试用空的 newValue 通知选择模型:

    tabPane.getSelectionModel().clearSelection();
    

    但这不能正常工作。调用select(-1) 应该调用clearSelection(),但行为有所不同。

    当我在调用clearSelection() 后选择另一个选项卡时,选择模型处理程序使用oldValue == null 调用,这可能不会更新内部索引并且选项卡不会切换到选定的一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2019-04-11
      • 1970-01-01
      • 2011-10-17
      相关资源
      最近更新 更多