[英]How do i display my MenuBar across all my scenes in JavaFX
我是 JavaFX 的新手
但是我写了这段代码,我不知道如何在我的所有场景中显示菜单栏。 此外,我想在我的 HelloApplication 中使用布局创建/填充我的场景(但那是另一个问题)。
我有一个控制器,用于设置舞台并启动它。 我的 MenuBar 在 MenuLeiste 类中,但我希望它也出现在我的 Credits 类中。 对于缺少评论和此评论的布局,我感到非常抱歉。
public class HelloApplication extends Application {
public class Main {
public static void main(String[] args) {
launch(args);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
//set window as primaryStage
Stage window = primaryStage;
//Layout of MenuLeiste is put in l1 and setted as scene1
MenuLeiste l1 = new MenuLeiste();
//menuscene gets its objects fromsceneViewMenu
Scene menuscene = new Scene(l1.sceneViewMenu());
window.setScene(menuscene);
window.setHeight(600);
window.setWidth(800);
window.setTitle("Game Title");
window.show();
}
}
我的 MenuLeiste 课程
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MenuLeiste {
public VBox sceneViewMenu() {
MenuBar menuBar = new MenuBar();
VBox menuBox = new VBox(menuBar);
Menu dataMenu = new Menu("Data");
MenuItem exitItem = new MenuItem("Exit");
exitItem.setOnAction(e -> System.exit(0));
Menu extrasMenu = new Menu("Extras");
MenuItem creditsItem = new MenuItem("Credits");
creditsItem.setOnAction(e -> {
Credits c = new Credits();
Scene scene3 = new Scene(c.sceneView3());
Stage window = (Stage) menuBox.getScene().getWindow();
window.setScene(scene3);
});
extrasMenu.getItems().addAll(creditsItem);
dataMenu.getItems().addAll( exitItem);
menuBar.getMenus().addAll(dataMenu,extrasMenu);
//the scenes layout is saved in layout1
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(menuBox);
return layout1;
}
}
我的学分课程
package view;
import javafx.scene.Scene;`
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;`
public class Credits {
public VBox sceneView3()
{
Label label = new Label("Thanks");
Button backButton = new Button("Back");
backButton.setOnAction(e -> {
MenuLeiste l1 = new MenuLeiste();
Scene menuscene = new Scene(l1.sceneViewMenu());
Stage window = (Stage) backButton.getScene().getWindow();
window.setScene(menuscene);
});
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(label, backButton);
return layout1;
}
}
当您希望一个节点或一组节点存在于不同的“场景”之间时,通常最好的解决方案是不替换Scene
。 相反,您需要修改当前场景中显示的节点。 例如,在您的情况下,您可以将BorderPane
作为场景的根,并将MenuBar
设置为top
节点。 然后,当您要更改“视图”时替换center
节点。
这是一个演示此概念的最小可运行示例。 它使用“回调”来修改BorderPane
的中心节点,同时始终使用相同的MenuBar
实例。 尽管请注意该示例仅包含视图。 如果您有一个支持模型(即数据、业务逻辑等),您将需要修改代码以便可以传递它。 此外,如果您编写的应用程序与此示例类似,那么让所有视图在实际应用程序中实现一个公共接口可能是明智的。
我没有单独的菜单栏“视图类”,但这并不意味着你不能拥有一个(这样可能会更好)。
主.java :
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
var root = new BorderPane();
root.setTop(createMenuBar(root::setCenter));
root.setCenter(new TitleView().getNode());
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.setTitle("Demo");
primaryStage.show();
}
private MenuBar createMenuBar(Consumer<Node> onUpdateView) {
var exitItem = new MenuItem("Exit");
exitItem.setOnAction(e -> Platform.exit());
var creditsItem = new MenuItem("Credits");
creditsItem.setOnAction(e -> {
e.consume();
var view = new CreditsView();
view.setOnGoBack(() -> onUpdateView.accept(new TitleView().getNode()));
onUpdateView.accept(view.getNode());
});
return new MenuBar(
new Menu("File", null, exitItem),
new Menu("Extras", null, creditsItem)
);
}
}
标题视图.java:
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
public class TitleView {
private Node node;
public Node getNode() {
if (node == null) {
node = new StackPane(new Label("Welcome!"));
}
return node;
}
}
CreditsView.java:
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
public class CreditsView {
private Runnable onGoBack;
private Node node;
public Node getNode() {
if (node == null) {
var stack = new StackPane();
stack.setPadding(new Insets(10));
var label = new Label("Credits View");
stack.getChildren().add(label);
var goBackBtn = new Button("Go back");
goBackBtn.setOnAction(e -> {
e.consume();
if (onGoBack != null) {
onGoBack.run();
}
});
stack.getChildren().add(goBackBtn);
StackPane.setAlignment(goBackBtn, Pos.TOP_LEFT);
node = stack;
}
return node;
}
public void setOnGoBack(Runnable action) {
onGoBack = action;
}
}
以下是一些初学者应该很容易理解的基本代码。
主要布局和要在其中显示的潜在视图是预先创建的。
菜单栏位于主布局中边框窗格的顶部。
通过将节点设置为当前显示在边框窗格的中心,可以使用菜单项在视图之间切换。
现有视图被重用,而不是在每个导航上重新创建。
视图本身只是节点,因此该示例可以很容易地适应使用 FXML,因为 FXML 加载器的输出也是一个节点。 这同样适用于任何其他可能生成以这种方式用作视图的节点的东西。
手术
最初显示场景,用户单击“视图”菜单以显示可用视图的列表。
用户选择“查看二”菜单项并显示第二个视图。 应用程序菜单仍然可见,可用于将来的操作。
示例代码
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ViewSwitcherApp extends Application {
private BorderPane layout;
private final Node viewOne = new ViewOne();
private final Node viewTwo = new ViewTwo();
@Override
public void start(Stage stage) throws Exception {
// View menu
MenuItem viewOneMenuItem = new MenuItem("View One");
viewOneMenuItem.setOnAction(e -> setView(viewOne));
MenuItem viewTwoMenuItem = new MenuItem("View Two");
viewTwoMenuItem.setOnAction(e -> setView(viewTwo));
Menu viewMenu = new Menu(
"View", null,
viewOneMenuItem, viewTwoMenuItem
);
// File menu
MenuItem exitMenuItem = new MenuItem("Exit");
exitMenuItem.setOnAction(e -> Platform.exit());
Menu fileMenu = new Menu(
"File", null,
exitMenuItem
);
MenuBar menuBar = new MenuBar(
fileMenu, viewMenu
);
menuBar.setMinSize(MenuBar.USE_PREF_SIZE, MenuBar.USE_PREF_SIZE);
// Layout scene
layout = new BorderPane();
layout.setTop(menuBar);
setView(viewOne);
stage.setScene(
new Scene(layout, 300, 200)
);
stage.show();
}
private void setView(Node view) {
layout.setCenter(view);
}
public static void main(String[] args) {
launch(args);
}
}
class ViewOne extends StackPane {
public ViewOne() {
setStyle("-fx-background-color: lightblue; -fx-font-size: 30px;");
getChildren().add(new Label("View One"));
}
}
class ViewTwo extends StackPane {
public ViewTwo() {
setStyle("-fx-background-color: cornsilk; -fx-font-size: 30px;");
getChildren().add(new Label("View Two"));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.