我一直在查阅博客和其他的stackoverflow问题,但是没有看到我的问题有一个直接的答案。我正在创建一个JavaFX GUI客户端,并且我希望我的菜单栏是一个FXML中的一个控制器,然后我希望内容区域是另外的FXML文件。登录界面将是一个FXML,登录后将是应用程序的主要内容,它将在一个FXML中。我该如何做呢?
我只是不想把我的登录、菜单栏和主要内容的所有代码都放在同一个文件中。这是我正在工作的图片:
我一直在查阅博客和其他的stackoverflow问题,但是没有看到我的问题有一个直接的答案。我正在创建一个JavaFX GUI客户端,并且我希望我的菜单栏是一个FXML中的一个控制器,然后我希望内容区域是另外的FXML文件。登录界面将是一个FXML,登录后将是应用程序的主要内容,它将在一个FXML中。我该如何做呢?
我只是不想把我的登录、菜单栏和主要内容的所有代码都放在同一个文件中。这是我正在工作的图片:
通过使用自定义的Java类作为fx:root和fx:controller,将FXML用作组件:
http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm
要实现这一点,需要在自定义Java类的构造函数中调用FXMLLoader,它将加载您的FXML文件。优势在于可以更改FXML加载组件的方式。
FXMLLoader通过嵌套控制器的经典方式来实例化组件:先是FXML,然后是每个部分的控制器。
而使用此技术是:先是控制器,然后是每个组件的FXML。并且您不会直接在FXML中加载FXML,而是在FXML中导入自定义的Java类。
这是更好的抽象(在导入组件时无需知道组件如何实现),有助于重用代码,就像实现具有FXML支持的自定义小部件一样。为了使组件可重用,请确保其实现与其他部分没有紧密耦合,或者使用IOC进行处理(例如,使用Spring集成JavaFX)。这样,您就可以在应用程序的任何部分导入组件(就像DateInput小部件一样)而无需担心,也不会重复代码。
在您的情况下,您将拥有:
public class MenuBox extends VBox {
@FXML
private LoginBox loginBox;
@FXML
private ProfilesBox profilesBox;
public MenuBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("menu.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public class LoginBox extends VBox {
public LoginBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("login.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public class ProfilesBox extends VBox {
public ProfilesBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("profiles.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
你需要在管理页面全局布局的menu.fxml中导入LoginBox和ProfilesBox:
<?import com.foo.bar.LoginBox ?>
<?import com.foo.bar.ProfilesBox ?>
<fx:root type="javafx.scene.layout.VBox"
xmlns:fx="http://javafx.com/fxml">
<!-- Stuff here to declare the menu bar-->
<HBox>
<ProfilesBox fx:id="profilesBox"/>
<LoginBox fx:id="loginBox"/>
</HBox>
</fx:root>
login.fxml和profiles.fxml只包含基本组件。
我需要一个弹出窗口,具有类似的要求(对节点和布局有更多的控制)。
在经过推荐后,我找到了一个可能有用的解决方案。
首先,我创建了第二个fxml文档和第二个控制器(在NetBeans中,新建->空的FXML...->使用Java控制器->创建新...)。
有点挑战的是如何在主控制器中构建舞台并将其连接到弹出控制器。
链接传递参数JavaFX FXML提供了一些真正好的见解和技巧。
最终代码看起来像这样(希望能帮助某些人):
// Anchor Pane from the popup
@FXML
AnchorPane anchorPanePopup;
@FXML
private void soneButtonAction(ActionEvent event) throws IOException {
Stage newStage = new Stage();
AnchorPane anchorPanePopup = (AnchorPane) FXMLLoader.load(getClass().getResource("Popup_FXML.fxml"));
Scene scene = new Scene(anchorPanePopup);
newStage.setScene(scene);
newStage.initModality(Modality.APPLICATION_MODAL);
newStage.setTitle("Dialog Window");
newStage.showAndWait();
}
package javafxapplication11;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.stage.Stage;
public class FXMLDocumentController implements Initializable {
@FXML
private CheckBox c1;
@FXML
private CheckBox c2;
public void clicked1(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
public void clicked2(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
public void clicked3(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
// TODO Auto-generated method stub
}
}