JavaFX应用程序:在赢得的窗格和#x27;t加载集内容

JavaFX应用程序:在赢得的窗格和#x27;t加载集内容,java,user-interface,javafx,fxml,Java,User Interface,Javafx,Fxml,我有带侧菜单栏的桌面应用程序。主窗口是BorderPane,其中InsertLeft包含VBox。我设置了Hbox按钮及其行为,然后将它们逐个添加到VBoxInsertCenter只有一个包含大量元素的窗格 我为每个GUI布局创建了3个fxml文件 sample.fxml-边框窗格:InsertLeft->Menu(VBox),InsertCenter->Empty窗格 tab1_content.fxml-填充进度条、标签和按钮的窗格 tab2_content.fxml-尚未实现(空窗格)

我有带侧菜单栏的桌面应用程序。主窗口是
BorderPane
,其中
InsertLeft
包含
VBox
。我设置了
Hbox按钮及其行为,然后将它们逐个添加到
VBox
InsertCenter
只有一个包含大量元素的
窗格

我为每个GUI布局创建了3个fxml文件

  • sample.fxml-边框窗格:InsertLeft->Menu(VBox),InsertCenter->Empty窗格
  • tab1_content.fxml-填充进度条、标签和按钮的窗格
  • tab2_content.fxml-尚未实现(空窗格)
每个fxml文件都有自己的控制器

我想切换菜单按钮上sample.fxml中borderPane.center()的内容

我已经设法解决了一些问题,但主要问题是将数据加载到.fxml视图中

当我运行我的应用程序时,它工作得非常好,每个fxml文件都有自己的FXMLLoader,它将内容加载到主控制器内部的borderPane中

public void setDefaultViewProperties(){
    myController.tab1Controller.actualPath.textProperty().bind(currentScanningFileProperty);
    myController.tab1Controller.numOfScanned.textProperty().bind(fileCounterProperty.asString());
    myController.tab1Controller.numOfMaliciousFiles.textProperty().bind(maliciousFilesCounterProperty.asString());
}
单击按钮时出现问题。它将切换窗格,但实际内容将重置为默认状态,并且完全忽略Main.class初始化。按钮侦听器和标签值未初始化。它只是一个空的fxml布局。Main.class中的每个变量,我想从Tab1Controller访问的是返回NullPointerException-偶数方法

每个控制器扩展AbstractController,它包含在start()方法内初始化的Main.class实例。因此,我应该能够随时访问每个Main.class方法/变量

问题Gif:

一些代码示例:

我的
Main.class
start()
方法:

    public Controller myController;

    @Override
        public void start(Stage primaryStage) throws Exception {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("/sample.fxml"));
            myController = new Controller();
            myController.setMainApp(this);
            loader.setController(myController);
            Parent root = loader.load();
            primaryStage.setTitle("Simple App");
            primaryStage.setScene(new Scene(root));
            primaryStage.show();

            <other stuff>
    }

