2013-04-23 33 views
18

JavaFXでFXMLを使用してJavaプログラムを作成しようとしています。しかし、私はレイアウト管理に問題があります。私はスイングでCardLayoutに慣れていたのと同じように、Panesの間で切り替えたいですが、私はそれを得ることができません。JavaFXでペインを切り替える

私はグーグルで回り、何の答えも見つかりませんでした。

JavaFXに相当するCardLayoutはありますか?もしそうなら、私に例を教えてもらえますか?それは私の夕方を大いに助けます!あなたのペイン間のアニメーションの遷移を必要としない場合はここで

は、することができます、私のFXMLコード

<AnchorPane id="anchorPane" prefHeight="324.0" prefWidth="530.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication2.SampleController"> 
    <children> 
    <Pane fx:id="mainScreen" layoutX="6.0" prefHeight="324.0" prefWidth="518.0"> 
     <children> 
     <Button layoutX="254.0" layoutY="37.0" mnemonicParsing="false" text="Button" /> 
     </children> 
    </Pane> 
    <Pane fx:id="loginScreen" prefHeight="324.0" prefWidth="530.0"> 
     <children> 
     <TextField id="password" fx:id="username" layoutX="142.0" layoutY="106.0" prefWidth="200.0" /> 
     <TextField fx:id="password" layoutX="142.0" layoutY="140.0" prefWidth="200.0" /> 
     <Label fx:id="label" layoutX="126.0" layoutY="120.0" minHeight="16.0" minWidth="69.0" /> 
     <Button fx:id="button" layoutX="213.0" layoutY="196.0" onAction="#handleButtonAction" onKeyPressed="#handleButtonAction" text="Login" /> 
     </children> 
    </Pane> 
    </children> 
</AnchorPane> 

答えて

30

非アニメーション遷移

です:

  1. は交換してください新しいシーンを作成することによって全体のシーンとset that scene on your Stageまたは
  2. (親のchildren listを操作して)新しいウィンドウ枠を追加するか、
  3. StackPaneにすべてのペインを配置し、表示したいペインをstack's child list。あなたのペインの間transtionsをアニメ化希望の場合

アニメーションが

移行し、その後、JavaFXの中で複数の画面を管理する上でアンジェラCaicedoの2部シリーズを参照してください。

アンジェラの解決策は、StackPaneと別のカスタムScreenControllerクラスを使用して、Transitionsまたはanimationsをスタック内にペイントすることです。


フレームワーク

JFXFlowWebFXのようなフレームワークは、ユーザーが戻って使用して画面と進むボタンと履歴リストの間で前後に切り替えることができるように、アプリのブラウザスタイルのインターフェイスを提供することができます。

アップデート2017

私は上記の両方の参照フレームワークでの開発は、今は亡きだと思います。開発中の他のフレームワークは、以下のとおりです。

および多数の他の人が(私はここでは包括的なリストを提供することはありません)。


関連

4

ここで私はそれを行う方法は次のとおりです。 (この例では、私はそれに対応するコントローラと2つのFXML文書を作成している彼らがFXMLLoginと呼ばれています。 .fxml、およびHome.fxml)。

ので、この例では、ホームにFXMLLoginから

を行くために、私が押されているフォーム上の「ログイン」ボタンに応答FXMLLoginController内のメソッドを作成:

@FXML 
private void login(javafx.event.ActionEvent event) throws IOException 
{ 
    if(pwf1.getText().equals("alphabetathetagamma")) 
    { 
      Parent blah = FXMLLoader.load(getClass().getResource("Home.fxml")); 
      Scene scene = new Scene(blah); 
      Stage appStage = (Stage) ((Node) event.getSource()).getScene().getWindow(); 
      appStage.setScene(scene); 
      appStage.show(); 
    } 
    else 
    { 
      label1.setText("Password is incorrect. Please Try Again"); 
    } 
} 

@FXMLは非常に重要であることに注意してください。

私はあなたの質問を正しく理解していれば、これはトリックを行う必要があります。

