私はいくつかのブログやその他のstackoverflowの質問を見てきましたが、私の質問に対する直接的な答えは見当たりません。 javafx guiクライアントを作成しています。メニューバーを1つのfxmlの1つのコントローラーにしたいので、コンテンツ領域を追加のfxmlファイルにしたいです。ログイン画面が1つのfxmlになり、ログイン画面がアプリケーションのメインコンテンツになり、それが1つのfxmlになります。これを行うにはどうすればよいですか?
ログイン、メニューバー、メインコンテンツのすべてのコードを同じファイルに入れたくありません。これは私が取り組んでいるもののイメージです:
FXMLファイルのfx:rootおよびfx:controllerとしてカスタムJavaクラスを使用して、FXMLをコンポーネントとして使用します。 http://docs.Oracle.com/javafx/2 /fxml_get_started/custom_control.htm
そのためには、FXMLをロードするカスタムJavaクラスFXMLLoaderのコンストラクターを呼び出す必要があります。利点は、FXMLがコンポーネントをロードする方法を変更することです。
ネストされたコントローラーを使用してFXMLLoaderを介してコンポーネントをインスタンス化する古典的な方法は、最初にFXML、次に各パーツのコントローラーです。
この手法では、最初にコントローラー、次に各コンポーネントのFXMLを使用します。また、FXMLにFXMLを直接ロードするのではなく、カスタムのJavaクラスをFXMLにインポートします。
これはより優れた抽象化であり(FXMLにコンポーネントをインポートするときにコンポーネントを実装する方法を知る必要はありません)、FXMLをサポートするカスタムウィジェットを実装するようなコードの再利用に役立ちます。コンポーネントを再利用可能にするには、実装が他の部分と密結合していないことを確認するか、IOCを使用してそうします(たとえば、JavaFXとのSpring統合)。このように、 (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文書を含める 相互に含めることができます-これは、設計ロジックの分離に役立ちます。
これは、 ネストされたコントローラー -各ドキュメントに1つを持つことができることを意味します。
ドキュメントから、ロジックを分離したり、必要に応じてルートコントローラーから呼び出したりできるようにコードを設定できるようになりました。
お役に立てば幸いです。
同様の要件を持つポップアップウィンドウが必要でした(ノードとレイアウトをより詳細に制御できます)。
推奨事項を順を追って検討した結果、役立つソリューションが見つかりました。
最初に、2番目のfxmlドキュメントと2番目のコントローラーを作成しました(NetBeansで、New-> Empty FXML ...-> Use Java Controller-> Create New ...))。
少し難しいのは、メインコントローラーでステージを構築し、ポップアップコントローラーに接続する方法を見つけることでした。
リンク Passing Parameters 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
}
}