【问题标题】:Replace TabPane with separate scenes (JAVAFX)用单独的场景替换 TabPane (JAVAFX)
【发布时间】:2017-04-19 14:48:05
【问题描述】:

目前我有带有 3 个活动标签的 TabPane。我必须在它们之间手动切换,这并不理想。我想做的是将TabPane全部替换并在舞台内有一个场景,然后按下按钮切换到下一个场景(从Tab1到Tab2到Tab3)。

维护设置标签文本功能很重要。

Tab1

Tab2

Main.java

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("../view/Main.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


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

MainController.java

package controller;

import javafx.fxml.FXML;
import controller.tab.Tab1Controller;
import controller.tab.Tab2Controller;
import controller.tab.Tab3Controller;

public class MainController {

    @FXML Tab1Controller tab1Controller;
    @FXML Tab2Controller tab2Controller;
    @FXML Tab3Controller tab3Controller;

    public void initialize() {
        tab1Controller.init(this);
        tab2Controller.init(this);
        tab3Controller.init(this);
    }

    public void setTab2LabelText(String text) {

        tab3Controller.lbl3.setText(text);
        tab2Controller.lbl2.setText(text);
    }
}

Tab1Controller.java

package controller.tab;

import controller.MainController;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

import java.io.IOException;

public class Tab1Controller {

    private MainController main;

    @FXML public Label lbl1;
    @FXML private Button btn1Send;

    @FXML private void btn1SendClicked(ActionEvent event) throws IOException {
        main.setTab2LabelText("abc");
    }

    public void init(MainController mainController) {
        main = mainController;
    }
}

Tab2Controller.java

package controller.tab;

import controller.MainController;
import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class Tab2Controller {

    private MainController main;

    @FXML public Label lbl2;

    public void init(MainController mainController) {
        main = mainController;
    }
}

Tab3Controller.java

package controller.tab;

import controller.MainController;
import javafx.fxml.FXML;
import javafx.scene.control.Label;


public class Tab3Controller {

    private MainController main;

    @FXML public Label lbl3;

    public void init(MainController mainController) {
        main = mainController;
    }

}

Main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="432.0" prefWidth="443.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
    <children>
        <TabPane prefHeight="299.0" prefWidth="309.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <tabs>
                <Tab closable="false" text="Tab 1">
                    <content>
                        <fx:include fx:id="tab1" source="tab/Tab1.fxml" />
                    </content></Tab>
                <Tab closable="false" text="Tab 2">
                    <content>
                        <fx:include fx:id="tab2" source="tab/Tab2.fxml" />
                    </content></Tab>
                <Tab closable="false" text="Tab 3">
                    <content>
                        <fx:include fx:id="tab3" source="tab/Tab3.fxml" />
                    </content></Tab>
            </tabs>
        </TabPane>
    </children>
</AnchorPane>

Tab2.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="206.0" prefWidth="226.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.tab.Tab1Controller">
    <children>
        <Button fx:id="btn1Send" layoutX="42.0" layoutY="74.0" mnemonicParsing="false" onAction="#btn1SendClicked" prefHeight="58.0" prefWidth="142.0" text="Send to Tab2 &amp; Tab3" />
    </children>
</AnchorPane>

Tab2.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="206.0" prefWidth="226.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.tab.Tab2Controller">
    <children>
        <Label fx:id="lbl2" alignment="CENTER" layoutX="37.0" layoutY="46.0" prefHeight="17.0" prefWidth="152.0" text="Default Tab2 text" />
    </children>
</AnchorPane>

Tab3.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="206.0" prefWidth="226.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.tab.Tab3Controller">
    <children>
        <Label fx:id="lbl3" alignment="CENTER" layoutX="37.0" layoutY="46.0" prefHeight="17.0" prefWidth="152.0" text="Default Tab3 text" />
    </children>
</AnchorPane>

【问题讨论】:

    标签: java javafx controller javafx-8 tabpanel


    【解决方案1】:

    这是一个例子

    fxml

    创建 3 个窗格,带有自己的按钮和标签

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane id="AnchorPane" prefHeight="380.0" prefWidth="387.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ask.FXMLDocumentController">
       <children>
          <Pane fx:id="p3" prefHeight="380.0" prefWidth="387.0" visible="false">
             <children>
                <Label layoutX="184.0" layoutY="181.0" text="p3" />
                <Button fx:id="p3previous" layoutX="152.0" layoutY="225.0" mnemonicParsing="false" text="previous" />
             </children>
          </Pane>
          <Pane fx:id="p2" prefHeight="380.0" prefWidth="387.0" visible="false">
             <children>
                <Label layoutX="184.0" layoutY="181.0" text="p2" />
                <Button fx:id="p2previous" layoutX="78.0" layoutY="255.0" mnemonicParsing="false" text="previous" />
                <Button fx:id="p2next" layoutX="239.0" layoutY="255.0" mnemonicParsing="false" text="next" />
             </children>
          </Pane>
          <Pane fx:id="p1" prefHeight="380.0" prefWidth="387.0">
             <children>
                <Button fx:id="p1next" layoutX="167.0" layoutY="210.0" mnemonicParsing="false" text="next" />
                <Label layoutX="184.0" layoutY="181.0" text="p1" />
             </children>
          </Pane>
       </children>
    </AnchorPane>
    

    控制器

    添加按钮动作事件,使用setVisible(boolean) 控制应该显示哪个窗格。

    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.layout.Pane;
    
    public class FXMLDocumentController implements Initializable {
    
        @FXML Pane p1;
        @FXML Pane p2;
        @FXML Pane p3;
        @FXML Button p1next;
        @FXML Button p2next;
        @FXML Button p2previous;
        @FXML Button p3previous;
    
        public void initialize(URL url, ResourceBundle rb) 
        {
            p1next.setOnAction(e->{ p1.setVisible(false); p2.setVisible(true); });
            p2next.setOnAction(e->{ p2.setVisible(false); p3.setVisible(true); });
            p2previous.setOnAction(e->{ p2.setVisible(false); p1.setVisible(true); });
            p3previous.setOnAction(e->{ p3.setVisible(false); p2.setVisible(true); });
        }  
    }
    

    【讨论】:

    • 您好,感谢您的意见。您是否也知道我如何为每个单独的窗格添加@FXML 文件,或者有更好的方法来编辑p1p2p3
    • 这可能会有所帮助。 stackoverflow.com/questions/22161586/…
    • @Elion 请检查 fabian 的答案
    • @TomN 是的,感谢你们俩。我希望我能发出不止一个绿色勾号!结案。 ^.^
    【解决方案2】:

    您不需要将在 fxml 文件中创建的所有内容都添加到场景中。 &lt;fx:define&gt; 标签可用于创建不属于物体场景的Node(目前)。使用合适的Parent,让您可以正确显示内容。

    示例:

    <StackPane fx:id="container" prefHeight="432.0" prefWidth="443.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
        <children>
            <fx:include fx:id="tab1" source="tab/Tab1.fxml" />
            <fx:define>
                <fx:include fx:id="tab2" source="tab/Tab2.fxml" />
                <fx:include fx:id="tab3" source="tab/Tab3.fxml" />
            </fx:define>
        </children>
    </StackPane>
    
    public class MainController {
    
        @FXML private Tab1Controller tab1Controller;
        @FXML private Tab2Controller tab2Controller;
        @FXML private Tab3Controller tab3Controller;
    
        @FXML private Node tab1;
        @FXML private Node tab2;
        @FXML private Node tab3;
    
        @FXML private StackPane container;
    
        public void initialize() {
            tab1Controller.init(this);
            tab2Controller.init(this);
            tab3Controller.init(this);
        }
    
        public void setTab2LabelText(String text) {
            tab3Controller.lbl3.setText(text);
            tab2Controller.lbl2.setText(text);
        }
    
        public void toTab2() {
            container.getChildren().setAll(tab2);
        }
    }
    

    【讨论】:

    • 谢谢!解决了这个问题。 ^.^
    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    相关资源
    最近更新 更多