我想知道我构建了一个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"
中设置控制器(您已经拥有)。