29

私はいくつかのブログやその他のスタックオーバーフローの質問を見てきましたが、私の質問に対する直接的な回答がありません。javafx gui クライアントを作成しています。メニューバーを 1 つの fxml 内の 1 つのコントローラーにしたいのですが、コンテンツ領域を追加の fxml ファイルにしたいと考えています。ログイン画面は 1 つの fxml になり、ログイン画面がアプリケーションのメイン コンテンツになり、1 つの fxml になります。これを行うにはどうすればよいですか?

ログイン、メニューバー、およびメイン コンテンツのすべてのコードを同じファイルに格納したくないだけです。これは私が取り組んでいることのイメージです:

ここに画像の説明を入力

4

4 に答える 4

35

カスタム Java クラスを FXML ファイルの fx:root および fx:controller として使用することにより、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 を使用してそうします (たとえば、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 には、基本的なコンポーネントのみが含まれています。

于 2013-10-13T06:18:33.793 に答える
5
  1. FXML ドキュメントを別のドキュメントに含めることができます。これは、設計ロジックを分離するのに役立ちます。

  2. これは、ドキュメントごとに 1 つの入れ子になったコントローラーを持つことができることを意味します。

ドキュメントから、ロジックを分離してルートコントローラーから呼び出すことができるようにコードをセットアップできるようになりました (必要な場合)。

それが役立つことを願っています。

于 2013-10-13T05:53:57.130 に答える
1

同様の要件を持つポップアップウィンドウが必要でした(ノードとレイアウトをより細かく制御できます)。

推奨事項に沿って作業を進めたところ、役立つ可能性のある解決策が見つかりました。

最初に、2 番目の fxml ドキュメントと 2 番目のコントローラを作成しました (NetBeans では、[新規] -> [空の FXML] ... -> [Java コントローラを使用] -> [新規作成])。

少し難しかったのは、メイン コントローラーでステージを構築し、それをポップアップ コントローラーに接続する方法を理解することでした。

リンク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();        
}
于 2016-12-29T22:06:36.393 に答える
0
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
           } 
               }
于 2018-03-12T00:25:33.563 に答える