ペインの切り替えは明白ではなく、私が見つけたWeb上のチュートリアルではっきりと説明されていません。私は最初にそれを見つけ出す前に、自分自身を広範囲にGoogleにしなければならなかった。幸いにも、いったんあなたがそれを掛けてしまえば、実際はとても簡単です。

私はあなたの質問を誤解していないと思いますか?これがあなたの必要なものかどうか教えてください:)

0

JRebirth Application Frameworkは、専用のパターンwB-CSMvcを使用してカスタム 'CardLayout'を提供します。

StackModelクラスはジョブを行います(org.jrebirth.af:コンポーネントアーティファクトによって提供されます)。herehereの2つの用途があります。

各 'カード'モデルは、enum | modelKey識別子を使用して呼び出すことができ、各スタックは一意の名前を持ちます。

最初のサンプルはJRebirth Demo Applicationのために使用されています。別のJRebirthショーケースアプリケーションを(別々の独立したjarから)JRebirthモジュールとして動的にロードすることができます。

public final class JRebirthDemo extends DefaultApplication<StackPane> { 

    public static void main(final String... args) { 
     Application.launch(JRebirthDemo.class, args); 
    } 

    @Override 
    public Class<? extends Model> firstModelClass() { 
     return MainModel.class; 
    } 

    @Override 
    protected String applicationTitle() { 
     return "JRebirth Demo Application"; 
    } 

    @Override 
    protected void customizeScene(final Scene scene) { 
     super.customizeScene(scene); 

     addCSS(scene, DemoStyles.DEFAULT); 
     addCSS(scene, WorkbenchStyles.DEFAULT); 
    } 

    @Override 
    protected void customizeStage(final Stage stage) { 
     // Center the stage 
     stage.centerOnScreen(); 
    } 

    @Override 
    protected List<? extends ResourceItem<?, ?, ?>> getResourceToPreload() { 
     return Collections.emptyList(); 
    } 
} 

このアプリケーションは、その最初のモデル(MainModel)をロードし、(自動的に構築されたStakPane、)シーンのルートノードへのルートノードを配置します。

MainModelは、すべてのアプリケーションのサブモジュールをリストして、左のメニューにボタンエントリを追加し、各モジュールコンテンツを表示するStackModelをリストします。 StackModelは、固有のStringキーを使用して特殊なアノテーションを使用してロードされます。

public final class MainModel extends DefaultModel<MainModel, MainView> { 

    private final List<ModuleModel> modules = new ArrayList<>(); 

    @Link("DemoStack") 
    private StackModel stackModel; 

    @Override 
    protected void initModel() { 
     for (final ModuleModel mm : getModels(ModuleModel.class)) { 
      this.modules.add(mm); 
     } 
    } 

    @Override 
    protected void showView() { 
     view().node().setCenter(this.stackModel.node()); 
    } 

    @Override 
    protected void hideView() { 
     // Nothing to do yet 

    } 

    List<ModuleModel> getModules() { 
     return this.modules; 
    } 
} 

MAINVIEWは、モジュールのメニューを作成するには、担当することになります

public final class MainView extends DefaultView<MainModel, BorderPane, MainController> { 

    private final List<Button> buttonList = new ArrayList<>(); 

    public MainView(final MainModel model) throws CoreException { 
     super(model); 
    } 

    @Override 
    protected void initView() { 

     node().setPrefSize(800, 600); 

     node().setLeft(createMenu()); 

    } 

    @Override 
    public void start() { 
     this.buttonList.stream().findFirst().ifPresent(button -> button.fire()); 
    } 

    private Node createMenu() { 
     final VBox box = new VBox(); 

     for (final ModuleModel mm : model().getModules()) { 
      final Node n = createModuleButton(mm); 
      VBox.setMargin(n, new Insets(4, 4, 4, 4)); 
      box.getChildren().add(n); 
     } 
     return box; 
    } 

    private Node createModuleButton(final ModuleModel mm) { 
     final Button b = new Button(mm.moduleName()); 
     b.getStyleClass().add("menuButton"); 
     b.setPrefSize(100, 50); 
     b.setOnAction(controller()::onButtonFired); 
     b.setUserData(Key.create(mm.getClass())); 
     this.buttonList.add(b); 
     return b; 
    } 
} 

