我想知道我构建了一个GUI Java Scene Builder,但是我希望它在我拥有的VBOX中显示网站。毫无疑问,这运行得很好。但是我在制作的FX:ID VBOX中无法显示该网站有一些问题。我只是以google为例。我正在为自己制作的游戏构建游戏启动器,但我不喜欢Swing或AWT的外观,因此我改用JavaFx。我现在有点如何使用它,但是我可以弄清楚如何将我的VBOX与我的代码连接。谢谢您的帮助。到目前为止,这是我的代码

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class Main extends Application {

    @FXML public VBox VBOX;

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent main = FXMLLoader.load(getClass().getResource("launcher.fxml"));

        primaryStage.setTitle("Dev Launcher");
        primaryStage.setWidth(900);
        primaryStage.setHeight(560);

        Scene scene = new Scene(new Group());
        VBOX = new VBox();
        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();
        webEngine.load("http://google.com");

        VBOX.getChildren().addAll(browser);
        scene.setRoot(main);

        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();
    }

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


继承人的FXML文件

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

<?import javafx.geometry.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.web.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <bottom>
      <ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
        <items>
            <GridPane alignment="CENTER" prefHeight="57.0" prefWidth="883.0">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="375.2518005371094" minWidth="10.0" prefWidth="154.2821502685547" />
                <ColumnConstraints halignment="CENTER" hgrow="ALWAYS" maxWidth="550.5108489990234" minWidth="0.0" prefWidth="481.0280303955078" />
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="173.30714416503906" minWidth="10.0" prefWidth="154.2821502685547" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <Button mnemonicParsing="false" prefHeight="57.0" prefWidth="286.0" text="Play" GridPane.columnIndex="1" GridPane.halignment="CENTER">
                     <font>
                        <Font name="System Bold" size="13.0" />
                     </font>
                  </Button>
                  <Button mnemonicParsing="false" prefHeight="30.0" prefWidth="85.0" text="Website" GridPane.halignment="RIGHT" GridPane.valignment="CENTER" />
                <Button mnemonicParsing="false" prefHeight="30.0" prefWidth="85.0" text="About" GridPane.valignment="CENTER" />
                  <Label text="Version: " GridPane.columnIndex="2" GridPane.halignment="LEFT" GridPane.hgrow="SOMETIMES" GridPane.valignment="CENTER" GridPane.vgrow="SOMETIMES" />
                  <Label prefWidth="120.0" text="0.0.1" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.valignment="CENTER" GridPane.vgrow="SOMETIMES">
                     <GridPane.margin>
                        <Insets left="-100.0" />
                     </GridPane.margin>
                  </Label>
               </children>
            </GridPane>
        </items>
      </ToolBar>
   </bottom>
   <center>
      <TabPane nodeOrientation="LEFT_TO_RIGHT" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER">
        <tabs>
          <Tab text="Update Notes">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <ScrollPane layoutX="1.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
                           <content>
                              <AnchorPane prefHeight="450.0" prefWidth="862.0">
                                 <children>
                                    <VBox fx:id="VBOX" alignment="CENTER" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                                 </children>
                              </AnchorPane>
                           </content>
                        </ScrollPane>
                     </children>
                  </AnchorPane>
            </content>
          </Tab>
          <Tab text="Game Log">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
            </content>
          </Tab>
        </tabs>
      </TabPane>
   </center>
</BorderPane>


我的Controller类没有很多:

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;

import java.io.IOException;

public class Controller {

    @FXML private VBox VBOX;

}

最佳答案

您的应用程序所需要做的就是维护应用程序生命周期(例如,启动应用程序,执行start方法将初始场景加载到舞台中,显示舞台并根据需要停止应用程序)。这样做就足够了,可以将其他逻辑委托给程序中的其他类(例如Controllers)。事实是,控制器是FXMLLoader创建的东西,而FXMLLoader足够聪明,可以为场景图创建基础节点并将它们自动连接到控制器中,从而简化了这种委派。

因此,您不需要(也不应该)将标记为@FXML的对象设置为新值。例如,声明:@FXML public VBox VBOX;,然后再调用:VBOX = new VBox();是错误的。

您也不应在应用程序中设置@FXML字段,因为这没有任何意义。 @FXML仅在控制器内有意义。该应用程序通常不是(也不应该是)控制器。如果是这样,则会引起问题,因为通常在加载新的FXML时,FXMLLoader会创建一个新的Controller。在您的应用程序中拥有一个以上的应用程序实例是没有意义的,一个实例是由Java启动器创建的,而另一个是由FXMLLoader创建的(这只会使您感到困惑)。有关更多信息,请参见JavaFX controller class not working

请记住,您的代码可以按以下方式重构。

样本。主要

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent main = FXMLLoader.load(getClass().getResource("launcher.fxml"));

        primaryStage.setTitle("Dev Launcher");
        primaryStage.setWidth(900);
        primaryStage.setHeight(560);

        Scene scene = new Scene(main);

        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();
    }

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


sample.Controller

package sample;

import javafx.fxml.FXML;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class Controller {
    @FXML private VBox vbox;

    public void initialize() {
        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();
        webEngine.load("http://google.com");

        vbox.getChildren().addAll(browser);
    }
}


而且,您的FXML文件也应位于示例目录中。注意,在上面的代码中,我将VBOX变量的名称更改为vbox,以更好地适应标准Java命名约定。为了使其起作用,变量名称必须与FXML中的fx:id说明符匹配(因此将fx:id="VBOX"更改为fx:id="vbox")。另外,还需要在FXML fx:controller="sample.Controller"中设置控制器(您已经拥有)。

09-10 13:25
查看更多