public void setDefaultViewProperties(){
        currentScanningFileProperty = new SimpleStringProperty();
        myController.tab1Controller.actualPath.textProperty().bind(currentScanningFileProperty); //NullPointerException while called from Controller
        fileCounterProperty = new SimpleLongProperty();
        myController.tab1Controller.numOfScanned.textProperty().bind(fileCounterProperty.asString());
        maliciousFilesCounterProperty = new SimpleIntegerProperty();
        myController.tab1Controller.numOfMaliciousFiles.textProperty().bind(maliciousFilesCounterProperty.asString());

        myController.tab1Controller.fileChoiceBtn.setOnMouseClicked(event -> chooseFile());
        myController.tab1Controller.runScanBtn.setOnMouseClicked(event -> new Thread(() -> {
            try {
                resetValues();
                startFileWalking(chosenFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start());
    }
选项卡1控制器:

package sample;

import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller extends AbstractController implements Initializable{
    public HBox sideMenu;
    public VBox mainMenu;
    public BorderPane borderPane;
    public Boolean isButton1Pressed = false;
    public Boolean isButton2Pressed = false;
    public static final String TAB_1 = "TAB-1";
    public static final String TAB_2 = "TAB-2";
    public Button malwareButton;
    public Button webShieldButton;
    public Tab1Controller tab1Controller;
    public Tab2Controller tab2Controller;


    @Override
    public void initialize(URL location, ResourceBundle resources) {

        createMenuButtons();
        setSideMenu();
        setMenuButtonsListeners();
    }

    private void setSideMenu(){
        mainMenu.getChildren().add(item(malwareButton));
        mainMenu.getChildren().add(item(webShieldButton));
        mainMenu.setStyle("-fx-background-color:#004D40");
    }

    private HBox item(Button menuButton){
        menuButton.setPrefSize(200, 50);
        menuButton.setStyle("-fx-background-color: transparent;");
        menuButton.setTextFill(Color.web("#E0F2F1"));
        menuButton.setPadding(Insets.EMPTY);
        sideMenu = new HBox(menuButton);
        return sideMenu;
    }

    public void setMenuButtonsListeners(){
        malwareButton.setOnMousePressed(event -> {
            setButtonStylePressed(malwareButton);
            setButtonStyleUnpressed(webShieldButton);
            isButton1Pressed = true;
            isButton2Pressed = false;
            loadTab1Content();
            main.setDefaultViewProperties();
        });

        webShieldButton.setOnMousePressed(event -> {
            setButtonStylePressed(webShieldButton);
            setButtonStyleUnpressed(malwareButton);
            isButton1Pressed = false;
            isButton2Pressed = true;
            loadTab2Content();
        });

        malwareButton.setOnMouseExited(event -> {
            if(!isButton1Pressed){
                setButtonStyleUnpressed(malwareButton);
            }
        });
        webShieldButton.setOnMouseExited(event -> {
            if(!isButton2Pressed){
                setButtonStyleUnpressed(webShieldButton);
            }
        });

        malwareButton.setOnMouseEntered(event -> setButtonStylePressed(malwareButton));
        webShieldButton.setOnMouseEntered(event -> setButtonStylePressed(webShieldButton));
    }

    public void setButtonStylePressed(Button btn){
        btn.setStyle("-fx-background-color: #E0F2F1");
        btn.setTextFill(Color.web("#004D40"));
    }

    public void setButtonStyleUnpressed(Button btn){
        btn.setStyle("-fx-background-color: transparent");
        btn.setTextFill(Color.web("#E0F2F1"));
    }

    private void loadTab1Content(){
        FXMLLoader tab1loader = new FXMLLoader();
        tab1loader.setLocation(getClass().getResource("/tab_1_content.fxml"));
        try {
            if (tab1Controller == null){
                tab1Controller = new Tab1Controller();
            }
            tab1loader.setController(tab1Controller);
            borderPane.setCenter(tab1loader.load());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void loadTab2Content(){
        FXMLLoader tab2loader = new FXMLLoader();
        tab2loader.setLocation(getClass().getResource("/tab_2_content.fxml"));
        try {
            if (tab2Controller == null){
                tab2Controller = new Tab2Controller();
            }
            tab2loader.setController(tab2Controller);
            borderPane.setCenter(tab2loader.load());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void createMenuButtons(){
        malwareButton = new Button();
        malwareButton.setText(TAB_1);
        webShieldButton = new Button();
        webShieldButton.setText(TAB_2);
    }
}
package sample;

import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

/**
 * Created by admin on 5. 5. 2018.
 */
public class Tab1Controller extends AbstractController implements Initializable {


    public ProgressBar progressBar;
    public Button runScanBtn;
    public Button fileChoiceBtn;
    public Label chosenPath;
    public Label actualPath;
    public Label numOfMaliciousFiles;
    public Label hashValue;
    public Label scanFinishedMsg;
    public Label numOfScanned;
    public Button showFoundMalwareButton;



    @Override
    public void initialize(URL location, ResourceBundle resources) {


        runScanBtn.setDisable(true);
        scanFinishedMsg.setVisible(false);
        showFoundMalwareButton.setVisible(false);
        showFoundMalwareButton.setOnAction(event -> showPopupWindow());
    }
更新#1-单击按钮后通过Main.class更新fxml值

我终于无一例外地运行了这个应用程序。我必须为窗格fxml布局本身创建下一个名为Tab1Controller的控制器。当我初始化控制器时,它立即初始化了内部的Tab1Controller。因此,当我想更改中央边框窗格标签时,我必须调用
myController.tab1Controller.tabLabel.setText()

我不知道这是否是解决这个问题的好办法。 但现在我又回到我的老问题上来了。当我点击TAB-1时,它将加载内容,但值并没有初始化为默认状态

例如,我有两个实时更新的标签。我用默认值绑定了一些SimpleProperties。它以前工作过,但由于我有三个控制器,它将首次加载数据,但当我单击TAB-1按钮时,它将只加载fxml内容,但它不会设置这些标签

所以我在Main.class中公开了这个方法,每当我从控制器切换到TAB-1时,我都会调用它

public void setDefaultViewProperties(){
    myController.tab1Controller.actualPath.textProperty().bind(currentScanningFileProperty);
    myController.tab1Controller.numOfScanned.textProperty().bind(fileCounterProperty.asString());
    myController.tab1Controller.numOfMaliciousFiles.textProperty().bind(maliciousFilesCounterProperty.asString());
}
但现在每次我点击表1,我都有

java.lang.NullPointerException: Cannot bind to null

您可以创建两个窗格,并使用
setVisible()
方法在它们之间切换

示例:

void btn1Clicked() {
   pane1.setVisible(true);
   pane2.setVisible(false);
}

void btn2Clicked() {
   pane1.setVisible(false);
   pane2.setVisible(true);
}

您可以使用选项卡窗格实现此行为:

已解决。我不知道怎么做,但是setDefaultViewProperties()目前没有抛出NullPointerException。我没有更改代码中的任何内容:

malwareButton.setOnMousePressed(event -> {
                setButtonStylePressed(malwareButton);
                setButtonStyleUnpressed(webShieldButton);
                isButton1Pressed = true;
                isButton2Pressed = false;
                loadTab1Content();
                main.setDefaultViewProperties();
            });

为什么要更换按钮侦听器?只需执行类似于
borderPane.setCenter(newContent)的操作也不需要使用fxml。您也可以使用java代码来创建场景…我尝试过使用borderPane.setCenter(fxml窗格资源)。它起作用了,但我所有的观点都不起作用。我必须将Main.class中的代码重新连接到此新窗格。因为我在新窗格中的任何视图都不起作用。我需要向Main.class发送一些类似于上下文(用于Android开发)的内容。不知道你做错了什么。在加载fxml时,可能需要从这里的答案中执行一些操作。顺便说一句:将fxml作为参数传递给
menuDecorator
方法,而不是根据不同的字符串进行决定,并希望在调整按钮文本时不要忘记在检查中调整字符串,这有什么不对?听起来问题不在您发布的代码中。“我所有的观点都不起作用”:这到底意味着什么?另外,看起来你真的希望在这里切换按钮,而不是普通的按钮,你可以通过将样式移动到CSS来摆脱很多这类代码,CSS有合适的选择器(例如,
:hover
),你可以使用这些选择器来代替执行输入、退出等处理程序。“我的所有视图都不工作”意味着,当我按下按钮时,fxml内容被加载到窗格中。该内容不起作用。当我单击按钮时,它们不会响应,标签文本不会更新(当我在Main.class方法中初始化该文本时)。看起来它将添加fxml内容,但它没有与Main.class连接。