し、任意のメニューボタンがトリガされたときにメインコントローラは、モジュールのコンテンツをロードします:

public final class MainController extends DefaultController<MainModel, MainView> implements ActionAdapter { 

    public MainController(final MainView view) throws CoreException { 
     super(view); 
    } 

    public void onButtonFired(final ActionEvent event) { 
     final Button b = (Button) event.getSource(); 
     final UniqueKey<? extends Model> data = (UniqueKey<? extends Model>) b.getUserData(); 

     model().sendWave(StackWaves.SHOW_PAGE_MODEL, 
         WBuilder.waveData(StackWaves.PAGE_MODEL_KEY, data), 
         WBuilder.waveData(StackWaves.STACK_NAME, "DemoStack")); 
    } 
} 

秒例ではStackModelがinnerComponentとしてロードされ、各カードは(FXMLPageに格納された)enumエントリで識別されます。FXMLShowCaseModelを見てみましょう:

final InnerComponent<StackModel> stack = CBuilder.innerComponent(StackModel.class, FXMLPage.class); 
    this.stackModel = findInnerComponent(stack); 

モデルで列挙型エントリをリンク列挙:カードリストが知られているように

public enum FXMLPage implements PageEnum { 

    StandaloneFxml, 
    IncludedFxml, 
    ViewEmbeddedFxml, 
    HybridFxml; 

    @Override 
    public UniqueKey<? extends Model> getModelKey() { 
     UniqueKey<? extends Model> modelKey; 

     switch (this) { 

      default: 
      case ViewEmbeddedFxml: 
       modelKey = Key.create(EmbeddedModel.class); 
       break; 
      case StandaloneFxml: 
       modelKey = Key.create(StandaloneModel.class); 
       break; 
      case HybridFxml: 
       modelKey = Key.create(HybridModel.class, FXMLModel.KEYPART_FXML_PREFIX + "org.jrebirth.af.showcase.fxml.ui.hybrid.Hybrid"); 
       break; 
      case IncludedFxml: 
       modelKey = Key.create(IncludedModel.class, new LoremIpsum()); 
       break; 
     } 

     return modelKey; 
    } 
} 

は、ツールバー項目は、静的FXMLShowCaseViewに作成され、イベント処理もstaically別の技術を使用してFXMLShowCaseControllerに定義されています。

public final class FXMLShowCaseController extends DefaultController<FXMLShowCaseModel, FXMLShowCaseView> { 

    private static final Logger LOGGER = LoggerFactory.getLogger(FXMLShowCaseController.class); 

    public FXMLShowCaseController(final FXMLShowCaseView view) throws CoreException { 
     super(view); 
    } 

    @Override 
    protected void initEventAdapters() throws CoreException { 

     // WaveData<Class<? extends PageEnum>> stackName = Builders.waveData(StackWaves.STACK_PAGES, FXMLShowCaseModel.STACK_PAGES); 

     // Manage Ui Command Button 
     linkWave(view().getShowIncluded(), ActionEvent.ACTION, StackWaves.SHOW_PAGE_ENUM, 
       WBuilder.waveData(StackWaves.PAGE_ENUM, FXMLPage.IncludedFxml)); 

     linkWave(view().getShowEmbedded(), ActionEvent.ACTION, StackWaves.SHOW_PAGE_ENUM, 
       WBuilder.waveData(StackWaves.PAGE_ENUM, FXMLPage.ViewEmbeddedFxml)); 

     linkWave(view().getShowStandalone(), ActionEvent.ACTION, StackWaves.SHOW_PAGE_ENUM, 
       WBuilder.waveData(StackWaves.PAGE_ENUM, FXMLPage.StandaloneFxml)); 

     linkWave(view().getShowHybrid(), ActionEvent.ACTION, StackWaves.SHOW_PAGE_ENUM, 
       WBuilder.waveData(StackWaves.PAGE_ENUM, FXMLPage.HybridFxml)); 

    } 
} 

質問がある場合はお知らせください

関連する問題