【发布时间】:2019-12-26 02:07:09
【问题描述】:
我目前有 3 节课。
ScreenController(控制器类):
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.layout.AnchorPane;
import java.net.URL;
import java.util.ResourceBundle;
public class ScreenController implements Initializable
{
private AnchorPane window;
public ScreenController()
{
super();
}
public ScreenController(AnchorPane window)
{
setWindow(window);
}
public void setWindow(AnchorPane window)
{
this.window = window;
}
public void setScreen(String screen)
{
try
{
Parent root = FXMLLoader.load(getClass().getResource("/com/app/client/resources/fxml/" + screen + ".fxml"));
window.getChildren().setAll(root);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void initialize(URL location, ResourceBundle resources)
{
}
}
LoginScreen(主屏幕):
import com.app.client.java.controllers.ScreenController;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class LoginScreen extends ScreenController
{
@FXML
private AnchorPane loginWindow;
@FXML
private Button goButton;
public LoginScreen()
{
super();
setWindow(loginWindow);
}
@FXML
public void goButtonPressed(ActionEvent event) throws IOException
{
setScreen("Home");
System.out.println("Success.");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="loginWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" opacity="0.5" prefHeight="500.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.app.client.java.classes.LoginScreen">
<children>
<Button fx:id="goButton" layoutX="205.0" layoutY="60.0" mnemonicParsing="false" onAction="#goButtonPressed" text="Button" />
</children>
</AnchorPane>
主屏幕(辅助屏幕):
import com.app.client.java.controllers.ScreenController;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
public class HomeScreen extends ScreenController
{
@FXML
private static AnchorPane homeWindow = new AnchorPane();
public HomeScreen()
{
super (homeWindow);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="homeWindow" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.app.client.java.classes.HomeScreen">
<children>
<TextArea layoutX="200.0" layoutY="100.0" prefHeight="200.0" prefWidth="200.0" text="aksajkasjkasja" />
</children>
</AnchorPane>
我希望能够使用 setScreen() 函数从主屏幕移动到辅助屏幕。但是,我发现该过程没有成功完成。
我发现另一种可行的方法是(尽管它会调整窗口大小,而不是用新窗口的内容填充初始窗口):
Parent root = FXMLLoader.load(getClass().getResource("/com/app/client/resources/fxml/" + screen + ".fxml"));
Stage stage = (Stage) loginWindow.getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
但是,我更喜欢使用初始实现,因为它更简洁、易读,并且理论上可以提供我想要的确切行为。
【问题讨论】:
-
FXMLLoader#load(URL)方法是静态的,无论您是否在实例上调用它。您需要使用实例load()方法。通过构造函数或FXMLLoader#setLocation(URL)设置位置。但是,正如我在对您之前的问题的回答中指出的那样,共享控制器实例并不是一个好主意。你希望通过这个实现什么?控制器实例将替换所有注入的字段,初始化将发生两次,链接的方法现在将链接到多个不相关的对象。 -
您应该有一个设计良好的模型并在控制器之间共享该模型。然后控制器与模型进行交互,包括观察模型的变化并做出适当的反应。我建议阅读有关 MVC、MVVM 和 MVP 等应用程序架构的内容。
-
一方面,你不能同时使用
setController和fx:controller,只能使用其中之一。如果我理解的话,您似乎想将 same 控制器实例用于多次加载。如果是这种情况,请不要。
标签: java intellij-idea javafx fxml fxmlloader